Wiki 9Minecraft Wiki 9Minecraft

Block Permutations

Conditionally swap or add block components based on active block states.

5Sections
2Code examples
3Known errors

Block permutations let a single custom block change its appearance, collision box, light emission, or physical behavior dynamically while in the world. By pairing Molang condition strings with custom or built-in block states, you can override base components without registering separate block identifiers for every state of a machine, lamp, or directional model. You reach for permutations whenever a block needs to rotate, toggle on and off, or grow through stages.

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.

FieldWhat it doesNotes
permutationsTop-level array inside `minecraft:block` holding all conditional overrides.Evaluated in array order from first to last.
conditionMolang string evaluated against the block's current state values.Almost always uses `q.block_state(...)`.
componentsObject 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.

BP/blocks/toggle_lamp.json
{
  "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.

BP/blocks/directional_carved_stone.json
{
  "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 seeWhyThe 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.