W-SIM-7 coastal (1/n): sea-level datum + cliff / wave-cut platform
Lane: B · Base branch: worldgen-relief (NOT main) · Labels: agent:B, golden-touch
Context
Fifth and LAST landform of the worldgen-relief diverse-relief roadmap (tectonic → aeolian → volcanic →
glacial → coastal). Grounding: pm/reports/w-sim-coastal-grounding.md (RnD sim/world/17, coastal
half; the tectonic half already shipped as W-SIM-4a).
The generator today has no ocean — no sea_level, no coastline, no water; MaterialId::Air is used
as zero-resistance "empty", biomes are all terrestrial, the map is 100 % land. The four prior landforms
each deformed the existing height/resistance fields; coastal is different — RnD 17 operates "on
sea-level", so the coastline is an integer threshold of height vs a sea_level datum that does not yet
exist. This slice therefore introduces a sea_level datum (the first water in the world) as its
enabling primitive, then carves the anchor coastal form.
The world-gen pipeline (v2/crates/world/src/gen/caps.rs::classify_and_caps) runs, on
worldgen-relief HEAD, erode → glacial → aeolian → classify (tectonics and volcanic are folded INSIDE
erode/erode_with_tectonics pre-erosion; glacial is merged as W-SIM-6 #418 and runs post-erosion,
pre-aeolian). Per RnD 17 §1 the coastal pass belongs after the aeolian (depositional) pass and before
the final classify loop — it consumes the post-aeolian height and produces a post-coastal height (+ an
explicit submerged/coastal signal) fed into the existing classify. The four prior landforms are each an
opt-in enable_<x> bool defaulting OFF, orthogonal, so acceptance corridors stay byte-identical when
off; this slice follows that exact contract with a new enable_coastal flag.
Two known integration hazards the coder must resolve (not optional):
- No Water material exists.
MaterialId (material.rs) is Air/Sand/Permafrost/Soil/Bedrock/Basalt/
Tuff/Till; Air is already the "above-surface empty" sentinel (cap 0, resource floor 1). Submerged
cells therefore CANNOT be represented by reusing Air — that is byte-indistinguishable from sky and
from barren land, and the coastline band could not be recovered. The submerged set must be an
UNAMBIGUOUS signal (a new appended Water MaterialId, or a separate submerged-mask field on
WorldFields) — coder's choice, but it must be distinguishable.
- Classify currently assumes all land. The classify loop runs
climate_from_height/biome_at on
every cell → a submerged cell would get a terrestrial biome. Classify must gain a submerged branch so
below-sea cells do not read as land biomes.
Goal
Add a deterministic coastal pass, opt-in and default-OFF (enable_coastal), that:
- establishes a
sea_level datum so terrain below it reads as submerged (the world's first water), and
- carves the anchor coastal form along the coastline: a cliff (wave-undercut retreat) and its
wave-cut platform (near-flat seaward bench), the retreat gated by wave exposure and rock
resistance.
When OFF, the world is byte-identical to the current worldgen-relief HEAD.
Acceptance criteria (observable, cloud-CI checkable)
- OFF ⇒ byte-identical. With
enable_coastal=false, every existing acceptance corridor and every
existing determinism golden is unchanged (no sea datum applied, no coastal RNG draw, no reorder).
- Sea datum + coastline. With
enable_coastal=true, a sea_level datum exists; cells with height
below it read as submerged via the unambiguous submerged signal (new Water material or mask field —
NOT reused Air); a coastline band (cells adjacent to the land↔sea integer threshold) is
identifiable; submerged cells do NOT classify as a terrestrial biome. The sea_level datum is
derived from the height distribution (e.g. a fixed percentile of the post-aeolian heights),
quantize-before-compare — NOT a bare constant — so that across a spread of seeds (≥3) the submerged
fraction is bounded away from both 0 % and 100 % (a representative window, not a knife-edge). A bare
constant that degenerates to all-land or all-sea on some seed fails this criterion.
- Cliff is a sharp feature the baseline cannot make. Count coastline-band cells whose seaward slope
exceeds a threshold ABOVE what fBm + erosion produces (escarpment-grade, per the W-SIM-4a
relief-verification precedent): baseline (coastal OFF) ≈ 0 such cells, coastal ON clearly exceeds.
Anti-forcing-clean — verify the sharp coastal feature, not bulk roughness, and do not crank magnitude
to force it.
- Wave-cut platform is a near-flat bench. Platform cells seaward of the cliff foot form a low-slope
bench (bounded, shallow seaward gradient), and platform width correlates positively with wave exposure
(higher exposure ⇒ wider platform). (The full self-limiting wave-damping feedback is NOT required in
this slice — only the observable flat bench + exposure-width correlation.)
- Resistance gates retreat. Higher rock resistance ⇒ slower retreat (shallower cliff inset) at equal
exposure; lower resistance ⇒ deeper inset. Demonstrable as a monotone relation on controlled inputs.
- Determinism. A seed-divergence test (different seeds ⇒ different coastal result) plus at least one
pinned integer golden for the ON path (two-pass CI: placeholder → CI-revealed value → pin; arm64 and
x86 agree). The whole pass is pure-integer — world/tests/no_float_guard_gen.rs passes. Any
along-profile / distance-from-coast computation (retreat depth, platform width) MUST be
traversal-order-independent (e.g. a seaward distance-transform / BFS to a fixed point, quantized) —
a row-major or scan-order relaxation is a determinism hazard on a golden-touch slice and is
disallowed. (The canonical closed-loop coastline-ordering primitive is deferred to 7b and must NOT be
pulled forward; an order-free distance field keeps this slice self-contained.)
Out of scope (explicit — these are follow-up sub-slices, do NOT build them here)
- Longshore deposition (beach / spit / bar / baymouth-bar+lagoon / tombolo / barrier island / cuspate
foreland) and its canonical coastline-ordering primitive (closed-loop cut + fixed traversal sign)
→ W-SIM-7b.
- Headland–bay wave refraction (exposure boost on convex coast) → W-SIM-7c.
- Sea-level-change forms (raised beach / marine terraces / ria) → W-SIM-7d.
- Sea caves / arches (TRUE-3D overhang/void) → RnD dive 18 (caves) = next version, out of this roadmap.
- Biome/vegetation/render changes — the roadmap is relief-only, numeric verification only.
Verification
Cloud CI (scripts/ci-report.sh, exit 0 = green): the v2 jobs — v2-sim-x86 (invariants + the new
coastal ON-path corridor asserting AC 2–5) and v2-golden-arm64 (the pinned ON-path golden, AC 6). The
default-OFF byte-identical guarantee (AC 1) is carried by the existing corridors + goldens staying green
with the flag threaded but off. Two-pass for the golden (pass 1 = code + placeholder [0,0,0,0] + PR;
pass 2 = pin the CI-revealed value). Pre-push: cd v2 && bash ../scripts/compile-check.sh must print
PASS before any "compiles" claim.
Depends-on
None new. Reuses erosion::resistance_field / resistance_class_at (rock resistance, integer classes),
sim-core::rng::seed_fold (counter-based keyed RNG), and the integer-threshold / quantize-before-compare
pattern the glacial ELA gate established. Grounding doc: pm/reports/w-sim-coastal-grounding.md.
W-SIM-7 coastal (1/n): sea-level datum + cliff / wave-cut platform
Lane: B · Base branch:
worldgen-relief(NOT main) · Labels:agent:B,golden-touchContext
Fifth and LAST landform of the
worldgen-reliefdiverse-relief roadmap (tectonic → aeolian → volcanic →glacial → coastal). Grounding:
pm/reports/w-sim-coastal-grounding.md(RnDsim/world/17, coastalhalf; the tectonic half already shipped as W-SIM-4a).
The generator today has no ocean — no
sea_level, no coastline, no water;MaterialId::Airis usedas zero-resistance "empty", biomes are all terrestrial, the map is 100 % land. The four prior landforms
each deformed the existing height/resistance fields; coastal is different — RnD 17 operates "on
sea-level", so the coastline is an integer threshold of
heightvs asea_leveldatum that does not yetexist. This slice therefore introduces a
sea_leveldatum (the first water in the world) as itsenabling primitive, then carves the anchor coastal form.
The world-gen pipeline (
v2/crates/world/src/gen/caps.rs::classify_and_caps) runs, onworldgen-reliefHEAD,erode → glacial → aeolian → classify(tectonics and volcanic are folded INSIDEerode/erode_with_tectonicspre-erosion; glacial is merged as W-SIM-6 #418 and runs post-erosion,pre-aeolian). Per RnD 17 §1 the coastal pass belongs after the aeolian (depositional) pass and before
the final classify loop — it consumes the post-aeolian height and produces a post-coastal height (+ an
explicit submerged/coastal signal) fed into the existing classify. The four prior landforms are each an
opt-in
enable_<x>bool defaulting OFF, orthogonal, so acceptance corridors stay byte-identical whenoff; this slice follows that exact contract with a new
enable_coastalflag.Two known integration hazards the coder must resolve (not optional):
MaterialId(material.rs) is Air/Sand/Permafrost/Soil/Bedrock/Basalt/Tuff/Till;
Airis already the "above-surface empty" sentinel (cap 0, resource floor 1). Submergedcells therefore CANNOT be represented by reusing
Air— that is byte-indistinguishable from sky andfrom barren land, and the coastline band could not be recovered. The submerged set must be an
UNAMBIGUOUS signal (a new appended
WaterMaterialId, or a separate submerged-mask field onWorldFields) — coder's choice, but it must be distinguishable.climate_from_height/biome_atonevery cell → a submerged cell would get a terrestrial biome. Classify must gain a submerged branch so
below-sea cells do not read as land biomes.
Goal
Add a deterministic coastal pass, opt-in and default-OFF (
enable_coastal), that:sea_leveldatum so terrain below it reads as submerged (the world's first water), andwave-cut platform (near-flat seaward bench), the retreat gated by wave exposure and rock
resistance.
When OFF, the world is byte-identical to the current
worldgen-reliefHEAD.Acceptance criteria (observable, cloud-CI checkable)
enable_coastal=false, every existing acceptance corridor and everyexisting determinism golden is unchanged (no sea datum applied, no coastal RNG draw, no reorder).
enable_coastal=true, asea_leveldatum exists; cells with heightbelow it read as submerged via the unambiguous submerged signal (new
Watermaterial or mask field —NOT reused
Air); a coastline band (cells adjacent to the land↔sea integer threshold) isidentifiable; submerged cells do NOT classify as a terrestrial biome. The
sea_leveldatum isderived from the height distribution (e.g. a fixed percentile of the post-aeolian heights),
quantize-before-compare — NOT a bare constant — so that across a spread of seeds (≥3) the submerged
fraction is bounded away from both 0 % and 100 % (a representative window, not a knife-edge). A bare
constant that degenerates to all-land or all-sea on some seed fails this criterion.
exceeds a threshold ABOVE what fBm + erosion produces (escarpment-grade, per the W-SIM-4a
relief-verification precedent): baseline (coastal OFF) ≈ 0 such cells, coastal ON clearly exceeds.
Anti-forcing-clean — verify the sharp coastal feature, not bulk roughness, and do not crank magnitude
to force it.
bench (bounded, shallow seaward gradient), and platform width correlates positively with wave exposure
(higher exposure ⇒ wider platform). (The full self-limiting wave-damping feedback is NOT required in
this slice — only the observable flat bench + exposure-width correlation.)
exposure; lower resistance ⇒ deeper inset. Demonstrable as a monotone relation on controlled inputs.
pinned integer golden for the ON path (two-pass CI: placeholder → CI-revealed value → pin; arm64 and
x86 agree). The whole pass is pure-integer —
world/tests/no_float_guard_gen.rspasses. Anyalong-profile / distance-from-coast computation (retreat depth, platform width) MUST be
traversal-order-independent (e.g. a seaward distance-transform / BFS to a fixed point, quantized) —
a row-major or scan-order relaxation is a determinism hazard on a
golden-touchslice and isdisallowed. (The canonical closed-loop coastline-ordering primitive is deferred to 7b and must NOT be
pulled forward; an order-free distance field keeps this slice self-contained.)
Out of scope (explicit — these are follow-up sub-slices, do NOT build them here)
foreland) and its canonical coastline-ordering primitive (closed-loop cut + fixed traversal sign)
→ W-SIM-7b.
Verification
Cloud CI (
scripts/ci-report.sh, exit 0 = green): the v2 jobs —v2-sim-x86(invariants + the newcoastal ON-path corridor asserting AC 2–5) and
v2-golden-arm64(the pinned ON-path golden, AC 6). Thedefault-OFF byte-identical guarantee (AC 1) is carried by the existing corridors + goldens staying green
with the flag threaded but off. Two-pass for the golden (pass 1 = code + placeholder
[0,0,0,0]+ PR;pass 2 = pin the CI-revealed value). Pre-push:
cd v2 && bash ../scripts/compile-check.shmust printPASS before any "compiles" claim.
Depends-on
None new. Reuses
erosion::resistance_field/resistance_class_at(rock resistance, integer classes),sim-core::rng::seed_fold(counter-based keyed RNG), and the integer-threshold / quantize-before-comparepattern the glacial ELA gate established. Grounding doc:
pm/reports/w-sim-coastal-grounding.md.