Structures & jigsaw
The full custom-structure pipeline: the structure definition, the structure set that places it, the template pool and processor list that assemble its pieces, and the .nbt builds plus the structure-block / jigsaw-block workflow behind them. Primary syntax targets 1.21+ (singular worldgen/structure/ and structure/ folders).
Structure definition
The structure definition JSON at data/<namespace>/worldgen/structure/ is distinct from the .nbt build files (see below). It declares which biomes the structure may generate in, its generation step, mob-spawn overrides, terrain adaptation, and β for jigsaw structures β the starting template pool and expansion limits.
worldgen/structure β jigsaw root schema shape
{
"type": "minecraft:jigsaw",
"biomes": "#minecraft:has_structure/village_plains",
"step": "surface_structures",
"terrain_adaptation": "beard_thin",
"spawn_overrides": {},
"start_pool": "example:village/town_centers",
"size": 6,
"start_height": { "absolute": 0 },
"project_start_to_heightmap": "WORLD_SURFACE_WG",
"max_distance_from_center": 80,
"use_expansion_hack": false
}
Structure types
One data-driven type plus fifteen hardcoded types. Most custom work uses jigsaw.
| Kind | Types |
|---|---|
| Data-driven | jigsaw β villages, outposts, bastions, ancient cities, trail ruins, trial chambers, and all custom structures. |
| Hardcoded (15) | buried_treasure, desert_pyramid, end_city, fortress, igloo, jungle_temple, mineshaft, nether_fossil, ocean_monument, ocean_ruin, ruined_portal, shipwreck, stronghold, swamp_hut, woodland_mansion |
Hardcoded types accept the common fields below plus a few type-specific ones β e.g. mineshaft has mineshaft_type + probability; ocean_ruin has biome_temperature, large_probability, cluster_probability; ruined_portal has a setups[] list; shipwreck has is_beached; nether_fossil has height.
Common fields (all structure types)
| Field | Notes |
|---|---|
type | One of the types above. |
biomes | A biome id, an inline array, or a #tag. Structure biome tags live in tags/worldgen/biome/. |
step | Generation step enum β surface_structures is typical. (Full enum: raw_generation, lakes, local_modifications, underground_structures, surface_structures, strongholds, underground_ores, underground_decoration, fluid_springs, vegetal_decoration, top_layer_modification.) |
spawn_overrides | Per-mob-category spawn rules (optional). See below. |
terrain_adaptation | none, beard_thin, beard_box, bury, or encapsulate. See below. |
spawn_overrides is an object keyed by mob category (monster, creature, ambient, water_creature, water_ambient, misc, underground_water_creature, axolotls). Each entry sets a bounding_box (piece or full) and a spawns list:
spawn_overrides β one category
{
"monster": {
"bounding_box": "piece",
"spawns": [ { "type": "minecraft:pillager", "weight": 1, "minCount": 1, "maxCount": 2 } ]
}
}
An empty spawns list suppresses natural spawns inside the box β the Ancient City / Trial Chamber "no mobs wander in" trick.
terrain_adaptation blends the structure into surrounding terrain, and the adaptation counts against max_distance_from_center:
| Value | Effect |
|---|---|
none | Do nothing. |
beard_thin | Light blending under/around pieces. |
beard_box | Heavy blending. |
bury | Encase in the dimension's base block (used by strongholds). |
encapsulate | Fully surround (used by trial chambers). |
Jigsaw-specific fields
| Field | Type / values |
|---|---|
start_pool | Template pool id (must contain ≥ 1 element) β the first piece. |
size | Int 0–20 (max jigsaw recursion depth; villages use 6). |
start_height | Height provider (see projection behavior below). |
project_start_to_heightmap | Heightmap enum, or omit to disable surface projection. |
max_distance_from_center | Int; horizontal Chebyshev cap. Hard max 128 (1–128 if terrain_adaptation: none, ≤ 116 otherwise). |
use_expansion_hack | Bool β legacy vertical-expansion behavior. |
pool_aliases | List β redirect pool names at generation time (see below). |
dimension_padding | { "bottom": n, "top": n } β keep pieces away from world limits. |
liquid_settings | apply_waterlogging (default) or ignore_waterlogging. |
start_height × project_start_to_heightmap interaction:
- Projected (heightmap set):
start_heightis a relative Y from the surface.0= one block into the ground; positive raises, negative buries. Useabsoluteanchors. - Not projected (heightmap omitted):
start_heightis the literal spawn Y regardless of terrain. May useabsolute/above_bottom/below_top(Nether structures usebelow_topto sit under the roof).
pool_aliases entries take one of three shapes:
pool_aliases β direct, random, random_group
{ "type": "minecraft:direct", "alias": "example:target", "target": "example:pool_a" }
{ "type": "minecraft:random", "alias": "example:target",
"targets": [ { "data": "example:pool_a", "weight": 1 }, { "data": "example:pool_b", "weight": 2 } ] }
{ "type": "minecraft:random_group",
"groups": [ { "data": [ /* list of direct/random aliases */ ], "weight": 1 } ] }
data/example/worldgen/structure/tall_tower.json (single-piece surface structure)
{
"type": "minecraft:jigsaw",
"biomes": "#minecraft:has_structure/mineshaft",
"step": "surface_structures",
"terrain_adaptation": "beard_thin",
"start_pool": "example:tall_tower",
"size": 1,
"start_height": { "absolute": 0 },
"project_start_to_heightmap": "WORLD_SURFACE_WG",
"max_distance_from_center": 80,
"use_expansion_hack": false,
"spawn_overrides": {}
}
- Since 1.19 (22w11a): the consolidated
jigsawtype was introduced, merging the oldvillage/pillager_outpost/bastion_remnantconfigured-structure-feature types; the registry moved fromconfigured_structure_featuretostructure. - Since 1.21 (pack_format 48): folder is singular
worldgen/structure/;dimension_padding,liquid_settings,pool_aliases, and split horizontal/vertical distance handling are available. sizemax: was 7 in ≤ 1.20.2, raised to 20 from 1.20.3+.- Structure biome tags live in
tags/worldgen/biome/β nottags/biome/.
- Single-build structure:
size: 1, astart_poolwith onesingle_pool_element, and a start piece containing one downward/heightmap-facing jigsaw β no other pieces needed. - Every jigsaw structure gets a random rotation even with
alignedjoints β design relative-coordinate mechanics (functions, puzzles) to be rotation-agnostic behind an anchor block. - Reduce
max_distance_from_center/sizeif a sprawling structure hurts chunk-load performance.
Structure set
A structure set at data/<namespace>/worldgen/structure_set/ controls where and how often a group of structure definitions is attempted. Biome validity is not here β that lives on each structure. Vanilla groups same-frequency structures (all village biome variants) into one set.
worldgen/structure_set β root schema shape
{
"structures": [ { "structure": "example:tall_tower", "weight": 1 } ],
"placement": { "type": "minecraft:random_spread", "salt": 1234567, "spacing": 32, "separation": 8 }
}
Fields
structures[] β each { "structure": <id>, "weight": <positive int> }. On a successful attempt, one is chosen by weight among those whose biome/conditions pass.
placement common fields:
| Field | Notes |
|---|---|
type | minecraft:random_spread or minecraft:concentric_rings. |
salt | Non-negative int seed offset (unique per set). |
frequency | Float 0–1 (default 1) β attempt keep-chance. |
frequency_reduction_method | default, legacy_type_1, legacy_type_2, legacy_type_3. |
locate_offset | [x,y,z] chunk offset, each −16..16. |
exclusion_zone | { "other_set": <id>, "chunk_count": 1–16 } β fail if too near another set. |
random_spread extras: spacing (0–4096 chunks, average grid cell), separation (0–4096, minimum gap, must be < spacing), spread_type (linear default, or triangular).
concentric_rings extras (used for strongholds): distance (0–1023, ring spacing in 6-chunk units), count (1–4095 total placements), spread (0–1023, placements on the nearest ring), preferred_biomes (biome ids / #tags).
data/example/worldgen/structure_set/towers.json
{
"structures": [
{ "structure": "example:tall_tower", "weight": 3 },
{ "structure": "example:short_tower", "weight": 1 }
],
"placement": {
"type": "minecraft:random_spread",
"salt": 84920155,
"spacing": 34,
"separation": 8,
"spread_type": "linear",
"frequency": 0.6,
"exclusion_zone": { "other_set": "minecraft:villages", "chunk_count": 8 }
}
}
- Structure sets were introduced with the 1.18 worldgen rewrite; the schema is stable through 1.21.8.
- Give every custom set a unique large
saltβ reused salts make different structures land on identical chunks. - Lower
spacing/separation= denser; always keepseparation < spacingor generation errors. exclusion_zoneis how vanilla keeps pillager outposts away from villages./locate structure <id>searches by structure definition, independent of the set.
Template pool
A template pool at data/<namespace>/worldgen/template_pool/ is "a loot table for builds." A jigsaw's start_pool and each jigsaw block's Target Pool point at one of these. It weights the candidate pieces and supplies a fallback.
| Field | Notes |
|---|---|
fallback | Another pool id used when elements can't fit or size is exhausted (an end-cap); minecraft:empty if none. |
elements[] | Each { "weight": <int 1–150>, "element": { ... } }. |
name | Optional β ignored on load; the file path is the id. |
element_type (inside each element):
| Type | Fields |
|---|---|
single_pool_element | location (NBT id), processors (list id/inline), projection, optional override_liquid_settings. |
legacy_single_pool_element | As single; legacy structure-block block handling. |
list_pool_element | elements[] (list of pool elements placed together), projection. |
feature_pool_element | feature (placed feature id/inline), projection. |
empty_pool_element | (nothing to place) β terminator. |
projection: rigid (piece stays flat, ignores terrain β houses, start piece) or terrain_matching (each column drops to follow terrain β village roads).
data/example/worldgen/template_pool/tall_tower.json
{
"name": "example:tall_tower",
"fallback": "minecraft:empty",
"elements": [
{ "weight": 3, "element": {
"element_type": "minecraft:single_pool_element",
"location": "example:tower/body",
"processors": "example:mossify",
"projection": "rigid" } },
{ "weight": 1, "element": {
"element_type": "minecraft:single_pool_element",
"location": "example:tower/body_ruined",
"processors": "minecraft:empty",
"projection": "rigid" } }
]
}
list_pool_element,legacy_single_pool_element, andoverride_liquid_settingsare Java-only; the schema is stable across 1.19 → 1.21.8.
Provide a small fallback pool (a blank wall / cap) so truncated jigsaw chains don't look sheared off. Use terrain_matching only for pieces meant to melt into the ground (roads); everything else rigid, especially the start piece.
Processor list
A processor list at data/<namespace>/worldgen/processor_list/ is an ordered set of block transformations applied as a template piece is stamped into the world (weathering, block swaps, gravity settling, loot injection). Pool elements reference it via processors. The root is a processors array-holder object:
worldgen/processor_list β root schema shape
{ "processors": [ { "processor_type": "minecraft:block_ignore", "blocks": [ { "Name": "minecraft:structure_void" } ] } ] }
Processor types
processor_type | Fields |
|---|---|
block_ignore | blocks[] (block states to skip placing). |
block_rot | integrity (0–1 keep-fraction), optional rottable_blocks (block list). |
gravity | heightmap, offset (int) β settle each column to a heightmap. |
jigsaw_replacement | none β convert leftover jigsaw blocks to air. |
rule | rules[] (see below). |
block_age | mossiness (float) β random weathering / cobweb / cracks. |
blackstone_replace | none β swap cobblestone-family → blackstone-family. |
lava_submerged_block | none β waterlogged / air-in-lava handling. |
protected_blocks | value (block #tag that must never be overwritten). |
capped | delegate (a processor), limit (int provider β max applications). |
nop | none. |
Rules & rule tests
Each entry in a rule processor's rules[]: input_predicate tests the block in the template; location_predicate tests the block already in the world at that spot; if both pass, output_state is written.
rule β one entry
{
"input_predicate": { "predicate_type": "minecraft:always_true" },
"location_predicate": { "predicate_type": "minecraft:block_match", "block": "minecraft:red_sand" },
"position_predicate": { "predicate_type": "minecraft:always_true" },
"output_state": { "Name": "minecraft:red_sandstone" },
"block_entity_modifier": { "type": "minecraft:passthrough" }
}
Rule tests (predicate_type β shared with ore targets):
| Predicate type | Fields |
|---|---|
always_true | β |
block_match | block |
blockstate_match | block_state |
tag_match | tag (no leading #) |
random_block_match | block, probability |
random_blockstate_match | block_state, probability |
Position predicates (the optional position_predicate): always_true, linear_pos (min_chance, max_chance, min_dist, max_dist), axis_aligned_linear_pos (adds axis).
block_entity_modifier types: clear, passthrough (keep existing NBT), append_static (data compound merged in), append_loot (loot_table β sets a LootTable so the container fills on first open).
data/example/worldgen/processor_list/mossify.json
{
"processors": [
{ "processor_type": "minecraft:block_age", "mossiness": 0.2 },
{ "processor_type": "minecraft:rule",
"rules": [
{ "input_predicate": { "predicate_type": "minecraft:block_match", "block": "minecraft:sand" },
"location_predicate": { "predicate_type": "minecraft:block_match", "block": "minecraft:red_sand" },
"output_state": { "Name": "minecraft:red_sand" } }
] }
]
}
block_rot,block_age,gravity,blackstone_replace,lava_submerged_block, andnopare Java-only; the set is stable across 1.18 → 1.21.8.capped(delegate +limitint provider) andprotected_blocksare present in 1.21.
append_lootin a rule'sblock_entity_modifieris how structures ship unfilled chests.protected_blockswith a custom tag prevents a processor or terrain from overwriting hand-placed key blocks.- Wrap a heavy processor in
cappedto bound how many blocks it touches per piece.
Structure NBT & jigsaw workflow
Keep the two "structure" things straight:
data/<namespace>/structure/<name>.nbtβ the build saved by a Structure Block (blocks + optional entities).data/<namespace>/worldgen/structure/<name>.jsonβ the definition (above) that decides biomes, step, and spawns. A template pool element'slocationpoints at the.nbtbuild.
Structure Block workflow
/give @s structure_block. The placed block defaults to Load mode; click Load twice to reach Save mode.- Set a Structure Name (
namespace:path, lowercase / no spaces), a Relative Position (e.g.1 0 1), and a Structure Size (max 48×48×48; extends in +X/+Y/+Z). - Toggle Include Entities if display entities / mobs are inside (they must sit ≥ 0.01 blocks inside the box or they're dropped). Redstone state is not saved.
- Press SAVE β the file is written under the world's
generated/<namespace>/structure(s)/. Merge it into the data pack. - Use Structure Void (
/give @s structure_void) at the build's edges so natural terrain / foliage shows through instead of air. (Build with sponge as a placeholder, swap to voids last β voids have a tiny hitbox.)
Jigsaw blocks
/give @s jigsaw. Directional; the sideways interface shows:
| Field | Meaning |
|---|---|
| Target Pool | Template pool this jigsaw may spawn from (minecraft:empty if it's only a connector). |
| Name | This jigsaw's own name (what a parent's Target Name matches). |
| Target Name | The Name of the jigsaw in the child piece it should line up with. |
Turns Into (final_state) | Block that replaces the jigsaw after generation (usually minecraft:air; accepts blockstates). |
| Joint Type (up/down only) | rollable (random rotation allowed) or aligned (fixed to the indicator line). |
| Selection / Placement Priority 1.20.4+ | Higher = generated first, so key children claim space before others. |
Convention: pair a parent and child by swapping Name ↔ Target Name and namespacing both.
Single-piece structure recipe: a .nbt build (with one downward or heightmap-facing jigsaw, Target Pool minecraft:empty) → a one-element template_pool (single_pool_element, location = the .nbt, projection: rigid) → a structure definition with size: 1 pointing start_pool at that pool → a structure_set with a random_spread placement. Done.
- Structure Block max is 48³; larger builds must be split across jigsaw-connected pieces.
- A jigsaw child's bounding box cannot intersect any previously placed piece's box β put jigsaws at the very edge facing out, or keep an internally-spawned child small enough to fit.
- Max horizontal reach from the start center is 128 blocks (also bounded by
max_distance_from_centerand terrain adaptation). - Max jigsaw steps = 20 (7 in ≤ 1.20.2); villages use ~6. Deep branching hurts chunk-load performance. Everything inherits the start piece's random rotation.
- Since 1.21: the build folder is singular
structure/. Structure Blocks in ≤ 1.20 saved tostructures/, so rename after exporting a pre-1.21 build. - Since 1.20.4: jigsaw blocks expose Selection / Placement Priority.
The /place command
Used for testing structure generation without waiting for natural spawns.
/place β the four subcommands
/place feature <configured_feature_id> [<pos>]
/place structure <structure_id> [<pos>]
/place jigsaw <start_pool> <target_jigsaw_name> <max_depth> [<pos>]
/place template <template_id> [<pos>] [<rotation>] [<mirror>] [<integrity>] [<seed>] [strict]
place featuretakes a configured feature id (placement modifiers are ignored).place structureruns the full structure definition (spawn overrides, terrain adaptation).place jigsawexpands a pool tomax_depthsteps from a named jigsaw.place templatestamps a raw.nbtbuild:rotation∈none/clockwise_90/counterclockwise_90/180,mirror∈none/front_back/left_right,integrity0–1.
Prototype spawning with /place structure and /locate structure before relying on natural generation. Keep a tiny fallback / end-cap piece in every pool so truncated chains look intentional, and store rotation-sensitive logic behind an anchor block/entity so mechanics survive the random rotation.
Sources
- Jigsaw structure β Minecraft Wiki
- Structure set β Minecraft Wiki
- Template pool β Minecraft Wiki
- Processor list β Minecraft Wiki
- Tutorial: Custom structures β Minecraft Wiki
- /place command β Minecraft Wiki
- Data pack version β Minecraft Wiki
- PMC "Custom Structure Generation Documentation" (kanokarob / Datapack Hub)