How Bedrock Biomes Work
In Minecraft Bedrock, biomes are data-driven files stored inside the behavior pack under the BP/biomes/ directory. Each JSON file defines a single biome using the minecraft:biome root object. A biome does not place individual trees or ores directly; instead, it defines the base terrain shape, the blocks that make up the ground, the local temperature and downfall, and a set of tags.
Other systems in your behavior pack read those tags to decide what to do. Entity spawn rules check biome tags through the minecraft:biome_filter component to decide which mobs appear. Feature rules use the exact same filter mechanism to scatter vegetation, structures, and ore veins across the world. You can either create a brand-new biome with your own namespace or override a vanilla biome by matching its file name and identifier without a namespace prefix.
Biome Definition Structure
Every biome file begins with a format_version and the minecraft:biome object, which is split into description and components. The description holds the identifier. Historically, vanilla biome overrides omitted the minecraft: prefix in their identifier (for example, plains instead of minecraft:plains), while custom biomes always require your custom namespace.
The components block holds the terrain, climate, and tag definitions. Below is a foundational biome definition that sets up a custom arid highland with coarse dirt and stone surfaces, warm climate values, and custom tags for feature and spawn filtering.
{
"format_version": "1.13.0",
"minecraft:biome": {
"description": {
"identifier": "mypack:arid_highlands"
},
"components": {
"minecraft:climate": {
"downfall": 0.1,
"snow_accumulation": [
0.0,
0.0
],
"temperature": 1.2
},
"minecraft:overworld_height": {
"noise_type": "mountains"
},
"minecraft:surface_parameters": {
"sea_floor_depth": 7,
"sea_floor_material": "minecraft:gravel",
"foundation_material": "minecraft:stone",
"mid_material": "minecraft:coarse_dirt",
"top_material": "minecraft:sand",
"sea_material": "minecraft:water"
},
"minecraft:overworld_generation_rules": {
"hills_transformation": "mypack:arid_highlands",
"generate_for_climates": [
[
"warm",
10
]
]
},
"monster": {},
"overworld": {},
"arid_highlands": {}
}
}
}Core Biome Components
While vanilla files contain many legacy and internal components, a small core set does the heavy lifting for add-on creators. Surface parameters dictate the blocks placed during the initial terrain pass, before any features or caves are carved. Generation rules tell the Overworld climate engine how likely this biome is to be picked when rolling a specific climate zone.
The table below outlines the primary components used in format version 1.13.0 and later.
| Component | What it does | Notes |
|---|---|---|
| minecraft:climate | Sets temperature, downfall, and snow accumulation. | Temperature above 0.15 prevents snow; downfall affects rain and fire spread. |
| minecraft:surface_parameters | Defines the top, mid, foundation, and sea floor blocks. | Accepts block identifiers or block descriptor objects. |
| minecraft:overworld_height | Controls the vertical terrain profile. | Uses either a preset noise_type string or a noise_params array of two floats. |
| minecraft:overworld_generation_rules | Injects the biome into the Overworld biome layout. | Climate categories are cold, medium, lukewarm, warm, and frozen. |
| minecraft:tags | Attaches filterable tags to the biome in newer format versions. | In 1.13.0, tags are written as empty JSON objects directly inside components. |
Biome Tags and Filtering
How you write tags inside a biome file depends on the format_version you target. In 1.13.0, any key inside the components object that does not have a namespace and is assigned an empty object (such as "overworld": {} or "desert": {}) is treated by the engine as a biome tag. In newer 1.16.0+ schemas, these bare keys were replaced by an explicit minecraft:tags component containing a tags array of strings.
Once a tag is attached to a biome, you do not need to reference the biome identifier directly in your spawn rules or feature rules. Instead, you test for the tag using has_biome_tag. This allows you to inject a custom biome into all existing vanilla mob spawning pools simply by giving it standard tags like monster, animal, and overworld.
{
"format_version": "1.8.0",
"minecraft:spawn_rules": {
"description": {
"identifier": "mypack:arid_scorpion",
"population_control": "monster"
},
"conditions": [
{
"minecraft:spawns_on_surface": {},
"minecraft:brightness_filter": {
"min": 0,
"max": 7,
"adjust_for_weather": true
},
"minecraft:biome_filter": {
"test": "has_biome_tag",
"operator": "==",
"value": "arid_highlands"
}
}
]
}
}Resource Pack Appearance
Behavior pack biome files only control server-side logic and block placement. Visual and audio properties—such as water surface color, fog distance, and ambient sounds—are handled on the client side in your resource pack.
To style your biome, create or edit RP/biomes_client.json. Keys inside the biomes object match your biome's short name or full identifier. From there, you can set water_surface_color, water_fog_color, and fog_identifier to point to a custom fog definition in RP/fogs/. Grass and foliage tints can also be influenced by the temperature and downfall values you set in the behavior pack's minecraft:climate component.
{
"biomes": {
"mypack:arid_highlands": {
"water_surface_color": "#43d5ee",
"water_fog_color": "#041f33",
"water_surface_transparency": 0.65,
"fog_identifier": "minecraft:fog_desert"
}
}
}Which versions this applies to
Vanilla biome overrides and biome tags work in stable Bedrock releases (format_version 1.13.0 is the baseline for Caves & Cliffs and older style biome files). However, generating custom biomes in the Overworld requires the Custom Biomes experimental toggle to be enabled on the world. Because Mojang disabled the legacy Caves & Cliffs generation pipeline after 1.18, custom minecraft:overworld_generation_rules injection is fragile across recent 1.20 and 1.21 updates and remains strictly experimental.
When it does not work
| What you see | Why | The fix |
|---|---|---|
| Custom biome never appears anywhere in a newly generated world, with no content log errors. | The Custom Biomes experimental toggle is turned off in the world settings, or the weight inside generate_for_climates is missing or set to 0. | Enable the Custom Biomes experiment before generating the world, and make sure generate_for_climates includes a valid climate category (such as 'medium' or 'warm') with a positive integer weight. |
| Content Log shows: [Biome][error] Failed to parse biome... unrecognized component. | You mixed 1.13.0 bare tag objects (like "overworld": {}) into a file using a newer format_version, or used the newer minecraft:tags component inside a 1.13.0 file without the matching schema. | Keep your tag syntax aligned with your format_version. For 1.13.0, write tags as empty objects at the bottom of the components list. |
| Custom blocks used in minecraft:surface_parameters generate as dirt or stone instead. | The block identifier is misspelled, or the custom block lacks a default permutation when referenced as a plain string. | Verify the exact identifier in your BP/blocks/ file and ensure it loads without errors in the Content Log. |
Reference, straight from the game files
Read out of the game itself, so the ids match the version you are building for.
