Skip to content

W-SIM-7 coastal (1/n): sea-level datum + cliff / wave-cut platform #423

Description

@mrtlvmbt

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:

  1. establishes a sea_level datum so terrain below it reads as submerged (the world's first water), and
  2. 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)

  1. 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).
  2. 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.
  3. 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.
  4. 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.)
  5. 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.
  6. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent:BOwned by dev agent Bgolden-touchTouches determinism golden — serialize, single-writer

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions