W-10 — material diversity: presentation-only soil split + slope outcrops
Part of the "hex diorama" program. Integration branch: render-r12-terragen-preview — branch
off it (W-9 just merged into it — you build ON TOP of the talus pass), PR back into it with
explicit --base render-r12-terragen-preview (GOTCHAS: gh defaults to main).
Lane: worldgen (v2/crates/world/** only).
Goal (user ask: "почвы различного состава")
The 512 all-ON map must show ≥7 visually distinct BARE materials with spatially coherent patches:
bedrock, sand, till, basalt, tuff, permafrost + the NEW soil variants below.
HARD CONSTRAINT — presentation-only (17-round consensus decision, do not violate)
MaterialId inside classify remains the SIM SUBSTRATE. The biome cascade (override_biome,
incl. the Fertile branch) and caps_from/material_mult read the UNCHANGED substrate. Touching
the substrate silently rewrites caps/O2/NO3 ecology (Fertile dies for renamed cells; Bedrock
(0,1) collapses caps on steep-wet cells). The split lives ONLY in the presentation byte that
WorldView::surface_material returns.
Mechanism
A pure POST-classify pass that rewrites ONLY the surface_material byte in WorldFields, from
(substrate, moisture, slope) — all three already computed inside classify_and_caps:
- (a) Soil -> {SoilDry (new u8 discriminant 9), Soil, SoilWet (10)} keyed on the ALREADY-COMPUTED
per-cell moisture at thresholds picked from a MEASURED moisture histogram @512 (Phase-0 below).
Thresholds land as named consts.
- (b) Exposed rock/outcrop: where slope (height drop to D8 receiver, already computed in classify)
= OUTCROP_SLOPE_THRESHOLD and the presentation byte would be Soil*, presentation byte =
Bedrock. Landform-primary bytes (Basalt/Tuff/Till/Sand/Water) KEEP priority — never overwritten.
- Gated by the SAME any-landform-ON gate (OFF path byte-identical).
- Determinism: integer-only (no_float_guard), fixed iteration order, no hashing containers.
Phase-0 (measure FIRST, local run authorized — pure worldgen, <1 min)
On the POST-W-9 field (the staged seam classify_and_caps_staged exists — use it), @512, seeds
1 and 2: moisture histogram (deciles) over Soil-substrate cells; slope histogram over Soil cells;
pick (a) thresholds so the three soil classes each form visible, coherent regions (report the
class shares — they inform, they don't gate) and (b) the outcrop threshold from the slope tail.
Numbers table goes in the PR body; thresholds are pinned FROM it.
Tests (in-suite)
- ON-path INVARIANCE: biome, caps, resource arrays byte-identical pre/post the W-10 pass
(the pass may only change surface_material) — @dim=64 and @dim=256 landform-ON fixtures.
- OFF-path byte-identity (whole WorldFields).
- Presentation-byte sanity: every cell's byte is a valid discriminant; landform-primary cells
unchanged by the pass (targeted asserts on till/basalt cells).
- Patch coherence smoke: on the 256 fixture, SoilDry/SoilWet each form at least one 4-connected
patch of >= 8 cells (no salt-and-pepper) — thresholds from Phase-0 make this achievable; if
not, re-pick thresholds, do NOT relax the test.
- Existing goldens: conserved + w2/w5 must stay byte-identical (they hash biome/caps/materials on
the OFF path). If any landform-ON golden vector hashes surface_material and moves — two-pass
re-pin via CI, report honestly.
Acceptance
- @512 all-ON, 2 seeds: >=7 distinct presentation materials PRESENT with coherent patches (patch
count / mean size reported); NO share-floor KPI; NO tuning of vents/ELA/landform physics to
manufacture coverage (anti-forcing — physical knobs are not render KPIs).
- Screenshot evidence: use the render harness (
--standalone --dim 512 --seed 1 --screenshot,
material color mode) BEFORE vs AFTER — attach to PR. VERIFY every PNG by opening it with the
Read tool before claiming anything (GOTCHAS).
- ON-path invariance + OFF-path identity tests land and pass LOCALLY (run them via
./scripts/test-bar.sh targeted and QUOTE the passing output — a compile-check is not a test
run; two CI round-trips were burned on this mistake in W-9).
- compile-check PASS (quoted, from v2/) -> push ->
bash scripts/ci-report.sh green (or honest
two-pass re-pin if a material-hashing vector moves).
- code-critic self-review on the diff vs THIS issue; verdict block as PR comment.
Out of scope
- WorldView trait changes; render palette work (that is R-14); substrate/caps/biome changes of
any kind; new landform knobs.
Process
Branch w10-material-diversity off origin/render-r12-terragen-preview. STATUS-line contract;
status.md last. Do not poll CI in a loop — one ci-report.sh call per pass.
W-10 — material diversity: presentation-only soil split + slope outcrops
Part of the "hex diorama" program. Integration branch:
render-r12-terragen-preview— branchoff it (W-9 just merged into it — you build ON TOP of the talus pass), PR back into it with
explicit
--base render-r12-terragen-preview(GOTCHAS: gh defaults to main).Lane: worldgen (
v2/crates/world/**only).Goal (user ask: "почвы различного состава")
The 512 all-ON map must show ≥7 visually distinct BARE materials with spatially coherent patches:
bedrock, sand, till, basalt, tuff, permafrost + the NEW soil variants below.
HARD CONSTRAINT — presentation-only (17-round consensus decision, do not violate)
MaterialIdinside classify remains the SIM SUBSTRATE. The biome cascade (override_biome,incl. the Fertile branch) and
caps_from/material_multread the UNCHANGED substrate. Touchingthe substrate silently rewrites caps/O2/NO3 ecology (Fertile dies for renamed cells; Bedrock
(0,1) collapses caps on steep-wet cells). The split lives ONLY in the presentation byte that
WorldView::surface_materialreturns.Mechanism
A pure POST-classify pass that rewrites ONLY the
surface_materialbyte in WorldFields, from(substrate, moisture, slope) — all three already computed inside classify_and_caps:
per-cell moisture at thresholds picked from a MEASURED moisture histogram @512 (Phase-0 below).
Thresholds land as named consts.
Phase-0 (measure FIRST, local run authorized — pure worldgen, <1 min)
On the POST-W-9 field (the staged seam
classify_and_caps_stagedexists — use it), @512, seeds1 and 2: moisture histogram (deciles) over Soil-substrate cells; slope histogram over Soil cells;
pick (a) thresholds so the three soil classes each form visible, coherent regions (report the
class shares — they inform, they don't gate) and (b) the outcrop threshold from the slope tail.
Numbers table goes in the PR body; thresholds are pinned FROM it.
Tests (in-suite)
(the pass may only change surface_material) — @dim=64 and @dim=256 landform-ON fixtures.
unchanged by the pass (targeted asserts on till/basalt cells).
patch of >= 8 cells (no salt-and-pepper) — thresholds from Phase-0 make this achievable; if
not, re-pick thresholds, do NOT relax the test.
the OFF path). If any landform-ON golden vector hashes surface_material and moves — two-pass
re-pin via CI, report honestly.
Acceptance
count / mean size reported); NO share-floor KPI; NO tuning of vents/ELA/landform physics to
manufacture coverage (anti-forcing — physical knobs are not render KPIs).
--standalone --dim 512 --seed 1 --screenshot,material color mode) BEFORE vs AFTER — attach to PR. VERIFY every PNG by opening it with the
Read tool before claiming anything (GOTCHAS).
./scripts/test-bar.shtargeted and QUOTE the passing output — a compile-check is not a testrun; two CI round-trips were burned on this mistake in W-9).
bash scripts/ci-report.shgreen (or honesttwo-pass re-pin if a material-hashing vector moves).
Out of scope
any kind; new landform knobs.
Process
Branch
w10-material-diversityoff origin/render-r12-terragen-preview. STATUS-line contract;status.md last. Do not poll CI in a loop — one ci-report.sh call per pass.