Layers and Progression Pacing
Depth is how Underroot gates content. The underground is a stack of bands, each one a main material with a small chance of rarer ores mixed in, and how deep the player has to dig sets what they can make. Time paces the rest: the length of a day decides how much escalation the player buys with every dig. The bands live in layers.json; the day length is balance.json → time → day_duration. DataRegistry reads the bands at startup, and LayerGenerator uses them to decide what material fills each undug tile.
In plain terms: depth is progression
The surface is depth 0. Digging goes downward into positive depth, counted in tiles (one tile is 32 px). As the digger descends, the ground shifts from dirt to clay to stone and on down to quartz. Each band is defined by a depth_start and depth_end (inclusive, in tiles), a main_material filling most of it, and an optional ore_inclusions list of rarer materials scattered through it.
Tools, recipes, and defensive walls all depend on which materials the player can reach, which makes the depth table the main progression gate. Push a material deeper and it becomes a later-game resource; pull it shallower and the player gets it sooner. Recipes unlock once the player has seen all their input materials, so where a material first appears sets when its whole downstream tech opens up.
Between bands sits a blend zone. Near the bottom of a band, tiles start mixing in the next band's material with rising probability, so the boundary feels gradual instead of a hard line. That's the blend_depth field — the number of tiles at the bottom of the band where blending happens. It's a feel knob, not a progression gate.
The depth bands (top to bottom)
Depths are in tiles. "Ore inclusions" lists each scattered material with its
per-tile chance (a chance of 0.09 means roughly 9% of that band's tiles).
| Band (display name) | Depth start–end | Main material | Ore inclusions (chance) |
|---|---|---|---|
| Surface / Roots | 0 – 2 | dirt |
none |
| Dirt | 3 – 12 | dirt |
none |
| Clay | 13 – 26 | clay |
ancient_clay (0.004) |
| Stone | 27 – 51 | stone |
coal (0.09) |
| Shale / Coal | 52 – 76 | coal |
sulfur (0.03) |
| Iron-Rich Rock | 77 – 112 | iron_ore |
coal (0.10) |
| Dense Stone | 113 – 140 | dense_stone |
prismatic_shard (0.003) |
| Copper-Tin Ore | 141 – 200 | dense_stone |
tin_ore (0.40), copper_ore (0.40), prismatic_shard (0.003) |
| Limestone | 201 – 232 | limestone |
sulfur (0.03), ancient_clay (0.004) |
| Deep Coal | 233 – 262 | deep_coal |
ember_essence (0.001) |
| Quartz | 263 – 342 | quartz |
dense_stone (0.20), void_iron (0.004), ember_essence (0.002) |
A few things to read from this table when tuning:
- First appearance = unlock gate.
coalfirst shows up as an inclusion in the Stone band (depth 27+) before becoming the main material of Shale/Coal at 52.iron_oregates behind depth 77.limestone(key to cement and steel) waits until 201. Move a band'sdepth_startand you move when that whole material tier enters the run. - Inclusion chance sets how "rich" a band feels. The Copper-Tin band is deliberately dense (0.40 tin and 0.40 copper) so it reads as an ore field; the exotic shards and essences sit at fractions of a percent so they stay rare finds. A chance list is rolled in order, so the listed chances are consumed cumulatively per tile.
- Band width sets how long a phase lasts. Wide bands (Copper-Tin is 60 tiles, Quartz 80) are long grinds; narrow ones (Deep Coal is 30) are quick transitions. Widen or narrow a band by editing its start/end to stretch or compress that stage of the run.
- Quartz is the floor. The deepest defined band ends at 342. Ground below the last band has no material and generates as empty, so this is effectively the bottom of the world.
The fields on each band
| Field | What it controls |
|---|---|
depth_start / depth_end |
The inclusive tile range the band occupies. This is the progression gate — it decides at what depth a material appears. |
main_material |
The material that fills most tiles in the band. Two bands may share a main material (Copper-Tin reuses dense_stone) and differ only by their inclusions. |
ore_inclusions |
Optional list of {material, chance} scattered through the band. Chance is per tile, rolled cumulatively. Controls how rich and how surprising a band feels. |
blend_depth |
How many tiles at the bottom of the band gradually mix in the next band's material, softening the boundary. A feel knob, not a gate. Set to 0 for a hard edge (Quartz uses 0). |
color_hex, display_name, description |
Presentation only — the band's tint, name, and flavor text. No gameplay effect. |
Pacing in time: day duration
| Setting | Where it lives | Default | What it controls | Turn it up / down |
|---|---|---|---|---|
day_duration |
balance.json → time |
360.0 |
The length of one in-game day in real seconds (6 minutes). This is the master time unit the whole game paces off. | Higher = everything time-based slows down. Lower = the whole run compresses. High-impact — see below. |
day_duration isn't just the day/night cosmetic. It's the denominator for most
time-based systems, so changing it re-times the entire game at once:
- The Maw's
grace_period(360 s) equals exactly one day at the default, and itspressure_growth_per_dayis measured in these days — a longer day means slower escalation. - The survival drains are per-second, so a longer day means more real seconds of drain per day (players eat and drink more per "day").
- Villager daily ticks, light-surge cadence (
light_surge_mean_days), and every "per day" village rate all stretch with it.
So much reads off day_duration that you should treat it as a global pacing dial, not a local tweak. Change it and re-check the Maw and survival feel afterward.
The shape of the curve
Read together, the depth table and the day length draw the run's difficulty curve:
- Early game (depth 0–26, dirt and clay): shallow, fast to dig, no pickaxe
needed until stone. This is where
grace_periodprotects the player while they learn — depth and time both stay gentle. - Mid game (depth 27–140, stone through dense stone): pickaxes required, coal and iron unlock the first real crafting tiers, and progress starts to slow at Dense Stone by design. Meanwhile time pressure has begun compounding.
- Late game (depth 141–342, copper-tin to quartz): long, rich ore bands and the toughest ground, reachable only with the best tools — while the Maw's pressure multiplier is well above 1.0. Depth difficulty and time difficulty peak together.
Two coarse dials shift the overall pace: the band depths in layers.json (how far the player must dig to reach each tier) and day_duration in balance.json (how much real time each day of escalation costs). Material toughness (terrain_hp, base_chew_resistance) and tool power fine-tune within that frame and are tuned on their own pages.
Safe to change / handle with care
- A band's
depth_start— this is a hard progression gate. Pulling a material likelimestonefar shallower can unlock late-game recipes before the player is meant to have them; pushing a key fuel likecoaldeeper can stall the early game with nothing to burn. - Inclusion
chancevalues — the tiny exotic chances (0.001–0.004) are deliberately rare. Raising them a little multiplies late-game exotic supply a lot. The 0.40 copper/tin chances are what make that band a proper ore field; drop them and mid-game metal supply dries up. day_duration(360.0) — a global multiplier on nearly every time-based system. Change it and re-verify Maw escalation and survival drain together, not in isolation.- Leave no gaps or overlaps in the depth ranges — a tile at a depth no band
covers generates empty. Keep each band's
depth_startexactly one past the previousdepth_end.