Wiki 9Minecraft Wiki 9Minecraft

N-Way Block Rotation (4-Way, 6-Way, and 16-Way)

How to rotate custom blocks horizontally, in all six directions, or at angled increments.

5Sections
3Code examples
4Known errors

Most decorative and functional custom blocks need to orient themselves based on how the player places them. In Minecraft Bedrock, you achieve N-way rotation by combining placement traits or custom block states with permutation-driven geometry transformations. You will reach for these patterns whenever you build furniture, directional machinery, pillar blocks, or angled signage.

How Block Rotation Works in Bedrock

Block rotation in Bedrock is split into two distinct jobs: recording the direction the block should face when placed, and rotating the visual model and hitboxes to match that recorded state. In older format versions, creators had to write complex Molang queries inside event triggers to calculate player facing angles. In modern Bedrock (format version 1.19.80 and onward), the game provides built-in block traits that automatically capture player orientation and write it into standardized block states.

Once a block state holds the directional value, you use the permutations array to check that state via Molang. Inside each matching permutation, the minecraft:transformation component rotates the block's geometry, collision box, and selection box. Because minecraft:transformation only accepts 90-degree increments, 4-way and 6-way rotations are handled natively through JSON components, whereas 16-way rotation requires a different approach using multi-bone geometries and scripting.

Placement Direction Traits Reference

For standard 4-way and 6-way rotations, you do not need to declare custom properties. Instead, you add the minecraft:placement_direction trait inside the description object of your block JSON. This trait unlocks built-in states that the engine updates automatically the moment the block is placed in the world.

You can enable one or both of the available states in a single block, though you will almost always pick just one depending on whether your block behaves like a furnace (horizontal only) or a dispenser (all six directions). The y_rotation_offset field allows you to shift the horizontal calculation in 90-degree steps, which is handy if you want the front of your model to face the player rather than away from them without editing your geometry file.

Enabled StatePossible ValuesBest Used For
minecraft:cardinal_directionnorth, south, east, west4-way horizontal blocks like chairs, furnaces, and carved pumpkins.
minecraft:facing_directiondown, up, north, south, east, west6-way omnidirectional blocks like observers, pistons, and logs.

4-Way Horizontal Rotation (Cardinal)

A 4-way rotation restricts the block to the horizontal plane, ignoring whether the player is looking up at the sky or down at the ground. To set this up, enable the minecraft:cardinal_direction state in the placement_direction trait. By default, Bedrock records the direction the player is looking toward. If you model your custom block in Blockbench facing North (the standard default), setting y_rotation_offset to 180 makes the front of the block face back toward the player when placed.

Each permutation checks query.block_state('minecraft:cardinal_direction') and applies a Y-axis rotation via minecraft:transformation. Notice how the rotation array takes [X, Y, Z] values in degrees. Because the transformation component rotates both the visual mesh and the bounding boxes simultaneously, if you have an asymmetrical collision box defined in your base components, it will automatically turn with the block.

BP/blocks/custom_chair.json
{
  "format_version": "1.20.80",
  "minecraft:block": {
    "description": {
      "identifier": "wiki:custom_chair",
      "traits": {
        "minecraft:placement_direction": {
          "enabled_states": ["minecraft:cardinal_direction"],
          "y_rotation_offset": 180
        }
      }
    },
    "components": {
      "minecraft:geometry": "geometry.custom_chair",
      "minecraft:material_instances": {
        "*": {
          "texture": "custom_chair",
          "render_method": "alpha_test"
        }
      },
      "minecraft:collision_box": {
        "origin": [-6, 0, -6],
        "size": [12, 10, 12]
      },
      "minecraft:selection_box": {
        "origin": [-6, 0, -6],
        "size": [12, 16, 12]
      }
    },
    "permutations": [
      {
        "condition": "query.block_state('minecraft:cardinal_direction') == 'north'",
        "components": {
          "minecraft:transformation": { "rotation": [0, 0, 0] }
        }
      },
      {
        "condition": "query.block_state('minecraft:cardinal_direction') == 'west'",
        "components": {
          "minecraft:transformation": { "rotation": [0, 90, 0] }
        }
      },
      {
        "condition": "query.block_state('minecraft:cardinal_direction') == 'south'",
        "components": {
          "minecraft:transformation": { "rotation": [0, 180, 0] }
        }
      },
      {
        "condition": "query.block_state('minecraft:cardinal_direction') == 'east'",
        "components": {
          "minecraft:transformation": { "rotation": [0, -90, 0] }
        }
      }
    ]
  }
}

6-Way Omnidirectional Rotation (Facing)

When a block needs to point ceiling-ward or floor-ward in addition to the four compass points, switch your enabled state to minecraft:facing_direction. This state evaluates the player's pitch as well as their yaw. If the player looks steeply up or down while placing the block, the state resolves to down or up respectively.

When building the geometry for a 6-way block, pay close attention to which face of your model is the active front. The example below assumes your base model faces North in Blockbench. For the up and down permutations, you pitch the model around the X-axis by -90 or 90 degrees. If you are making a pillar or log block that only needs three axes (X, Y, Z) rather than six distinct facing directions, you still use this exact setup, as the visual symmetry of the texture hides the difference between opposite directions like North and South.

BP/blocks/directional_vent.json
{
  "format_version": "1.20.80",
  "minecraft:block": {
    "description": {
      "identifier": "wiki:directional_vent",
      "traits": {
        "minecraft:placement_direction": {
          "enabled_states": ["minecraft:facing_direction"]
        }
      }
    },
    "components": {
      "minecraft:geometry": "geometry.directional_vent",
      "minecraft:material_instances": {
        "*": {
          "texture": "directional_vent",
          "render_method": "opaque"
        }
      }
    },
    "permutations": [
      {
        "condition": "query.block_state('minecraft:facing_direction') == 'up'",
        "components": {
          "minecraft:transformation": { "rotation": [-90, 0, 0] }
        }
      },
      {
        "condition": "query.block_state('minecraft:facing_direction') == 'down'",
        "components": {
          "minecraft:transformation": { "rotation": [90, 0, 0] }
        }
      },
      {
        "condition": "query.block_state('minecraft:facing_direction') == 'north'",
        "components": {
          "minecraft:transformation": { "rotation": [0, 0, 0] }
        }
      },
      {
        "condition": "query.block_state('minecraft:facing_direction') == 'west'",
        "components": {
          "minecraft:transformation": { "rotation": [0, 90, 0] }
        }
      },
      {
        "condition": "query.block_state('minecraft:facing_direction') == 'south'",
        "components": {
          "minecraft:transformation": { "rotation": [0, 180, 0] }
        }
      },
      {
        "condition": "query.block_state('minecraft:facing_direction') == 'east'",
        "components": {
          "minecraft:transformation": { "rotation": [0, -90, 0] }
        }
      }
    ]
  }
}

8-Way and 16-Way Fine Rotation

Creating a block that rotates in 22.5-degree increments (16-way, like a vanilla standing sign or skull) hits a hard limitation in Bedrock: the minecraft:transformation component strictly rejects any rotation angle that is not a multiple of 90. Furthermore, there is no built-in placement trait that divides player yaw into 8 or 16 segments. To solve this, you must combine a custom integer block state, the bone_visibility feature inside minecraft:geometry, and a small Script API custom component.

First, inside your 3D modeling software, duplicate your block's mesh into 4 separate bones rotated at 0, 22.5, 45, and 67.5 degrees. Because 4 bones multiplied by the 4 cardinal 90-degree transformations equals 16 total angles, you only need 4 bones in your geometry file to achieve full 16-way rotation. Alternatively, for a simpler JSON setup, you can create 16 pre-rotated bones (named rot_0 through rot_15) in a single geometry file and toggle them directly using bone_visibility.

Because old JSON block events were removed in recent format versions, you set your custom 0-to-15 state during placement using a Script API custom component, or by listening to the playerPlaceBlock event in your behavior pack script. In the block JSON below, a custom state wiki:rotation holds an integer from 0 to 15, and bone_visibility ensures only the bone matching that exact angle renders.

BP/blocks/angled_trophy.json
{
  "format_version": "1.20.80",
  "minecraft:block": {
    "description": {
      "identifier": "wiki:angled_trophy",
      "states": {
        "wiki:rotation": {
          "values": { "min": 0, "max": 15 }
        }
      }
    },
    "components": {
      "minecraft:geometry": {
        "identifier": "geometry.angled_trophy",
        "bone_visibility": {
          "rot_0": "query.block_state('wiki:rotation') == 0",
          "rot_1": "query.block_state('wiki:rotation') == 1",
          "rot_2": "query.block_state('wiki:rotation') == 2",
          "rot_3": "query.block_state('wiki:rotation') == 3",
          "rot_4": "query.block_state('wiki:rotation') == 4",
          "rot_5": "query.block_state('wiki:rotation') == 5",
          "rot_6": "query.block_state('wiki:rotation') == 6",
          "rot_7": "query.block_state('wiki:rotation') == 7",
          "rot_8": "query.block_state('wiki:rotation') == 8",
          "rot_9": "query.block_state('wiki:rotation') == 9",
          "rot_10": "query.block_state('wiki:rotation') == 10",
          "rot_11": "query.block_state('wiki:rotation') == 11",
          "rot_12": "query.block_state('wiki:rotation') == 12",
          "rot_13": "query.block_state('wiki:rotation') == 13",
          "rot_14": "query.block_state('wiki:rotation') == 14",
          "rot_15": "query.block_state('wiki:rotation') == 15"
        }
      },
      "minecraft:material_instances": {
        "*": {
          "texture": "angled_trophy",
          "render_method": "alpha_test"
        }
      }
    }
  }
}

Which versions this applies to

Applies to Bedrock Edition 1.20.80 and newer. The minecraft:placement_direction trait and minecraft:transformation component are stable since 1.19.80, and bone_visibility inside minecraft:geometry is stable since 1.19.60. No experimental toggles are required for any JSON shown on this page.

When it does not work

What you seeWhyThe fix
Content Log error: "minecraft:transformation: rotation must be in 90 degree increments" and the block fails to load.You entered an angle like 45 or 22.5 inside the rotation array of the minecraft:transformation component. The engine's block transformation matrix only supports orthogonal (90-degree) turns.Keep all values in minecraft:transformation strictly as multiples of 90 (0, 90, 180, -90, 270). Move any non-90-degree rotations into the bones of your Blockbench geometry file and control them with bone_visibility.
The block loads without errors, places in the world, but always faces the same direction regardless of how the player stands.Your permutation conditions are checking for legacy integer values (like 0, 1, 2, 3) instead of the lowercase string values used by placement traits, or you forgot to include the 'minecraft:' namespace inside query.block_state().Ensure your condition checks exact string names such as "query.block_state('minecraft:cardinal_direction') == 'north'" and verify the state is listed under enabled_states in your block description.
The block rotates horizontally, but faces away from the player instead of toward them when placed.By default, minecraft:cardinal_direction records the compass direction the player's camera is looking toward. If your model's front face points North in Blockbench, looking North places the model facing North (showing you its back).Add "y_rotation_offset": 180 inside the minecraft:placement_direction trait object, or rotate your mesh 180 degrees inside your modeling program.
Content Log error complaining that a custom block state has too many values when attempting fine rotation.A single custom block state in Bedrock cannot exceed 16 possible values, and a block cannot exceed 64 total permutations.Keep your rotation state capped at 16 values (0 to 15). If you need bone visibility for 16 angles, evaluate the state directly inside the bone_visibility Molang strings rather than creating 16 separate objects in the permutations array.

Reference, straight from the game files

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