Wiki 9Minecraft Wiki 9Minecraft

Shipping a World with an Add-On Bundled Inside

How to package behavior and resource packs inside a .mcworld or .mctemplate archive.

6Sections
3Code examples
4Known errors

Distributing a standalone add-on requires players to manually activate your behavior and resource packs before creating a map. When your project relies on custom structures, pre-built arenas, or specific game rules, bundling the add-on directly inside the world file guarantees the packs are active the moment the player loads in. You can distribute these self-contained worlds as standard playable saves or as reusable world templates.

World archives versus world templates

Bedrock Edition supports two custom archive extensions for worlds: .mcworld and .mctemplate. Both are standard ZIP files with their file extensions renamed, and both install straight into the game when a player opens them.

A .mcworld file imports directly into the player's active Worlds list. If the player ruins the terrain or breaks a mechanism, they have to re-import the file to start over. A .mctemplate file installs into the World Templates library instead. Players click the template to generate a fresh, untouched copy of your world whenever they want, making .mctemplate the standard choice for adventure maps, minigames, and survival spawns.

The difference between the two formats comes down to a single manifest.json file placed at the root of the world folder. A .mcworld archive does not require a root manifest, while a .mctemplate archive will fail to import as a template without one.

ExtensionWhere it installsRoot manifest requiredBest used for
.mcworldPlay > Worlds listNoSharing personal saves, quick test worlds, or single-run builds.
.mctemplateCreate New > World TemplatesYesAdventure maps, minigames, and custom survival experiences.

Folder layout inside the world

When you open a world directory inside your com.mojang/minecraftWorlds folder, you will see the db folder (which holds the LevelDB chunk data), level.dat, levelname.txt, and world_icon.jpeg. When an add-on is bundled into that world, two additional directories sit alongside the database: behavior_packs and resource_packs.

Your pack folders live inside those two directories. Unlike the development folders, which let you leave packs loosely linked from the global directories, a shippable world must have the complete pack folders physically copied inside its own behavior_packs and resource_packs directories. Alongside them, two JSON files at the world root tell the engine which packs are turned on and in what priority order: world_behavior_packs.json and world_resource_packs.json.

The safest way to build this layout is to create the world in Minecraft, apply your packs from the world edit screen while they live in your standard behavior_packs and resource_packs folders, and then use the in-game Export World button on desktop. The game automatically copies the active packs into the world folder and writes the JSON activation lists for you. On platforms without an export button, or when building from a script, you construct this layout by hand.

Activating packs with world pack lists

Simply dropping your pack folder into the world's behavior_packs directory does not turn it on. Minecraft reads world_behavior_packs.json and world_resource_packs.json at the root of the world folder to decide which packs to load when opening the save.

Each file contains a JSON array of objects. Every object needs two keys: pack_id, which must match the UUID in the header block of your pack's manifest.json, and version, which is the three-number array matching the header version of that same manifest.

The order of objects in the array controls pack priority. The pack at index 0 sits at the top of the active list and overrides anything below it. If your add-on consists of both a behavior pack and a resource pack, you must create both JSON files at the root of the world and point each one at its corresponding pack UUID.

world_behavior_packs.json
[
  {
    "pack_id": "8f4a6b12-3c9d-4e7a-9b1f-2d5e8a3c6f90",
    "version": [1, 0, 0]
  }
]

Writing a world template manifest

If you plan to ship a .mctemplate file, you need a manifest.json at the very root of the world folder, right next to level.dat. Do not confuse this with the manifests inside your behavior or resource packs; a template world ends up with three separate manifest.json files in total: one for the world root, one inside the behavior pack, and one inside the resource pack.

A world template manifest uses format_version 2 and declares a single module with the type set to world_template. It needs its own unique UUIDs in both the header and the module block—never reuse the UUIDs from your behavior or resource packs.

The header block also accepts lock_template_options as a boolean. When set to true, players creating a world from your template are warned that the world settings are locked by the creator. If they unlock the settings to change difficulty or enable cheats, the game strips the template coupling for that save.

manifest.json
{
  "format_version": 2,
  "header": {
    "name": "pack.name",
    "description": "pack.description",
    "uuid": "c3d9b842-7f1a-42e8-b6a5-918273645501",
    "version": [1, 0, 0],
    "lock_template_options": true
  },
  "modules": [
    {
      "type": "world_template",
      "uuid": "a1e5f723-9b4c-48d1-82e6-345678901234",
      "version": [1, 0, 0]
    }
  ]
}

Localizing the template name and icon

When you turn a world into a template, the game ignores levelname.txt for the template selection menu and reads the header name and description from the root manifest.json instead. While you can hardcode strings directly into the manifest, clean templates place localization keys there and resolve them using a texts folder at the root of the world.

Create a texts folder alongside level.dat, add an en_US.lang file (and any other languages you support), and list your active language codes inside texts/languages.json. The thumbnail shown in the template list is always read from world_icon.jpeg at the root of the world folder. Make sure this image is a true JPEG file—typically 800x450 pixels—and not a PNG file with its extension renamed, as some platforms will render a renamed PNG as a corrupted black square.

texts/en_US.lang
pack.name=Skyblock Factory
pack.description=A custom skyblock world with automated resource generators.

Compressing and packaging the archive

The final step is compressing the world files into a single archive. Select the contents inside your world folder—the db directory, behavior_packs, resource_packs, level.dat, manifest.json, and all sibling files—and compress them into a standard .zip archive.

Do not zip the outer world folder itself. When you open the finished archive in a zip viewer, level.dat and the db folder must sit immediately at the top level of the archive. If they are nested inside a subfolder, Minecraft will still report that the import started, but it will immediately throw a failure notification because it cannot locate level.dat at the root.

Once you have verified the internal structure of the .zip file, rename the file extension from .zip to .mcworld or .mctemplate. Double-clicking the renamed file on Windows or opening it through a file manager on mobile will launch Minecraft and import your world with the add-on already attached and ready to play.

Which versions this applies to

Applies to all modern Bedrock Edition versions (1.16.0 and later). No experimental toggles are required to bundle packs or create world templates, though if your behavior pack relies on experimental features like Beta APIs, you must enable those toggles in the world settings before exporting.

When it does not work

What you seeWhyThe fix
Toast notification says 'Level import failed' or 'World template import failed' immediately after opening the file.You zipped the parent folder containing the world rather than selecting the files inside the world folder, placing level.dat and manifest.json one directory too deep.Open your archive and check the root level. Re-zip the contents so that level.dat, the db folder, and manifest.json sit at the very top of the archive with no wrapper folder.
The world loads fine, but custom entities, blocks, and scripts do nothing until the player manually activates the packs in the world settings.The pack folders were copied into behavior_packs and resource_packs, but world_behavior_packs.json or world_resource_packs.json is missing, or the version array inside them does not match the pack's manifest.json.Verify that both world_behavior_packs.json and world_resource_packs.json exist at the world root and that every pack_id and three-number version array matches the header block of the corresponding bundled pack.
The world imports when renamed to .mcworld, but fails to import when renamed to .mctemplate.The root manifest.json is missing, or its module type is set to 'data' or 'resources' instead of 'world_template'.Add a root manifest.json next to level.dat with a module type of 'world_template' and two fresh UUIDs that do not collide with your add-on packs.
Other players joining the hosted world see missing-texture checkerboard blocks or invisible entities.The resource pack is bundled and listed in world_resource_packs.json, but joining clients are not forced to download it, or the pack exists only in the creator's global development_resource_packs folder.Ensure the complete resource pack folder is physically inside the world's resource_packs directory, and check the 'Require players to accept resource packs to join' box in the world settings before exporting.

Reference, straight from the game files

Read out of the game itself, so the ids match the version you are building for.