Worldgen technique, measured
Everything else here documents what the game accepts. This page documents what authors actually do: measured across 90 published packs spanning 21 distinct pack_format values, from the 1.17 era through 26.2.
The corpus
90 pack archives were read in place, never extracted. 46 carry a data/ tree; the rest are resource packs shipped alongside them. Between them they use 99 distinct feature types across 9,936 uses, 15 placement modifiers across 5,820 uses, and 4 structure processors across 628 uses.
Only type strings, counts and orderings were recorded. No block palette, name, description or coordinate from any pack appears here or in the survey data — those belong to their authors. What is published is a fact about the ecosystem, not anyone's authored work.
The pack_format span is what makes the corpus useful: 13, 15, 18, 22, 26, 34, 38, 46, 48, 55, 61, 64, 69, 71, 81, 84, 88, 89, 94, 101, 107. That crosses the format 48 folder rename in both directions, so a technique visible at both ends is not an artefact of one era.
Placement order is the technique
A placed_feature's placement list is not a set of options. It is a pipeline: each modifier receives the positions the previous one emitted, and may multiply them, move them or discard them. The same modifiers in a different order describe a different pack.
count -> height_range -> in_square -> biome appears 157 times and count -> in_square -> height_range -> biome 126 times. Both are widespread, and they are not interchangeable: whether the vertical range is chosen before or after the horizontal scatter changes which positions survive the later filters. If you copy a stack from another pack, copy its order too.
One ordering rule is near-universal in the corpus: biome appears 1,167 times and is almost always last. It rejects positions whose biome does not list the feature, so running it after the cheap multiplying modifiers wastes the least work — and running it first would filter a single position before the pack had scattered it.
| Placement modifier | Uses | What it does to the position stream |
|---|---|---|
count | 929 | multiplies — N copies per chunk |
in_square | 892 | moves — scatters horizontally within the chunk |
height_range | 559 | moves — picks a Y from a provider |
heightmap | 474 | moves — snaps Y to a surface |
biome | 1,167 | filters — drops positions whose biome does not list it |
block_predicate_filter | 493 | filters — tests the block at the position |
rarity_filter | 450 | filters — keeps 1 in N at random |
random_offset | 349 | moves — jitters the position |
count_on_every_layer | 231 | multiplies — once per exposed layer |
The stacks authors actually write
177 distinct orderings appear across the corpus, but the head of the distribution is short: a handful of shapes cover most placed features. These are worth learning as idioms.
| Placement stack | Times used |
|---|---|
count -> height_range -> in_square -> biome | 157 |
count -> in_square -> height_range -> biome | 126 |
block_predicate_filter | 106 |
count -> in_square -> heightmap -> biome | 55 |
rarity_filter -> in_square -> height_range -> biome | 52 |
rarity_filter -> in_square -> heightmap -> biome | 48 |
count_on_every_layer -> block_predicate_filter -> biome | 42 |
count_on_every_layer -> rarity_filter -> biome | 41 |
count -> rarity_filter -> in_square -> heightmap -> biome | 41 |
random_offset | 40 |
count_on_every_layer -> biome | 30 |
count | 27 |
count -> rarity_filter -> in_square -> height_range -> biome | 21 |
rarity_filter -> height_range -> in_square -> biome | 20 |
Feature nesting
Features compose by embedding: a selector holds features, which may themselves be selectors. 25 of the 46 data packs nest at all, and the deepest reaches 8 levels of embedding. That is the mechanism behind a single placed feature producing a whole varied thicket rather than one object.
| Feature type | Uses |
|---|---|
simple_state_provider | 1,951 |
uniform | 938 |
matching_blocks | 750 |
weighted_state_provider | 592 |
matching_block_tag | 579 |
all_of | 360 |
block_predicate_filter | 342 |
simple_block | 304 |
tree | 253 |
two_layers_feature_size | 232 |
vegetation_patch | 212 |
rule_based_state_provider | 208 |
matching_block_tag | 203 |
ore | 188 |
Processor chains
Structure processors are applied in order to a template's blocks. The corpus uses only 4 distinct processor types, and one of them dominates: rule accounts for 571 of 628 uses.
| Processor chain | Times used |
|---|---|
rule | 155 |
rule -> rule | 115 |
rule -> rule -> rule | 28 |
rule -> gravity | 16 |
gravity | 11 |
rule -> rule -> rule -> rule | 9 |
rule -> rule -> rule -> rule -> rule | 6 |
rule -> capped | 4 |
The long rule chains are the interesting part. Rather than one processor holding many rules, authors run several rule processors in sequence, because each one sees the output of the last — a block rewritten by the first can be matched again by the second. That is sequencing used deliberately, and it is the same insight as the placement pipeline.
Template pools
| Pool element type | Uses |
|---|---|
single_pool_element | 6,340 |
list_pool_element | 4,634 |
empty_pool_element | 267 |
feature_pool_element | 113 |
legacy_single_pool_element | 35 |
list_pool_element is used 4,634 times against 6,340 for single_pool_element. A list element applies several templates at one jigsaw slot, in order, so authors are layering pieces on a single anchor rather than authoring every combination as its own template.
What survives publication
18 worldgen files across 3 published pack archives have the wrong top-level JSON shape — a list where the game expects an object. The game rejects such a file quietly and carries on, so nothing visibly breaks at load time and the defect ships. The affected archives are successive released versions of the same pack, so it was carried forward across releases without being noticed.
This is the general shape of the danger in data packs: an error that fails loudly gets fixed before release, and an error that fails silently does not. Validate rather than trusting that a pack which loads is a pack that works.
Sources
- Measured by
tools/pack_survey.pyover a local corpus of 90 published pack archives, read in place. Aggregates only; no pack content is reproduced. - Survey manifest:
data/pack_survey.json. Every number on this page is re-derived from it byclaimcheck.py(C8). - Schema and semantics of the types named here: Features, Structures and Worldgen core.