How format_version and min_engine_version interact
Every behaviour and resource pack uses two distinct version numbers: min_engine_version inside manifest.json, and format_version at the top of individual JSON files like entities, blocks, and items. They do not do the same job, and bumping them blindly when an update releases is the most common way creators break their own packs.
The min_engine_version array in your manifest tells the game the minimum Bedrock release required to load the pack, and it also sets the baseline behaviour for certain engine systems, such as command execution rules inside function files. If a player is on an older game version than this array, the game refuses to load the pack.
By contrast, format_version tells the JSON parser which schema to validate a specific file against. When Mojang changes how a component works, they tie the new structure to a newer format_version. If your block file specifies "1.20.20", the game parses that file using the 1.20.20 ruleset even when the player is running 1.21.40. Because of this, you should leave format_version alone on working files unless you specifically want to adopt a component introduced in a later update.
| Version Field | Where it lives | What happens when you raise it |
|---|---|---|
| header.min_engine_version | BP/manifest.json, RP/manifest.json | Locks out older game clients and updates global engine behaviors (like command syntax in .mcfunction files) to the newer standard. |
| format_version | Individual JSON files (blocks, items, entities, recipes) | Forces that single file to be read using the newer schema. Old component names removed in that version will immediately stop working in that file. |
| dependencies[].version | BP/manifest.json (for Script API modules) | Changes which version of @minecraft/server your script imports. Requires updating your TypeScript/JavaScript code to match API renames. |
Migrating block and item schemas safely
When you do decide to raise the format_version on an existing block or item file—for instance, to gain access to a newer component—you must update any deprecated components in that same file at the same time. The game will not mix schemas within a single JSON document.
For example, older custom blocks often used minecraft:destroy_time and minecraft:block_light_emission. In newer format versions (such as 1.20.20 and later), the parser expects minecraft:destructible_by_mining and minecraft:light_emission instead. If you bump the format_version to a modern number without renaming those components, the Content Log will throw a schema error and your block will fall back to default stone-like properties.
Never run a global find-and-replace across your whole pack to bump format_version on patch day. Upgrade one file at a time, only when that specific asset needs a new feature, and test it with the Content Log enabled.
{
"format_version": "1.20.80",
"minecraft:block": {
"description": {
"identifier": "example:copper_lamp",
"menu_category": {
"category": "construction"
}
},
"components": {
"minecraft:destructible_by_mining": {
"seconds_to_destroy": 2.5
},
"minecraft:destructible_by_explosion": {
"explosion_resistance": 6.0
},
"minecraft:light_emission": 15,
"minecraft:geometry": "minecraft:geometry.full_block"
}
}
}Script API dependencies and the beta channel
The Script API handles versioning inside BP/manifest.json under the dependencies array. Each module, such as @minecraft/server or @minecraft/server-ui, has two tracks: stable numbered versions (like "1.11.0") and a single rolling "beta" version (like "1.12.0-beta").
Stable module versions are backwards-compatible. If your manifest requests version "1.10.0" of @minecraft/server, future versions of Minecraft will continue to provide the exact classes, methods, and properties that existed in 1.10.0, even if Mojang renames or removes those methods in 1.14.0.
The -beta track has zero backwards compatibility. Only one beta version exists in the engine at any given time. Whenever the game updates to a new minor release, the old beta version string is deleted from the game client. Any pack referencing an outdated -beta version in its manifest will completely fail to initialize its scripts on the new update. Use beta modules only for testing upcoming features, never for a released pack.
{
"format_version": 2,
"header": {
"name": "Stable Script Example",
"description": "Uses a locked stable script module version.",
"uuid": "8a7b6c5d-4e3f-2a1b-9c8d-7e6f5a4b3c2d",
"version": [1, 0, 0],
"min_engine_version": [1, 21, 0]
},
"modules": [
{
"type": "script",
"language": "javascript",
"uuid": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"entry": "scripts/main.js",
"version": [1, 0, 0]
}
],
"dependencies": [
{
"module_name": "@minecraft/server",
"version": "1.11.0"
}
]
}Command syntax changes in functions
Unlike JSON files, .mcfunction files do not have their own format_version header. Instead, the game decides how to parse your commands based on the min_engine_version in your behaviour pack's manifest.json.
When Mojang overhauls a command—such as the transition from the old /execute syntax to the modern chained /execute as ... at ... run syntax, or replacing data integers with block states in /setblock and /fill—they keep the old syntax working for packs with a older min_engine_version. As soon as you raise min_engine_version past the cutoff version for that command change, every function file in your pack must use the new syntax or those command lines will fail to register.
Avoiding vanilla overrides that go stale
The hardest update bugs to fix happen when an add-on copies and modifies a vanilla file, such as BP/entities/player.json or RP/blocks.json. Because Bedrock loads the highest-priority pack's file in full rather than merging JSON objects, your copy of player.json completely replaces the base game's file.
When a game update adds a new mechanic—like a new status effect, a crawling state, or interactions with a new mob—Mojang adds components and component groups to the vanilla player.json. If your pack overrides player.json with a copy taken from two updates ago, players using your add-on will silently lose all of those new vanilla mechanics.
Where possible, replace vanilla file overrides with event-driven scripts using @minecraft/server, or use resource pack render controllers and attachables that hook into entities without replacing their core definition. If you have no choice but to override a vanilla file, diff your copy against the updated vanilla template pack after every major release and merge Mojang's additions into your file.
Which versions this applies to
Applies to all Bedrock versions. Packs using stable JSON schemas and stable Script API versions require no experimental toggles. Packs using "-beta" script modules require the Beta APIs world toggle and will break on every major game update.
When it does not work
| What you see | Why | The fix |
|---|---|---|
| Pack scripts stop running immediately after a game update, and the Content Log reports: "Module [@minecraft/server] with version [1.x.0-beta] does not exist." | Your BP/manifest.json depends on a "-beta" version of a script module. Beta module versions are removed and replaced every time the game updates. | Change the dependency version in BP/manifest.json to a stable release number (such as "1.11.0"), turn off the Beta APIs toggle, and replace any beta-only methods in your code. |
| Custom blocks or items lose their textures, mining speed, or behaviours right after you raised their format_version. | You raised the file's format_version across a schema boundary where old components were deprecated or moved, without updating the component names in the file. | Either revert format_version back to the version the file was written for, or check the Content Log for "is not a valid component" errors and update the components to match the newer schema. |
| Commands inside .mcfunction files suddenly fail with syntax errors after you updated manifest.json. | Raising header.min_engine_version in BP/manifest.json opts all function files into the newer command parser, which rejects legacy command syntax like numeric block data values. | Update the commands in your .mcfunction files to use modern syntax (such as block states in square brackets), or lower min_engine_version if you do not actually need features from the newer engine. |
Reference, straight from the game files
Read out of the game itself, so the ids match the version you are building for.
