Wiki 9Minecraft Wiki 9Minecraft

Block Conditions for Features

Control where custom world generation features can attach, replace, or survive using block descriptors.

5Sections
2Code examples
3Known errors

When generating custom terrain decorations in a behavior pack, features do not blindly overwrite the world unless told to do so. Instead, feature files use block conditions to inspect the blocks around a target coordinate before placing anything. You reach for these conditions whenever you want a custom plant to only sprout on grass, an ore vein to only replace stone, or a stalactite to hang exclusively from cave ceilings.

How features check the world

Feature files evaluate placement at a specific coordinate passed down by a feature rule or a parent feature. Before placing the block, the engine runs through the validation arrays defined inside the feature definition. If any block test fails at that coordinate, the feature silently aborts placement for that specific spot and moves on.

Different feature types expose different condition fields depending on what they do. A single block feature cares about what it is replacing and what is directly around it, while an ore feature only cares about whether each block in its cluster path is allowed to be overwritten. Regardless of the feature type, the entries inside these condition fields all use the standard Bedrock block descriptor format.

Writing block descriptors

Every block condition list accepts either plain block identifier strings or detailed block descriptor objects. If you only care about the block type and want to match all of its state variations, a simple string like "minecraft:stone" or "minecraft:grass_block" is enough.

When you need to match a specific block state, such as only placing moss on waterlogged blocks or matching a specific wood pillar orientation, you use an object containing a "name" string and a "states" object. If you omit a state property from the "states" object, the game treats that property as a wildcard and matches any value for it.

BP/features/custom_fern_feature.json
{
  "format_version": "1.20.30",
  "minecraft:single_block_feature": {
    "description": {
      "identifier": "my_pack:custom_fern_feature"
    },
    "places_block": "my_pack:giant_fern",
    "enforce_survivability_rules": true,
    "enforce_placement_rules": true,
    "may_replace": [
      "minecraft:air",
      "minecraft:short_grass"
    ],
    "may_attach_to": {
      "bottom": [
        "minecraft:grass_block",
        "minecraft:podzol",
        {
          "name": "minecraft:dirt",
          "states": {
            "dirt_type": "coarse"
          }
        }
      ]
    }
  }
}

Single block replacement and attachment

The "minecraft:single_block_feature" is the most common place you will configure block checks. It provides two main condition structures: "may_replace" and "may_attach_to". The "may_replace" array lists every block that the feature is allowed to overwrite at the target coordinate. For surface plants and decorations, this almost always includes "minecraft:air", otherwise your feature will fail to place into empty space.

The "may_attach_to" object checks the neighboring blocks around the target position. You can specify arrays of valid blocks for "top", "bottom", "north", "south", "east", "west", or "all", and use " sides" as a shorthand for the four cardinal directions. By default, every side you list must match for the feature to succeed. If you want the feature to place when only some sides match—such as a vine attaching to any single adjacent cave wall—you can set "min_sides_must_attach" to an integer from 1 to 4.

Alongside these explicit checks, "minecraft:single_block_feature" also requires two boolean flags: "enforce_placement_rules" and "enforce_survivability_rules". These check the target block's own internal placement rules, such as whether a custom block's "minecraft:placement_filter" component permits it to live at that spot.

FieldWhat it doesNotes
may_replaceLists blocks the feature is permitted to overwrite at the target coordinate.Must include "minecraft:air" if placing into empty space.
may_attach_toChecks adjacent blocks by face direction (top, bottom, north, south, east, west, sides, all).Used in "minecraft:single_block_feature".
min_sides_must_attachLowers the required number of matching horizontal faces from 4 down to 1–4.Put inside "may_attach_to" alongside a "sides" array.
auto_rotateRotates the placed block to face the side it successfully attached to.Boolean inside "may_attach_to"; useful for wall-mounted blocks.
enforce_survivability_rulesChecks if the placed block can legally survive at the target coordinate.Required boolean in "minecraft:single_block_feature".
enforce_placement_rulesChecks if the placed block could legally be placed at the target coordinate.Required boolean in "minecraft:single_block_feature".

Ore feature replacement rules

When generating mineral veins with "minecraft:ore_feature", you do not check adjacent attachment faces. Instead, an ore feature uses an array called "replace_rules". Each entry in this array pairs a "places_block" descriptor with a "may_replace" array of target block descriptors.

The engine evaluates "replace_rules" in order for every block position inside the generated vein shape. This allows a single ore feature to seamlessly cross between normal stone and deep slate layers: the first rule replaces regular stone with the standard ore block, and the second rule replaces deepslate with the deepslate variant of the same ore.

BP/features/tin_ore_feature.json
{
  "format_version": "1.20.30",
  "minecraft:ore_feature": {
    "description": {
      "identifier": "my_pack:tin_ore_feature"
    },
    "count": 9,
    "replace_rules": [
      {
        "places_block": "my_pack:tin_ore",
        "may_replace": [
          "minecraft:stone",
          "minecraft:andesite",
          "minecraft:diorite",
          "minecraft:granite"
        ]
      },
      {
        "places_block": "my_pack:deepslate_tin_ore",
        "may_replace": [
          "minecraft:deepslate",
          "minecraft:tuff"
        ]
      }
    ]
  }
}

Growing features and ground conditions

Larger organic structures like "minecraft:growing_plant_feature" and "minecraft:multiface_feature" also rely on block descriptor arrays, though the property names match their specific geometry. A "minecraft:multiface_feature" (used for blocks like glow lichen) checks a "can_place_on" array to decide which cave walls or floors it can cling to.

Similarly, "minecraft:growing_plant_feature" uses "may_replace" to ensure the plant column only grows through empty air or water, while the base of the plant is anchored by checking neighboring blocks along its growth direction. When building multi-part structures using a "minecraft:aggregate_feature" or "minecraft:sequence_feature", it is common practice to put a strict "minecraft:single_block_feature" first in the list with "early_out": "first_failure" set on the parent feature, using the first block's conditions as a gatekeeper for the rest of the structure.

Which versions this applies to

Applies to Bedrock Edition 1.13.0 and newer, with flattened block names (such as "minecraft:short_grass" and split stone types) requiring 1.20.30 or higher. Stable; no experimental toggles are required for standard feature block conditions.

When it does not work

What you seeWhyThe fix
Surface plants or decorations never appear in the world, with no Content Log errors.You defined a "may_attach_to" bottom condition for the ground, but forgot to include "minecraft:air" inside "may_replace". Without "minecraft:air", the feature refuses to overwrite the empty air block above the ground.Add "minecraft:air" (and any ground cover like "minecraft:short_grass" or "minecraft:snow_layer" if desired) to the "may_replace" array.
Content Log shows an error about unknown block state or invalid block descriptor in your feature file.You used an outdated pre-flattening block name and state combination (such as "minecraft:stone" with a "stone_type" state) in a behavior pack targeting a modern "format_version".Use the modern flattened block identifiers directly as strings, such as "minecraft:granite", "minecraft:andesite", or "minecraft:short_grass".
Feature fails to load on world start with a schema validation error on "minecraft:single_block_feature".You omitted "enforce_placement_rules" or "enforce_survivability_rules". Unlike "may_replace" and "may_attach_to", those two boolean fields are mandatory in the JSON schema.Add both "enforce_placement_rules": true and "enforce_survivability_rules": true to the "minecraft:single_block_feature" object.

Reference, straight from the game files

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