The Three Shape Components
In Bedrock Edition, a block's visual appearance has no automatic effect on its physical hitbox. A custom model assigned via the geometry component only changes what the player sees. If you load a small teapot model onto a block without changing its collision or selection components, players will still walk into an invisible full-block barrier and see a full 16x16x16 wireframe outline when aiming at it.
To make a custom shape work properly, you combine three components in your block's behavior file. First, minecraft:geometry points to the 3D model in your resource pack. Second, minecraft:collision_box defines the solid physical bounds that stop entities from walking or falling through the block. Third, minecraft:selection_box defines the raycast hitbox that determines where a player must aim to highlight, mine, or interact with the block.
| Component | What it does | Accepts Boolean |
|---|---|---|
| minecraft:geometry | Assigns the visual 3D model from the resource pack. | No (requires identifier or object) |
| minecraft:collision_box | Defines the solid physical bounds that block entity movement. | Yes (false removes collision) |
| minecraft:selection_box | Defines the wireframe hitbox used for mining and interaction. | Yes (false makes block untargetable) |
Coordinate System and Size Limits
Both minecraft:collision_box and minecraft:selection_box use pixel units matching Blockbench's grid, where a standard full block is 16x16x16 units. However, the coordinate origin is not at the corner of the block. The X and Z axes are centered at the middle of the block's floor, while the Y axis starts at the very bottom. This means the bottom-north-west corner of a standard full block is at [-8, 0, -8], and the top-south-east corner is at [8, 16, 8].
When defining a box, you provide two arrays of three numbers: origin and size. The origin array [X, Y, Z] sets the starting corner of your box, and the size array [W, H, D] extends the box positively along the X, Y, and Z axes from that origin. For example, a bottom slab starts at origin [-8, 0, -8] and has a size of [16, 8, 16].
The engine enforces strict boundaries on both collision and selection boxes. Neither box may extend outside the standard 16x16x16 block volume. Every part of your box must stay within -8 to +8 on the X and Z axes, and 0 to 16 on the Y axis. If your origin plus your size exceeds these limits—for example, an origin of [-8, 0, -8] with a height of 24—the game will clamp the box or fail to load the block altogether. Furthermore, each component only accepts a single rectangular box per state; you cannot list an array of multiple boxes to create an L-shaped staircase hitbox within a single component.
{
"format_version": "1.20.80",
"minecraft:block": {
"description": {
"identifier": "wiki:stone_pedestal"
},
"components": {
"minecraft:geometry": "geometry.stone_pedestal",
"minecraft:material_instances": {
"*": {
"texture": "stone_pedestal",
"render_method": "alpha_test"
}
},
"minecraft:collision_box": {
"origin": [-6, 0, -6],
"size": [12, 16, 12]
},
"minecraft:selection_box": {
"origin": [-6, 0, -6],
"size": [12, 16, 12]
}
}
}
}Passable and Untargetable Blocks
Not every block needs a physical presence. Custom tall grass, flowers, torches, and walk-through curtains should allow players and mobs to pass right through them. Instead of setting the size array to [0, 0, 0], you can pass the boolean value false directly to minecraft:collision_box. This completely disables physical collision for the block while keeping its selection box intact so players can still break it.
Similarly, setting minecraft:selection_box to false removes the selection wireframe and makes the block completely ignored by player raycasts. Players will click right through the block as if it were air. This is useful for invisible technical blocks, light sources, or temporary filler blocks, though you must remember that players in Survival mode will have no way to mine a block directly if its selection box is disabled.
{
"format_version": "1.20.80",
"minecraft:block": {
"description": {
"identifier": "wiki:tall_reeds"
},
"components": {
"minecraft:geometry": "minecraft:geometry.cross",
"minecraft:material_instances": {
"*": {
"texture": "tall_reeds",
"render_method": "alpha_test",
"face_dimming": false,
"ambient_occlusion": false
}
},
"minecraft:collision_box": false,
"minecraft:selection_box": {
"origin": [-6, 0, -6],
"size": [12, 14, 12]
}
}
}
}Lighting and Occlusion on Non-Cube Blocks
When you use a custom geometry that is smaller than a full cube, you will often notice two visual bugs: the ground underneath your block turns pitch black, or touching an adjacent solid block causes the touching face of the neighbor to disappear, letting players see into the void. This happens because the engine optimizes rendering by culling faces hidden behind custom blocks unless told otherwise.
For most custom geometries, Bedrock automatically adjusts face culling based on the geometry component, provided you are not using the built-in full block geometry. However, lighting and shadow behavior should be tuned alongside your shape. Adding minecraft:light_dampening set to 0 prevents your small custom block from blocking sky light and casting dark shadows onto the blocks beneath it. In your minecraft:material_instances component, setting ambient_occlusion to false stops dark shadow gradients from rendering on the model's faces, which is especially important for flat cross-model plants.
Dynamic Shapes with Permutations
Because collision and selection boxes are standard block components, you can override them inside permutations to change a block's physical shape based on block states. This is how you build openable gates, collapsible spikes, or slabs that can be placed on either the top or bottom half of a block space.
Furthermore, if you rotate a block using the minecraft:transformation component inside a permutation, the engine automatically rotates both the collision_box and selection_box along with the visual geometry. You do not need to manually recalculate the origin and size coordinates for north, south, east, and west facings—define the hitbox once in the base components block, and let the transformation component rotate the entire space.
{
"format_version": "1.20.80",
"minecraft:block": {
"description": {
"identifier": "wiki:toggle_barrier",
"states": {
"wiki:open": [false, true]
}
},
"components": {
"minecraft:geometry": "geometry.toggle_barrier_closed",
"minecraft:collision_box": {
"origin": [-8, 0, -2],
"size": [16, 16, 4]
},
"minecraft:selection_box": {
"origin": [-8, 0, -2],
"size": [16, 16, 4]
}
},
"permutations": [
{
"condition": "q.block_state('wiki:open') == true",
"components": {
"minecraft:geometry": "geometry.toggle_barrier_open",
"minecraft:collision_box": false,
"minecraft:selection_box": {
"origin": [-8, 0, -2],
"size": [16, 4, 4]
}
}
}
]
}
}Which versions this applies to
Stable in format_version 1.19.40 and higher with no experimental toggles required. The built-in minecraft:geometry.cross identifier requires format_version 1.20.60 or higher.
When it does not work
| What you see | Why | The fix |
|---|---|---|
| Content Log error: "minecraft:collision_box: box must be contained within (-8, 0, -8) to (8, 16, 8)" and the block falls back to a default hitbox or fails to load. | Your origin plus your size extends past the 16x16x16 block boundary. A common mistake is using [0, 0, 0] as the origin with a size of [16, 16, 16], which pushes the X and Z bounds out to +16 instead of +8. | Shift your origin on the X and Z axes into the negative range. For a centered box of width W and depth D, the origin should be [-W/2, Y, -D/2]. |
| The custom block model renders off-center compared to the wireframe selection box. | Your Blockbench model's pivot or bone positions are centered at [8, 0, 8] (Java Edition style) instead of [0, 0, 0] (Bedrock style), or your collision origin was not calculated from the center of the block floor. | Ensure your geometry in Blockbench uses the Bedrock Block format centered at X=0, Z=0, and verify that your collision_box origin uses [-8, 0, -8] as the corner reference. |
| Adjacent solid blocks have invisible faces where they touch the custom block, allowing players to see through the world. | The block is missing a valid custom minecraft:geometry component, or is using minecraft:geometry.full_block while trying to render transparent textures or smaller bounds. | Assign a custom geometry identifier in minecraft:geometry and set the material instance render_method to alpha_test or blend. |
Reference, straight from the game files
Read out of the game itself, so the ids match the version you are building for.
