Wiki 9Minecraft Wiki 9Minecraft

Introduction to World Generation

Overview of features, feature rules, structures, and custom biomes in Bedrock behavior packs.

6Sections
2Code examples
3Known errors

World generation in Minecraft Bedrock add-ons is data-driven, controlled entirely through JSON files inside your behavior pack. You use these systems whenever you need to place custom ores underground, scatter new foliage across the surface, spawn Jigsaw structures, or alter the terrain and climate of biomes. Understanding how the engine separates placement logic from the actual blocks being placed is the first step to modifying a world.

The Core Worldgen Systems

Bedrock divides world generation into four distinct systems, each living in its own behavior pack folder. Rather than putting all placement logic into a single file, the game separates 'where' something generates from 'what' actually gets built in the world.

For the majority of add-on projects, you will spend most of your time pairing Feature Rules with Features. Features define the physical object—such as an ore vein, a single block, or a cluster of flowers—while Feature Rules define the biome conditions, frequency, and coordinate math required to place that feature inside a newly generated chunk.

SystemBehavior Pack FolderWhat it does
Feature RulesBP/feature_rules/Determines when, where, and how often a feature attempts to generate within a chunk based on biome tags and Molang math.
FeaturesBP/features/Defines the actual blocks to place or the logic to chain multiple features together (such as ore veins, single blocks, or scatter patterns).
StructuresBP/structures/Holds saved .mcstructure files exported from Structure Blocks, which can be placed into the world by Jigsaw systems or structure features.
BiomesBP/biomes/Configures climate, surface blocks, terrain height parameters, and the biome tags that Feature Rules and entity spawn rules listen for.

How Features and Feature Rules Connect

A feature will never appear in the world on its own unless another file calls its identifier. The entry point for all natural feature generation is a Feature Rule. When a new chunk generates, the engine evaluates all active Feature Rules whose biome filters match the current biome.

Once a Feature Rule's conditions pass, it calculates a target coordinate (X, Y, and Z) and triggers the specific feature listed in its description block. That feature might place blocks directly, like a `minecraft:ore_feature`, or it might be a proxy feature like `minecraft:aggregate_feature` or `minecraft:scatter_feature` that runs further coordinate offsets and calls yet another feature down the chain.

Generation Passes

World generation happens in a strict sequential order within every chunk, controlled by the `distribution_pass` property inside a Feature Rule. Choosing the correct pass is critical because a feature can only check or replace blocks that already exist at that point in the chunk's lifecycle.

For example, ores use `underground_pass` because the base stone of the terrain has already been carved out, whereas trees and flowers use `surface_pass` so they can accurately query the final heightmap of the grass or sand. There is also a `sky_pass` for floating elements, and `pregeneration_pass` or `first_pass` for heavy modifications that must happen before standard terrain decoration.

Minimal Example: Generating a Custom Ore

To put a custom block underground, you need two JSON files: one in `BP/features/` to define the ore cluster and what vanilla blocks it is allowed to overwrite, and one in `BP/feature_rules/` to scatter that cluster through Overworld stone.

First, create the `minecraft:ore_feature`. Note that the file name must match the identifier name (without the namespace) for the game to locate and link the feature reliably.

BP/features/custom_copper_ore_feature.json
{
  "format_version": "1.13.0",
  "minecraft:ore_feature": {
    "description": {
      "identifier": "example:custom_copper_ore_feature"
    },
    "count": 8,
    "replace_rules": [
      {
        "places_block": "minecraft:copper_block",
        "may_replace": [
          "minecraft:stone",
          "minecraft:andesite",
          "minecraft:diorite",
          "minecraft:granite"
        ]
      }
    ]
  }
}

Attaching the Feature Rule

Next, create the Feature Rule that references `example:custom_copper_ore_feature` in its `places_feature` field. This rule checks for the `overworld` biome tag during the `underground_pass`, and attempts to spawn the vein 10 times per chunk at a uniform random height between Y=0 and Y=64, across the full 16x16 horizontal span of the chunk.

BP/feature_rules/overworld_custom_copper_ore.json
{
  "format_version": "1.13.0",
  "minecraft:feature_rules": {
    "description": {
      "identifier": "example:overworld_custom_copper_ore",
      "places_feature": "example:custom_copper_ore_feature"
    },
    "conditions": {
      "placement_pass": "underground_pass",
      "minecraft:biome_filter": [
        {
          "test": "has_biome_tag",
          "operator": "==",
          "value": "overworld"
        }
      ]
    },
    "distribution": {
      "iterations": 10,
      "x": {
        "distribution": "uniform",
        "extent": [ 0, 16 ]
      },
      "y": {
        "distribution": "uniform",
        "extent": [ 0, 64 ]
      },
      "z": {
        "distribution": "uniform",
        "extent": [ 0, 16 ]
      }
    }
  }
}

Biome Tags and Filtering

You rarely target a single biome by its full identifier in a Feature Rule. Instead, `minecraft:biome_filter` uses `has_biome_tag` to query the tags assigned to biomes inside their `BP/biomes/` definition files. Tags like `overworld`, `monster`, `forest`, `cold`, and `ocean` allow your features to integrate automatically with both vanilla biomes and any custom biomes that share those tags.

You can combine multiple filter tests using `all_of` and `any_of` arrays inside `minecraft:biome_filter` to narrow down placement—for instance, requiring a biome to have the `forest` tag while excluding any biome with the `mutated` or `frozen` tags.

Which versions this applies to

Features and Feature Rules (`format_version` 1.13.0) are stable and work in base worlds since Bedrock 1.13.0 without any experimental toggles. Modifying vanilla biomes or adding custom biomes in `BP/biomes/` has historically required experimental toggles (such as Custom Biomes) depending on the exact engine version.

When it does not work

What you seeWhyThe fix
Content Log Error: [Features][error]-Feature [example:my_feature] does not match expected file nameUnlike blocks or entities, Bedrock's feature parser strictly requires the JSON filename (excluding the .json extension) to match the identifier string after the colon.If your feature identifier is "example:custom_copper_ore_feature", ensure the file is named exactly "custom_copper_ore_feature.json" inside the BP/features/ folder or a subfolder.
The pack loads with zero Content Log errors, but the feature never generates in the world.Either you are exploring chunks that were already generated before the pack was applied, or the feature's replacement/placement rules are failing against the blocks at the chosen Y level (for instance, using a heightmap query in `underground_pass` or setting Y extents below -64).Test in a brand new world or teleport thousands of blocks into unvisited chunks. Temporarily raise `iterations` to 50 and set `places_block` to something unmistakable like `minecraft:glowstone` on the surface to verify your Feature Rule is firing.
Surface features like custom plants or single blocks generate floating in the air or buried underground.The Feature Rule's `y` distribution is using fixed numbers instead of querying the terrain heightmap.In your Feature Rule's `distribution` block, set `"y": "query.heightmap(variable.worldx, variable.worldz)"` so the feature evaluates right at the highest solid block of that X/Z column.

Reference, straight from the game files

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