How Permutations Work
Every custom block definition starts with a base `components` object. The components placed inside that root object apply to the block at all times unless something overrides them. Permutations sit alongside the base components as an array of objects, each containing a `condition` string and its own `components` block.
When a block is placed or updated in the world, Minecraft evaluates the `condition` of every entry in the `permutations` array from top to bottom. If a condition evaluates to true for the block's current state values, the game merges that permutation's components over the base components. If multiple permutations evaluate to true at the same time, their components are layered in the order they appear in the JSON file, meaning a later permutation in the array will win if both try to modify the exact same component.
You do not need to repeat unchanged components inside a permutation. If your base block defines `minecraft:destructible_by_mining` and `minecraft:geometry`, and your permutation only changes `minecraft:material_instances` to swap a texture, the block keeps its base geometry and mining speed automatically.
Structure and Syntax
The `permutations` array belongs inside `minecraft:block`, at the same level as `description` and the base `components` object. For a permutation to have something to check, you must either declare custom `states` inside the `description` object or use `traits` (such as `minecraft:placement_direction`) which inject vanilla states into your block automatically.
Inside the `condition` field, you write a Molang expression using the `q.block_state('namespace:state_name')` query. For boolean states, you can test them directly or compare them to `true` or `false`. For integer and string states, use standard comparison operators like `==`, `!=`, `<`, or `>`. You can also chain checks together using `&&` (AND) and `||` (OR) to target specific combinations of states.
| Field | What it does | Notes |
|---|---|---|
| permutations | Top-level array inside `minecraft:block` holding all conditional overrides. | Evaluated in array order from first to last. |
| condition | Molang string evaluated against the block's current state values. | Almost always uses `q.block_state(...)`. |
| components | Object containing the block components to apply when `condition` is true. | Overrides matching base components; leaves unmentioned ones intact. |
Example: Toggleable Lamp Block
A classic use case for permutations is a lamp or machine that turns on and off. The block below declares a single boolean state named `wiki:lit`. In its base `components` object, the block emits no light and uses an unlit texture named `lamp_off`. When `wiki:lit` becomes `true` (which you would trigger via a custom script component or `/setblock` command), the permutation overrides `minecraft:light_emission` to `15` and swaps the material instance to `lamp_on`.
Notice how `minecraft:geometry` and `minecraft:destructible_by_mining` are only written once in the base components. Whether the lamp is lit or unlit, it remains the same shape and takes the same time to break.
{
"format_version": "1.20.80",
"minecraft:block": {
"description": {
"identifier": "wiki:toggle_lamp",
"states": {
"wiki:lit": [false, true]
}
},
"components": {
"minecraft:geometry": "minecraft:geometry.full_block",
"minecraft:destructible_by_mining": {
"seconds_to_destroy": 1.5
},
"minecraft:light_emission": 0,
"minecraft:material_instances": {
"*": {
"texture": "lamp_off",
"render_method": "opaque"
}
}
},
"permutations": [
{
"condition": "q.block_state('wiki:lit') == true",
"components": {
"minecraft:light_emission": 15,
"minecraft:material_instances": {
"*": {
"texture": "lamp_on",
"render_method": "opaque"
}
}
}
}
]
}
}Rotating Blocks with Placement Traits
Combining permutations with block `traits` is the standard way to build directional blocks like furnaces, pillars, or custom furniture. When you enable the `minecraft:placement_direction` trait with `minecraft:cardinal_direction` in your block's description, Minecraft automatically sets that state to `north`, `south`, `east`, or `west` when a player places the block.
You then write four permutations—one for each cardinal direction—and apply the `minecraft:transformation` component inside each one. By rotating the block around the Y axis in 90-degree increments, a single model in your resource pack can face all four directions without needing four separate geometry files. If your block also has a custom collision or selection box that is not symmetrical, the `minecraft:transformation` component rotates those boxes along with the visual geometry.
{
"format_version": "1.20.80",
"minecraft:block": {
"description": {
"identifier": "wiki:directional_carved_stone",
"traits": {
"minecraft:placement_direction": {
"enabled_states": ["minecraft:cardinal_direction"]
}
}
},
"components": {
"minecraft:geometry": "geometry.carved_stone",
"minecraft:material_instances": {
"*": {
"texture": "carved_stone",
"render_method": "opaque"
}
}
},
"permutations": [
{
"condition": "q.block_state('minecraft:cardinal_direction') == 'north'",
"components": {
"minecraft:transformation": {
"rotation": [0, 0, 0]
}
}
},
{
"condition": "q.block_state('minecraft:cardinal_direction') == 'south'",
"components": {
"minecraft:transformation": {
"rotation": [0, 180, 0]
}
}
},
{
"condition": "q.block_state('minecraft:cardinal_direction') == 'west'",
"components": {
"minecraft:transformation": {
"rotation": [0, 90, 0]
}
}
},
{
"condition": "q.block_state('minecraft:cardinal_direction') == 'east'",
"components": {
"minecraft:transformation": {
"rotation": [0, 270, 0]
}
}
}
]
}
}Permutation Limits and Performance
Every possible combination of states you declare in `description` multiplies the total number of permutations the engine generates in memory for that block, regardless of how many entries you actually write in the `permutations` JSON array. A block with one four-value direction state and one boolean toggle state has 4 × 2 = 8 total state combinations. A block with three integer states of 16 values each would require 16 × 16 × 16 = 4,096 combinations, which will fail to load.
Minecraft Bedrock enforces a hard cap of 65,536 total permutations across all custom blocks in a world, and individual blocks are restricted to a much smaller number of state combinations (keep a single block at or below 64 combinations in modern format versions to avoid load errors). Instead of putting every conceivable state onto one block identifier, split unrelated states across multiple block identifiers when a block gets too complex.
Also keep in mind that `condition` strings inside `permutations` are only for checking `q.block_state()`. You cannot query the world time, player position, or entity variables inside a block permutation condition, because permutations are baked when the block state changes, not ticked every frame.
Which versions this applies to
Stable in `format_version` 1.19.40 and above without any experimental toggles. Traits (`minecraft:placement_direction` and `minecraft:placement_position`) require `format_version` 1.20.20 or higher.
When it does not work
| What you see | Why | The fix |
|---|---|---|
| Content Log error: "Permutation condition ... failed to parse" or the permutation never activates in-game. | String values inside `q.block_state()` were wrapped in double quotes without escaping, breaking the JSON string, or a string state value was compared without quotes around the target value (for example, `== north` instead of `== 'north'`). | Use single quotes inside the double-quoted JSON string for both the state identifier and string values: `"q.block_state('minecraft:cardinal_direction') == 'north'"`. |
| Block fails to register and Content Log reports that the block exceeded the maximum number of permutations. | The `states` object in `description` defines too many states or arrays with too many values, multiplying out past the per-block state combination limit. | Reduce the number of values in each state array, remove unused states, or split the block into two separate block files (for example, an `on` block and an `off` block). |
| Only one visual change or hitbox change applies when two permutations should be active at the same time. | Both permutations define the same component (such as `minecraft:material_instances` or `minecraft:transformation`). Components in later permutations overwrite the entire component from earlier permutations rather than merging sub-fields. | Write a third permutation further down the array with a combined condition (using `&&`) that includes the complete component configuration for when both states are active simultaneously. |
Reference, straight from the game files
Read out of the game itself, so the ids match the version you are building for.
