Features & carvers
The worldgen decoration layer: the shared value-provider building blocks, configured features (the shapes) and placed features (where/how often they appear), and configured carvers that cut caves and canyons. Primary syntax targets 1.21+ (singular worldgen/configured_feature/, worldgen/placed_feature/, worldgen/configured_carver/ folders).
Shared building blocks
Several small value types appear across features, carvers, and structures. The dossier factors them out once; every schema below refers back to them. Wherever a field is typed as "vertical anchor", "height provider", "int provider", "float provider", or "block state provider", plug in one of the objects defined here.
Vertical anchor
A single Y position relative to the world. Use exactly one key.
| Key | Meaning |
|---|---|
absolute | A literal Y value. |
above_bottom | Y = minimum build height + n. |
below_top | Y = maximum build height − n (should not be negative). |
vertical anchor β the three forms
{ "absolute": 0 }
{ "above_bottom": 8 }
{ "below_top": 10 }
Height provider
Returns a Y using vertical anchors. Used for ore height ranges, carver origins, and structure start heights.
| Type | Fields |
|---|---|
constant | value (vertical anchor) β may also be given as a bare anchor object. |
uniform | min_inclusive, max_inclusive (anchors). |
biased_to_bottom | min_inclusive, max_inclusive, optional inner (default 1). |
very_biased_to_bottom | min_inclusive, max_inclusive, optional inner. |
trapezoid | min_inclusive, max_inclusive, optional plateau (flat middle length). |
weighted_list | distribution: list of { "data": <height provider>, "weight": <int> }. |
height provider β two forms
{ "type": "uniform", "min_inclusive": { "absolute": 0 }, "max_inclusive": { "absolute": 256 } }
{ "type": "trapezoid", "min_inclusive": { "above_bottom": 5 }, "max_inclusive": { "below_top": 10 }, "plateau": 20 }
Int provider & float provider
An int provider returns an integer for numeric parameters (vein size, patch tries, radii). A float provider mirrors it with constant / uniform / clamped_normal / trapezoid types and is used for carver radii.
| Type | Fields |
|---|---|
constant | value (int) β may be given as a bare int. |
uniform | min_inclusive, max_inclusive (ints, max ≥ min). |
biased_to_bottom | min_inclusive, max_inclusive. |
clamped | source (int provider), min_inclusive, max_inclusive. |
clamped_normal | mean (float), deviation (float), min_inclusive, max_inclusive. |
weighted_list | distribution: list of { "data": <int provider>, "weight": <int> }. |
int provider β two forms
{ "type": "uniform", "min_inclusive": 0, "max_inclusive": 7 }
{ "type": "clamped_normal", "mean": 8.0, "deviation": 3.0, "min_inclusive": 1, "max_inclusive": 16 }
Block state provider
Decides which block state to place at each position inside a feature (trunks, foliage, patches, disks). Wherever a feature field is typed "block state provider", use one of these.
| Type | Fields |
|---|---|
simple_state_provider (a.k.a. simple) | state (block state). |
weighted_state_provider | entries[]: { "data": <block state>, "weight": <int> } (non-empty). |
noise_provider | seed (long), noise (noise params), scale (float > 0), states[]. |
noise_threshold_provider | seed, noise, scale, threshold (−1..1), high_chance (0..1), low_states[], high_states[], default_state. |
dual_noise_provider | as noise_provider plus slow_noise, slow_scale, variety ([min,max] 1–64). |
randomized_int_state_provider | property (block property name), values (int provider), source (block state provider). |
rotated_block_provider | state (block state) β randomizes axis / facing. |
The noise field is a noise-parameters object (firstOctave + amplitudes[]), not an empty object β e.g. { "firstOctave": -3, "amplitudes": [1.0] }.
worldgen/placed_feature examples reuse these β weighted logs, then randomized crop age
{
"type": "weighted_state_provider",
"entries": [
{ "data": { "Name": "minecraft:oak_log", "Properties": { "axis": "y" } }, "weight": 3 },
{ "data": { "Name": "minecraft:birch_log", "Properties": { "axis": "y" } }, "weight": 1 }
]
}
{
"type": "randomized_int_state_provider",
"property": "age",
"values": { "type": "uniform", "min_inclusive": 0, "max_inclusive": 7 },
"source": { "type": "simple_state_provider", "state": { "Name": "minecraft:wheat" } }
}
noise_provider / dual_noise_provider create smooth patchy block variation (e.g. mixed grass/podzol) instead of per-block randomness. randomized_int_state_provider is how crops and berries generate at random growth ages.
Generation step (GenerationStep.Decoration). Placed features and structures are ordered into a shared, per-chunk decoration enum, stable since 1.18: raw_generation, lakes, local_modifications, underground_structures, surface_structures, strongholds, underground_ores, underground_decoration, fluid_springs, vegetal_decoration, top_layer_modification. A feature in an earlier step sees the world before later steps have run. (Placed features receive their step from the biome that lists them, not from the placed-feature JSON.)
Configured features
A configured feature at data/<namespace>/worldgen/configured_feature/ is a feature type bundled with its config. It never generates by itself β a placed feature references it and supplies the placement rules, or a biome references it. Root shape:
worldgen/configured_feature β root schema shape
{
"type": "minecraft:<feature_id>",
"config": { /* type-specific */ }
}
/place feature <configured_feature_id> [pos] places one directly for testing β it resolves against the configured_feature registry, not the placed-feature registry, and ignores placement modifiers.
Common feature types
| Category | Types |
|---|---|
| Vegetation | tree, flower, no_bonemeal_flower, random_patch, simple_random_selector, random_selector, random_boolean_selector, bamboo, sea_pickle, kelp, seagrass, vines, waterlogged_vegetation_patch, vegetation_patch, multiface_growth, sculk_patch, twisting_vines, weeping_vines |
| Terrain / blobs | ore, disk, lake, spring_feature, block_pile, delta_feature, iceberg, basalt_columns, basalt_pillar, netherrack_replace_blobs, fill_layer, geode, replace_single_block |
| Structures-in-features | fossil, desert_well, monster_room, huge_red_mushroom, huge_brown_mushroom, huge_fungus, nether_forest_vegetation |
| Blocks / columns | block_column, simple_block, block_pile, coral_tree, coral_claw, coral_mushroom, glow_lichen, dripstone_cluster, pointed_dripstone, large_dripstone |
Config-less (empty config) | blue_ice, bonus_chest, chorus_plant, desert_well, end_island, end_platform, freeze_top_layer, kelp, monster_room, no_op, vines, void_start_platform, weeping_vines |
tree
The most involved feature. It composes a trunk placer, a foliage placer, block state providers for logs/leaves/dirt, a minimum-size guard, and optional decorators. Schema shape (angle-bracket placeholders indicate where the building-block objects go):
worldgen/configured_feature β tree config shape
{
"type": "minecraft:tree",
"config": {
"trunk_provider": { /* block state provider β the log */ },
"foliage_provider": { /* block state provider β the leaves */ },
"trunk_placer": { "type": "...", "base_height": 4, "height_rand_a": 2, "height_rand_b": 0 },
"foliage_placer": { "type": "...", "radius": <int provider>, "offset": <int provider> },
"minimum_size": { "type": "two_layers_feature_size", "limit": 1, "lower_size": 0, "upper_size": 1 },
"dirt_provider": { /* block state provider β block placed under trunk */ },
"root_placer": { /* optional */ },
"decorators": [ /* required, may be empty β tree decorators */ ],
"ignore_vines": false,
"force_dirt": false
}
}
Trunk placers (all share numeric base_height, height_rand_a, height_rand_b):
| Type | Extra fields |
|---|---|
straight_trunk_placer | β |
forking_trunk_placer | β |
giant_trunk_placer | β |
mega_jungle_trunk_placer | β |
dark_oak_trunk_placer | β |
fancy_trunk_placer | β |
bending_trunk_placer | min_height_for_leaves, bend_length |
upwards_branching_trunk_placer | extra_branch_steps, place_branch_per_log_probability, extra_branch_length, can_grow_through |
cherry_trunk_placer | branch_count, branch_horizontal_length, branch_start_offset_from_top, branch_end_offset_from_top |
Foliage placers (all take radius + offset int providers, plus extras):
| Type | Extra fields |
|---|---|
blob_foliage_placer | height |
spruce_foliage_placer | trunk_height |
pine_foliage_placer | height |
acacia_foliage_placer | β |
bush_foliage_placer | β |
fancy_foliage_placer | height |
jungle_foliage_placer | height |
mega_pine_foliage_placer | crown_height |
dark_oak_foliage_placer | β |
random_spread_foliage_placer | foliage_height, leaf_placement_attempts |
cherry_foliage_placer | height, wide_bottom_layer_hole_chance, corner_hole_chance, hanging_leaves_chance, hanging_leaves_extension_chance |
Minimum size controls trunk width vs. height so the tree fits before it is placed:
| Type | Fields |
|---|---|
two_layers_feature_size | limit, lower_size, upper_size, optional min_clipped_height. |
three_layers_feature_size | limit, upper_limit, lower_size, middle_size, upper_size, optional min_clipped_height. |
Decorators (tree decorators β the required decorators[] array):
| Decorator | Fields |
|---|---|
trunk_vine | β |
leave_vine | probability |
cocoa | probability |
beehive | probability |
alter_ground | provider (block state provider) |
attached_to_leaves | probability, exclusion_radius_xz, exclusion_radius_y, required_empty_blocks, block_provider, directions |
Keep the tree's minimum_size in sync with the foliage_placer.radius. If foliage is wider than the reserved footprint it clips and the whole tree silently fails to place.
ore
Blob of ore blocks that replace matching targets. size is the vein size (int 0–64); discard_chance_on_air_exposure (float 0–1) is the per-block chance to skip a block adjacent to air (the "eaten by caves" look). Each targets[] entry is { target: <rule test>, state: <block state> }, where the rule test uses the same predicate grammar as processor rule tests (always_true, block_match, blockstate_match, tag_match, random_block_match, random_blockstate_match).
data/example/worldgen/configured_feature/ore_iron.json
{
"type": "minecraft:ore",
"config": {
"size": 9,
"discard_chance_on_air_exposure": 0.0,
"targets": [
{ "target": { "predicate_type": "minecraft:tag_match", "tag": "minecraft:stone_ore_replaceables" },
"state": { "Name": "minecraft:iron_ore" } },
{ "target": { "predicate_type": "minecraft:tag_match", "tag": "minecraft:deepslate_ore_replaceables" },
"state": { "Name": "minecraft:deepslate_iron_ore" } }
]
}
}
random_patch, disk, lake & geode
random_patch (and flower / no_bonemeal_flower) scatters a sub-feature. Note its feature field is a placed feature reference (or inline placed feature), not a configured one.
data/example/worldgen/configured_feature/flower_patch.json
{
"type": "minecraft:random_patch",
"config": {
"tries": 96,
"xz_spread": 7,
"y_spread": 3,
"feature": "example:placed_single_flower"
}
}
disk β a flat blob (clay/sand/gravel patches):
| Field | Meaning |
|---|---|
state_provider | Any block state provider for the disk blocks β a plain simple_state_provider or a rule_based_state_provider (both valid; see note). |
radius | Int provider, 0–8. |
half_height | Int provider, 0–4. |
target | Block predicate the disk may replace (vanilla uses matching_blocks). |
disk.state_provider is a generic block state provider, not hardcoded to rule-based β confirmed against vanilla configured features by sibling elkonia-wob: disk_clay/disk_gravel use a plain simple_state_provider, while disk_sand/disk_grass use rule_based_state_provider (all four with target: matching_blocks). This is not a version change β the field has always accepted any provider; the vanilla sand/grass disks just happen to use the rule-based one.
lake β takes fluid (block state provider) and barrier (block state provider). A minimal example:
data/example/worldgen/configured_feature/lava_lake.json
{
"type": "minecraft:lake",
"config": {
"fluid": { "type": "simple_state_provider", "state": { "Name": "minecraft:lava" } },
"barrier": { "type": "simple_state_provider", "state": { "Name": "minecraft:stone" } }
}
}
geode β the amethyst-geode generator. Its config is large: blocks (filling, inner_layer, alternate_inner_layer, middle_layer, outer_layer providers), layers (thickness floats), crack (generate_crack_chance, base_crack_size, crack_point_offset), inner_placements, plus int providers outer_wall_distance / distribution_points / point_offset, and min_gen_offset, max_gen_offset, invalid_blocks_threshold, use_potential_placements_chance.
Two more terrain features worth their fields:
| Feature | Fields |
|---|---|
spring_feature | state (fluid block state), rock_count (default 4), hole_count (default 1), requires_block_below (default true), valid_blocks (block id/tag/list). |
fossil | fossil_structures[] (NBT template ids), overlay_structures[] (same length), fossil_processors, overlay_processors, max_empty_corners_allowed (0–7). |
block_column | direction (up/down/north/east/south/west), allowed_placement (block predicate), prioritize_tip (bool), layers[] of { height: <int provider>, provider: <block state provider> }. |
delta_feature | contents (block state), rim (block state), size (int provider 0–16), rim_size (int provider 0–16). |
- Since 1.21 (pack_format 48): folder is singular
worldgen/configured_feature/. - Since 1.19:
sculk_patchandmultiface_growth(renamed from theglow_lichenfeature) added. - Since 1.20:
huge_fungusgainedreplaceable_blocks. - Since 1.21.4:
simple_blockgained optionalschedule_tick.
Tentative (26.x snapshots / pack_format ≥ 88, after 1.21.8): the registry worldgen/configured_feature is reported to become worldgen/feature with the config inlined into the root object (no separate config field), and geode block fields to accept ids/lists in addition to tags. This is forward-looking and unverified β do not apply it at a 1.21 baseline; confirm against the live wiki before relying on it.
Use random_selector / simple_random_selector to pick among multiple sub-features by weight, and set discard_chance_on_air_exposure > 0 on ores to give veins the "cave-eaten" look near air.
Placed features
A placed feature at data/<namespace>/worldgen/placed_feature/ wraps a configured feature with an ordered list of placement modifiers that decide where and how often it appears. Each modifier transforms a stream of candidate positions.
worldgen/placed_feature β root schema shape
{
"feature": "namespace:configured_feature_or_inline",
"placement": [ /* modifiers applied in order */ ]
}
Every placement modifier
| Modifier | Fields | Effect |
|---|---|---|
count | count (int provider, 0–256; stack modifiers for more) | Duplicate each position N times. |
count_on_every_layer | count (int provider) | N positions per exposed vertical layer. |
rarity_filter | chance (positive int) | Keep position with probability 1/chance. |
noise_based_count | noise_to_count_ratio (int), noise_factor (double), noise_offset (double, opt) | Count derived from surface noise. |
noise_threshold_count | noise_level (double), below_noise (int), above_noise (int) | Two-tier count by noise. |
in_square | (none) | Random X/Z offset 0–15 (spreads within the chunk). |
height_range | height (height provider β any form: constant, uniform, biased, trapezoid, weighted_list) | Set Y from a height provider. |
heightmap | heightmap (enum) | Set Y one above the named heightmap. |
random_offset | xz_spread (int provider, −16..16), y_spread (int provider) | Jitter the position. |
fixed_placement | positions (list of [x,y,z]) | Only emit if a listed position is in this chunk. |
biome | (none) | Drop position if the current biome doesn't list this feature. |
block_predicate_filter | predicate (block predicate) | Keep only where the predicate passes. |
surface_relative_threshold_filter | heightmap, min_inclusive (int, opt), max_inclusive (int, opt) | Keep by height relative to the surface. |
surface_water_depth_filter | max_water_depth (int) | Keep only where water is shallow enough. |
environment_scan | direction_of_search (up/down), max_steps (1–32), target_condition (block predicate), allowed_search_condition (block predicate, opt) | Walk vertically to a matching block. |
carving_mask 1.21–1.21.1 only | step (air/liquid) | Emit positions carved out by carvers. |
heightmap enum (used by heightmap and surface_relative_threshold_filter): WORLD_SURFACE_WG, WORLD_SURFACE, OCEAN_FLOOR_WG, OCEAN_FLOOR, MOTION_BLOCKING, MOTION_BLOCKING_NO_LEAVES.
Examples
data/example/worldgen/placed_feature/patch_flowers.json
{
"feature": "example:flower_patch",
"placement": [
{ "type": "minecraft:rarity_filter", "chance": 2 },
{ "type": "minecraft:in_square" },
{ "type": "minecraft:heightmap", "heightmap": "MOTION_BLOCKING" },
{ "type": "minecraft:biome" }
]
}
data/example/worldgen/placed_feature/ore_iron_upper.json (vanilla-style ore distribution)
{
"feature": "example:ore_iron",
"placement": [
{ "type": "minecraft:count", "count": 90 },
{ "type": "minecraft:in_square" },
{ "type": "minecraft:height_range",
"height": { "type": "trapezoid", "min_inclusive": { "absolute": 80 }, "max_inclusive": { "absolute": 384 } } },
{ "type": "minecraft:biome" }
]
}
- Since 1.18-pre1: placed features introduced (split out of the old configured-feature decorators).
- Since 1.21-pre2:
fixed_placementadded. - 1.21 / 1.21.1 (pack_format 48):
carving_maskis present and valid. - Removed 1.21.2 (24w33a, pack_format 57):
carving_maskwas removed β do not use it if targeting pack_format 57 or later.
Tentative (26.x snapshots): the count cap is reported to rise to 4096, and random_offset to be renamed offset with discrete x/y/z fields replacing xz_spread/y_spread. Both are unverified and out of scope for a 1.21 pack β verify against the live wiki before using.
- Canonical ordering: count/rarity → in_square → height/heightmap → filters → biome. Putting
biomelast prevents wasted work. in_squareis almost always required alongsidecount; without it every duplicated copy lands on the same X/Z.- Imitate vanilla ore distributions by pairing
countwith atrapezoidoruniformheight_range.
/place feature ignores placement modifiers β it stamps the configured feature at your cursor. Great for previewing the build, useless for verifying spawn rate.
Feature stacking
"Feature stacking" covers four related ways features layer during generation. Understanding all four is what lets you build composite terrain (a disk with plants on it, ore clusters, cave-wall growth) reliably.
1. The placement pipeline is a stack
A placed feature is an ordered list of placement modifiers, and that list is the stack: a stream of candidate positions flows through it top-to-bottom, and each modifier adds, drops, moves, or duplicates positions. Order matters β each modifier sees the stream as the previous one left it (e.g. heightmap before random_offset gives different results than the reverse).
2. Literal stacking β the count modifier
count duplicates each position N times (stacking copies onto one candidate). Two consequences:
countis capped 0β256. To exceed it, stack multiplecountmodifiers β each multiplies the stream, so twocount:100s β 10 000 attempts.count_on_every_layerstacks one position per exposed vertical layer β the mechanism behind cave-wall vegetation and glow lichen climbing a cliff.- Pair with
in_squareor every duplicate lands on the same X/Z (see the placement gotchas above).
3. Vertical stacking β features that place other features
Several configured-feature types reference other placed features, letting you nest feature logic:
random_selector,simple_random_selector,random_boolean_selectorβ choose among sub-features by weight/chance.random_patch,vegetation_patch,waterlogged_vegetation_patchβ theirfeaturefield is a placed feature, run many times over a patch (tries,xz_spread,y_spread). This is the "patch" pattern kanokarob's video calls Minecraft's most powerful feature.
So one biome entry can fan out: a random_selector β several random_patches β each placing a simple_block.
4. Decoration-step layering
A biome's features is a list of 11 lists, one per GenerationStep.Decoration (raw_generation β β¦ β underground_ores β β¦ β top_layer_modification). Two rules fall out:
- Across steps: a feature in an earlier step sees the world before later steps run β ores go in before vegetation so grass sits on the finished surface.
- Within a step: features generate in list order, so index 0 lays down before index 1 β how you stack a sand
diskand then a plant on top of it.
Minecraft builds one global feature ordering by topologically sorting every biome's per-step lists. If biome A lists [X, Y] in a step and biome B lists [Y, X] in the same step, that's a cycle β "Feature order cycle found" and the world won't generate. Keep the relative order of shared features identical across all biomes within each step, and reference each placed feature at exactly one step index.
Stacking can't target a structure. Placement modifiers only know noise, height, biome, and block predicates β never where a jigsaw landed. To hang a feature off a structure, bake a feature_pool_element into the jigsaw instead of stacking a biome feature.
Carvers
A configured carver at data/<namespace>/worldgen/configured_carver/ cuts caves and canyons after base terrain but before most decoration. There is no separate "placed carver" β a carver is attached to a biome via the biome's carvers field (e.g. { "air": [ "example:big_caves" ] }). Root:
worldgen/configured_carver β root schema shape
{ "type": "minecraft:cave | minecraft:nether_cave | minecraft:canyon", "config": { ... } }
Config fields
Universal fields (all three carver types):
| Field | Type | Meaning |
|---|---|---|
probability | float 0–1 | Chance each chunk attempts this carver. |
y | height provider | Vertical distribution of carve origins. |
lava_level | vertical anchor | At/below this Y, carved space fills with lava. |
replaceable | block id / tag / list | Blocks the carver may cut. |
debug_settings | object (optional) | debug_mode (bool) plus air_state, water_state, lava_state, barrier_state block states β visualization only. |
cave / nether_cave extras: yScale (float provider), horizontal_radius_multiplier (float provider), vertical_radius_multiplier (float provider), floor_level (float provider). nether_cave behaves like cave with wider tunnels and no water carving.
canyon extras: vertical_rotation (float provider) plus a shape object β distance_factor, thickness, horizontal_radius_factor (float providers), vertical_radius_default_factor, vertical_radius_center_factor (floats), width_smoothness (int).
data/example/worldgen/configured_carver/big_caves.json
{
"type": "minecraft:cave",
"config": {
"probability": 0.15,
"y": { "type": "uniform", "min_inclusive": { "above_bottom": 8 }, "max_inclusive": { "absolute": 180 } },
"yScale": { "type": "uniform", "min_inclusive": 0.1, "max_inclusive": 0.9 },
"lava_level": { "above_bottom": 8 },
"replaceable": "#minecraft:overworld_carver_replaceables",
"horizontal_radius_multiplier": { "type": "uniform", "min_inclusive": 0.7, "max_inclusive": 1.4 },
"vertical_radius_multiplier": { "type": "uniform", "min_inclusive": 0.8, "max_inclusive": 1.3 },
"floor_level": { "type": "uniform", "min_inclusive": -1.0, "max_inclusive": -0.4 }
}
}
- Since 1.21 (pack_format 48): folder is singular
worldgen/configured_carver/. - 1.16.2 – 1.21.x:
replaceable,lava_level, anddebug_settingsare all valid. - Since 1.18: carvers use a height-provider
yand multiplier-based radii.
Tentative (26.x snapshots): nether_cave, replaceable, lava_level, and debug_settings are reported removed, yScale renamed, and new cave-shape fields (thickness, start_vertical_radius_multiplier) added. All unverified and out of scope for a 1.21 pack.
Attach a carver only through a biome's carvers list; probability is the main density knob. Set debug_mode: true with distinct air_state/water_state/lava_state/barrier_state blocks to make cave shapes visible while tuning.
Sources
- Configured feature β Minecraft Wiki
- Tree definition β Minecraft Wiki
- Int provider β Minecraft Wiki
- Height provider β Minecraft Wiki
- Placed feature β Minecraft Wiki
- Block state provider β Minecraft Wiki
- Configured carver β Minecraft Wiki
- /place command β Minecraft Wiki
- Data pack version β Minecraft Wiki
- Misode worldgen generators
- kanokarob β "This is Minecraft's Most Powerful Feature" (the feature/patch system)