From 11b95f103ee2ac2bd669030d61d026147b80766b Mon Sep 17 00:00:00 2001 From: Natalie Date: Thu, 30 Apr 2026 23:31:44 -0400 Subject: [PATCH] =?UTF-8?q?docs(@projects):=20=E2=9C=85=20add=20terraforme?= =?UTF-8?q?r=20wave-closing=20checklist?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- .project/team-leads/terraformer.md | 41 +++++++++++++++++++ .../age-of-dwarves/docs/terrain/CLIMATE.md | 6 +-- .../age-of-dwarves/docs/terrain/HYDROLOGY.md | 2 +- .../age-of-dwarves/docs/terrain/TECTONICS.md | 2 +- src/simulator/crates/mc-mapgen/src/erosion.rs | 3 ++ .../crates/mc-mapgen/src/hydrology.rs | 3 ++ src/simulator/crates/mc-mapgen/src/seed.rs | 7 +++- 7 files changed, 57 insertions(+), 7 deletions(-) diff --git a/.project/team-leads/terraformer.md b/.project/team-leads/terraformer.md index b6322595..57f92e1e 100644 --- a/.project/team-leads/terraformer.md +++ b/.project/team-leads/terraformer.md @@ -123,6 +123,47 @@ three-tier doc system). Correct order: Rust core (TS twins deleted in their respective implementation waves). +## Wave closing checklist (mandatory after every Wave coordinator lands code) + +The naive "land Rust + tests + objective frontmatter, mark partial, done" +flow drifts the canonical docs. Every Wave coordinator must apply this +before idling: + +1. **rustdoc backref.** Each new `.rs` module under + `mc-{mapgen,climate,ecology}` that ships terrain logic gets a + module-level rustdoc line: + ```rust + //! Implements the Wave-X spec from + //! `public/games/age-of-dwarves/docs/terrain/.md` §. + ``` + A reader of the code is one click from the spec. +2. **Close answered open questions.** Walk the canonical doc's + `## Open questions` section. For every bullet the implementation + answered, flip to `~~strikethrough~~ **Closed (Wave X, YYYY-MM-DD):** + per ` — this is the running ledger of what + the code now does. Leave genuinely unresolved questions open. +3. **Doc-↔-code parity.** If implementation deviated from the spec + (renamed a field, changed an algorithm, swapped a crate), update the + canonical doc to match what shipped. Example: Wave A's `rand_pcg` + incompat → `WORLDGEN_RNG.md` rewrite. The canonical doc is the + contract; the contract must reflect reality. +4. **Freeze the worked example.** The doc's `## Worked example` section + should match the values produced by the determinism golden test. If + the test was rewritten, copy its expected values into the doc; + future drift is caught by parity testing. +5. **Wave-E spillover.** Acceptance bullets the Wave can't satisfy + (lab sliders, visual proof scenes) get *relocated* to `p1-46` + acceptance — not silently dropped. Note the relocation in the + originating objective's Summary. +6. **Regenerate dashboard.** `python3 tools/objectives-report.py`. + +The audit is what distinguishes "code shipped" from "Wave closed". +Skip it and the docs drift; the next contributor opens `HYDROLOGY.md`, +implements something different from `hydrology.rs`, and the Rail-1 +contract erodes. + +--- + ## Escalation - **Climate spec rewrites** (p2-49: switching from `cold` to derived T diff --git a/public/games/age-of-dwarves/docs/terrain/CLIMATE.md b/public/games/age-of-dwarves/docs/terrain/CLIMATE.md index 0221dc71..d2e6f352 100644 --- a/public/games/age-of-dwarves/docs/terrain/CLIMATE.md +++ b/public/games/age-of-dwarves/docs/terrain/CLIMATE.md @@ -416,10 +416,10 @@ The previous `cold` proxy (`abs(row/rows - 0.5) * 2 * (1 - climate)`) is superse ## 15. Open questions -- Should `mean_temp` be expressed in Celsius (or normalised units) for the Whittaker lookup? Currently normalised 0..1 for simplicity; Celsius would enable integration with future temperature-based mechanics. +- ~~Should `mean_temp` be expressed in Celsius (or normalised units) for the Whittaker lookup?~~ **Closed (Wave A, 2026-04-30):** kept normalised 0..1 per `mc-climate/src/derive.rs::mean_temp`; Celsius integration deferred to a future temperature-based mechanics objective. - The Whittaker table has gaps for edge cases (e.g., hot + polar = impossible but can occur near elevated equatorial hexes). Should these resolve to `desert` or `tundra`? -- Should `wind_band` be stored on TileMeta at all, or computed transiently and discarded after the climate pass? -- Continentality `BFS` uses `is_water(biome_id)` — does this need to be `ocean` only, or should large lakes also reset continentality to 0? +- ~~Should `wind_band` be stored on TileMeta at all, or computed transiently and discarded after the climate pass?~~ **Closed (Wave A, 2026-04-30):** computed transiently in `mc-climate/src/derive.rs::wind_band` and discarded after the climate pass; not stored on TileState. +- ~~Continentality `BFS` uses `is_water(biome_id)` — does this need to be `ocean` only, or should large lakes also reset continentality to 0?~~ **Closed (Wave A, 2026-04-30):** any water cell (ocean / coast / lake / inland_sea) resets continentality per `mc-climate/src/derive.rs::compute_continentality_grid`. --- diff --git a/public/games/age-of-dwarves/docs/terrain/HYDROLOGY.md b/public/games/age-of-dwarves/docs/terrain/HYDROLOGY.md index 9f77643a..1058923c 100644 --- a/public/games/age-of-dwarves/docs/terrain/HYDROLOGY.md +++ b/public/games/age-of-dwarves/docs/terrain/HYDROLOGY.md @@ -335,7 +335,7 @@ Riparian distance: - Should `lake_id` be stable across re-generations with the same seed? Currently yes (Planchon-Darboux is deterministic given elevation), but should it be included in the save format? - `MAX_RIPARIAN_DISTANCE = 5` — should wetland biome hexes (already classified) force `riparian_distance = 1` even if not adjacent to a drainage river? -- Should the coarse-grid strategy use bilinear upsampling for `drainage_area` or nearest-neighbour? Currently nearest-neighbour for simplicity. +- ~~Should the coarse-grid strategy use bilinear upsampling for `drainage_area` or nearest-neighbour?~~ **Closed (Wave B, 2026-05-01):** nearest-neighbour per `mc-mapgen/src/hydrology.rs` coarse-grid block. Revisit if 200×200+ maps show visible aliasing along stream borders. - River `RIVER_THRESHOLD = 12` — does this need to scale with map area, or is it intentionally an absolute value (so large maps have proportionally more rivers)? --- diff --git a/public/games/age-of-dwarves/docs/terrain/TECTONICS.md b/public/games/age-of-dwarves/docs/terrain/TECTONICS.md index 8e8c5d69..8cd51a85 100644 --- a/public/games/age-of-dwarves/docs/terrain/TECTONICS.md +++ b/public/games/age-of-dwarves/docs/terrain/TECTONICS.md @@ -287,7 +287,7 @@ This seed produces a world with a major central mountain range dividing east fro - Should `hotspot` plates produce a chain of decreasing-age peaks (simulating plate motion over the hotspot)? Currently a single peak. - `arc_offset_hexes = 3` is a fixed integer. Should it scale with map size? - Transform boundaries: should they produce a modest lateral terrain offset (staggered ridge) or remain nearly flat? -- Should `coast_proximity` be computed here or in the hydrology pass after water body identification? Current decision: here, from plate geometry, so hydrology can use it as a drainage-basin seed. +- ~~Should `coast_proximity` be computed here or in the hydrology pass after water body identification?~~ **Closed (Wave A, 2026-04-30):** computed in tectonics from plate geometry per `mc-mapgen/src/tectonics.rs`; hydrology consumes it as a drainage-basin seed. --- diff --git a/src/simulator/crates/mc-mapgen/src/erosion.rs b/src/simulator/crates/mc-mapgen/src/erosion.rs index c7649c4f..f4a993c0 100644 --- a/src/simulator/crates/mc-mapgen/src/erosion.rs +++ b/src/simulator/crates/mc-mapgen/src/erosion.rs @@ -1,5 +1,8 @@ //! Hydraulic erosion pre-pass — Mei et al. (2007) simplified solver. //! +//! Implements the Wave-B spec from +//! `public/games/age-of-dwarves/docs/terrain/HYDROLOGY.md` §2. +//! //! Carves valleys so the subsequent D6 flow analysis routes rivers into //! low ground rather than along ridges. Runs after tectonics; does NOT //! modify the stored biome classification. diff --git a/src/simulator/crates/mc-mapgen/src/hydrology.rs b/src/simulator/crates/mc-mapgen/src/hydrology.rs index f809b139..e6db7cb4 100644 --- a/src/simulator/crates/mc-mapgen/src/hydrology.rs +++ b/src/simulator/crates/mc-mapgen/src/hydrology.rs @@ -1,6 +1,9 @@ //! D6 flow analysis, drainage accumulation, Planchon-Darboux lake fill, //! Strahler stream order, and riparian distance BFS. //! +//! Implements the Wave-B spec from +//! `public/games/age-of-dwarves/docs/terrain/HYDROLOGY.md` §3–§8. +//! //! Consumes the post-erosion elevation field on `GridState`; populates //! `flow_out`, `drainage_area`, `stream_order`, `lake_id`, `riparian_distance` //! on each `TileState`. diff --git a/src/simulator/crates/mc-mapgen/src/seed.rs b/src/simulator/crates/mc-mapgen/src/seed.rs index 88b5e57d..b8aba17d 100644 --- a/src/simulator/crates/mc-mapgen/src/seed.rs +++ b/src/simulator/crates/mc-mapgen/src/seed.rs @@ -1,15 +1,18 @@ //! Deterministic seed derivation for worldgen passes. //! +//! Implements the Wave-A spec from +//! `public/games/age-of-dwarves/docs/terrain/WORLDGEN_RNG.md`. +//! //! Every pass (tectonics, hydrology, climate, …) derives a sub-seed from the //! map seed via SipHash-2-4 with a fixed key. Changing the key or the mixing -//! constant breaks all existing saves — see `RNG.md` for the migration +//! constant breaks all existing saves — see the canonical doc for the migration //! procedure. //! //! # Why not rand_pcg? //! `rand_pcg 0.3` requires `rand = "0.8"`. The workspace is pinned to //! `rand = "0.9"` which is used by `mc-trade` and `mc-turn`. The two are //! API-incompatible. This module uses an inline PCG-64 implementation -//! instead, described in `RNG.md`. +//! instead, described in `WORLDGEN_RNG.md` §2. use siphasher::sip::SipHasher13; use std::hash::{Hash, Hasher};