How Realms Handle Add-ons Differently
When you test an add-on locally, your device acts as both the host server and the client, reading files directly from your `development_behavior_packs` and `development_resource_packs` folders. On a Realm, the architecture splits completely. The Realm itself runs in the cloud as a headless server, executing your behavior pack logic, loot tables, entities, and `@minecraft/server` scripts. Connected players only download the resource pack to render custom geometries, textures, and sounds.
This separation exposes bugs that never appear in local testing. Scripts that assume a single player is always present in the overworld will fail when players scatter across dimensions. Animations or particles driven by client-side Molang queries may desynchronize if the server-side entity state updates faster than the network tick rate. Furthermore, Realms do not read from development folders; when you upload a world, the game bundles the active packs from your standard `behavior_packs` and `resource_packs` folders and transmits them to the remote server.
Realms also enforce strict file size and timeout limits during the upload and download phases. If your resource pack contains uncompressed audio files or oversized textures, the upload may stall, or console and mobile players may get disconnected while trying to join and download the assets.
Preparing Your Manifests for Realm Updates
The single biggest hurdle when testing on a Realm is the aggressive pack caching system. When you upload a world containing a behavior pack with version `[1, 0, 0]`, the Realm stores that exact version in its cloud storage. If you fix a bug in your script, re-import the pack locally with the same `[1, 0, 0]` version, and upload the world again, the Realm will often see that it already has version `[1, 0, 0]` on file and completely ignore your new changes.
To force both the Realm server and every connecting player's client to download your updated files, you must increment the `version` array in both the `header` and `modules` sections of your `manifest.json` before every single upload. If your behavior pack depends on a specific resource pack, you must also update the `version` inside the `dependencies` array so they remain linked.
Before uploading, package your add-on as a `.mcaddon` or `.mcpack` file and double-click it to install it into your standard game directories. Do not rely on packs sitting in `development_behavior_packs` when uploading to a Realm, as the uploader frequently fails to package development folders correctly, leaving the Realm with an empty world and missing entities.
{
"format_version": 2,
"header": {
"name": "Realm Test Behavior Pack",
"description": "Bump the patch version on every Realm upload",
"uuid": "a1b2c3d4-e5f6-4a5b-8c9d-0e1f2a3b4c5d",
"version": [1, 0, 2],
"min_engine_version": [1, 20, 80]
},
"modules": [
{
"type": "data",
"uuid": "b2c3d4e5-f6a7-4b5c-9d0e-1f2a3b4c5d6e",
"version": [1, 0, 2]
},
{
"type": "script",
"language": "javascript",
"uuid": "c3d4e5f6-a7b8-4c5d-0e1f-2a3b4c5d6e7f",
"entry": "scripts/main.js",
"version": [1, 0, 2]
}
],
"dependencies": [
{
"uuid": "d4e5f6a7-b8c9-4d5e-1f2a-3b4c5d6e7f8a",
"version": [1, 0, 2]
},
{
"module_name": "@minecraft/server",
"version": "1.10.0"
}
]
}The World-Swap Deployment Workflow
Attempting to apply or remove add-ons directly through the Realm slot settings menu is notoriously unreliable. The interface frequently fails to register bumped version numbers or hangs indefinitely when syncing large packs. The most reliable way to deploy and update an add-on on a Realm is the local world-swap workflow.
Instead of managing packs on the Realm directly, treat your local machine as the staging environment. Download the active world from your Realm slot to your local device. In your local world settings, remove the older version of your behavior and resource packs, activate the newly imported versions with the incremented version numbers, and load the world once locally to verify that the packs initialize cleanly.
Once verified locally, save and quit the world. Open your Realm settings, select the target world slot, choose the option to replace the world, and upload your updated local copy. This forces the Realm to accept the entire world state along with the newly versioned packs mounted inside its configuration files.
| Deployment Step | Where to Perform It | Why It Matters |
|---|---|---|
| Increment manifest versions | Code editor (BP and RP) | Bypasses the Realm cloud cache so modified files actually upload. |
| Import via .mcaddon | Local game client | Installs packs into standard folders rather than development folders. |
| Swap packs on downloaded world | Local world settings | Avoids the buggy Realm pack-management UI completely. |
| Require players to accept packs | Local Resource Packs tab | Ensures every player joining the Realm is forced to download the RP. |
| Replace World on Realm slot | Realm settings menu | Pushes the world and bundled packs to the remote server in one transaction. |
Debugging Without a Server Console
unlike a Bedrock Dedicated Server (BDS), a Realm does not give you access to a terminal window or server log files. However, you can still use the built-in Content Log to catch client-side JSON errors, missing textures, and UI issues. Before joining your Realm, go to your local Settings, select the Creator tab, and enable both Content Log File and Content Log GUI. When you connect to the Realm, any errors in your resource pack—and certain replicated entity errors—will pop up on your screen.
Because your `@minecraft/server` scripts run entirely on the remote Realm host, standard `console.warn()` and `console.error()` calls do not always route back to a connected player's local Content Log reliably. To debug script logic, tick events, and entity state on a live Realm, you should build a lightweight in-game logging wrapper that routes diagnostic messages to players who hold a specific developer tag.
Wrapping your critical script callbacks in `try...catch` blocks and broadcasting the error stack to tagged developers in chat lets you see exact line numbers and runtime exceptions the moment they happen on the Realm, without disrupting regular testers.
import { world, system } from "@minecraft/server";
const DEV_TAG = "addon_dev";
function logToDevs(message, isError = false) {
const prefix = isError ? "§c[Realm Error]§r " : "§e[Realm Debug]§r ";
for (const player of world.getAllPlayers()) {
if (player.hasTag(DEV_TAG)) {
player.sendMessage(`${prefix}${message}`);
}
}
}
world.afterEvents.EntityHitEntity.subscribe((event) => {
try {
const { damagingEntity, hitEntity } = event;
if (damagingEntity.typeId === "minecraft:player") {
logToDevs(`Player ${damagingEntity.name} hit ${hitEntity.typeId}`);
}
} catch (err) {
logToDevs(`${err.message} | Stack: ${err.stack}`, true);
}
});
system.runInterval(() => {
try {
// Periodic server-side health check
const players = world.getAllPlayers();
if (players.length > 0) {
logToDevs(`Server tick active. Online count: ${players.length}`);
}
} catch (err) {
logToDevs(`Interval failure: ${err.message}`, true);
}
}, 600);Testing Experimental Features safely
If your add-on relies on experimental toggles—such as Beta APIs in `@minecraft/server` or upcoming creator features—you must enable those toggles on the world locally before uploading it to the Realm. Realms do not provide toggles to flip experiments on or off from the cloud management screen; they simply read the `level.dat` configuration of the uploaded world.
Keep in mind that Realms automatically update to the latest retail version of Minecraft Bedrock as soon as it releases. If your add-on uses the `@minecraft/server` `beta` version string, a minor game update will almost certainly break your scripts on the Realm the day the update drops, because beta API signatures change between retail patches. Use stable version strings in your manifest dependencies whenever possible for Realm tests that run over several weeks.
Always use one of the three world slots on your Realm as a dedicated staging slot, or test on a separate disposable Realm subscription, before overwriting a live community world. Once a world has experimental toggles enabled and custom entities saved into its chunks, you cannot turn those toggles off without risking world corruption.
Which versions this applies to
Applies to all modern Minecraft Bedrock versions (1.20+ and 1.21+). No experimental toggle is required for standard add-ons, though worlds using Beta APIs must have the Beta APIs toggle enabled locally prior to uploading.
When it does not work
| What you see | Why | The fix |
|---|---|---|
| "Failed to apply packs" or "Upload failed: An error occurred" when replacing the Realm world. | The pack is either still located in your `development_behavior_packs` folder instead of the standard `behavior_packs` folder, or the pack contains thousands of tiny loose files that cause the Realm uploader to time out. | Export your add-on as a `.mcaddon` archive, delete the copies inside `development_behavior_packs` and `development_resource_packs`, and double-click the `.mcaddon` to install it properly before applying it to the world and uploading. |
| You uploaded a new version of the world, but the Realm is still running your old script code and showing old textures. | You kept the exact same `version` numbers in `manifest.json`. The Realm recognized the UUID and version pair as already existing in its cloud storage and skipped uploading the modified pack files. | Increment the version number (for example, from `[1, 0, 0]` to `[1, 0, 1]`) in the `header`, `modules`, and `dependencies` blocks of both your BP and RP manifests, re-apply them to the local world, and re-upload. |
| Custom entities are invisible or show up as purple-and-black checkered boxes for other players joining the Realm, even though they look fine to you. | You still have a local copy of the resource pack enabled in your Global Resources or development folders, so your client renders it from your hard drive, while the Realm world itself is not forcing connecting clients to download the RP. | Download the world, open the Resource Packs tab in the world settings, check the box labeled "Require players to accept resource packs to join", and re-upload the world to the Realm. |
| Scripts stop running completely after a Minecraft game update, and entities controlled by scripts freeze. | Your `BP/manifest.json` depends on a `-beta` version of `@minecraft/server`, and the Realm automatically updated to a newer retail version of Bedrock where that beta version is no longer supported. | Switch your script dependency to a stable release version (such as `"1.10.0"` or newer stable releases) so automatic game updates do not invalidate your script module. |
Reference, straight from the game files
Read out of the game itself, so the ids match the version you are building for.
