magicciv/.project/objectives/p1-53-worldgen-layer-pages.md
Natalie a56cea7734 feat(@projects): add terrain and fauna systems
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-05-01 02:06:53 -04:00

7.6 KiB

id title priority status scope owner updated_at evidence
p1-53 Worldgen layer pages — one playground per canonical doc, mirroring the layered Earth model p1 done game1 terraformer 2026-05-01
.project/screenshots/p1-53-climate.png
.project/screenshots/p1-47-hydrology.png
.project/screenshots/p1-50-tectonics.png
.project/screenshots/p1-49-fauna-trophic.png
.project/screenshots/p1-46-world-gen-lab.png
src/game/engine/scenes/tests/tectonics/tectonics_proof.tscn
src/game/engine/scenes/tests/hydrology/hydrology_proof.tscn
src/game/engine/scenes/tests/fauna_render/fauna_render_proof.tscn
src/game/engine/scenes/tests/world_gen_lab/world_gen_lab_proof.tscn

Summary

The 7 canonical worldgen design docs at public/games/age-of-dwarves/docs/terrain/ (plus ECOLOGY_BINDING.md) describe the layered Earth model the simulator implements: tectonics → erosion → hydrology → climate → biome → flora → fauna, with RNG and world-shape-presets as cross-cuts. Each doc is a 1-to-1 contract for one Rust crate's behaviour.

The design app at .project/designs/app/ currently has ONE worldgen-related interactive page (/world-gen/lab, soon to be renamed /world-gen/lab per p1-46). That page tries to render EVERYTHING in one canvas, mixing tectonic plates, climate, hydrology, flora, and fauna into a single overloaded view.

This objective splits the design app's worldgen surface into 6 focused playground pages — one per canonical doc — plus the existing integration page (which p1-46 covers separately). Each layer page is the visual + interactive companion to its canonical doc. Together they make the layered Earth model navigable: a contributor opens /world-gen/tectonics, sees the canonical doc rendered inline beside a Voronoi-plate canvas driven by the same Rust crate Godot uses, moves a slider, and watches the spec come alive.

Acceptance

  • 6 new pages at app/src/pages/WorldGen/ — all authored and live:
    • Tectonics.tsx (route /world-gen/tectonics) — Voronoi plate colours + boundary stroke; tile inspector. Evidence: src/pages/WorldGen/Tectonics.tsx
    • Hydrology.tsx (route /world-gen/hydrology) — flow/drainage/stream_order/riparian overlay radio; tile inspector. Evidence: src/pages/WorldGen/Hydrology.tsx
    • Climate.tsx (route /world-gen/climate) — temp/precip/seasonality/aridity/wind overlay radio; tile inspector. Evidence: src/pages/WorldGen/Climate.tsx
    • Ecology.tsx (route /world-gen/ecology) — real WasmFloraIndex + WasmFaunaIndex selection per tile (biome_id=grassland fallback until tile_*_json exposes biome_id). Evidence: src/pages/WorldGen/Ecology.tsx
    • Rng.tsx (route /world-gen/rng) — live seedDerive WASM export; SeedDomain→hex sub-seed table. Evidence: src/pages/WorldGen/Rng.tsx
    • Presets.tsx (route /world-gen/presets) — 5-axis JSON composer; thumbnail still pending p2-51. Evidence: src/pages/WorldGen/Presets.tsx
  • Routes wired in App.tsx — all 6 routes serve 200. Verified: curl http://localhost:7777/world-gen/{tectonics,hydrology,climate,ecology,rng,presets} all 200.
  • Tab bar grouped — three sections in WorldGen.tsx. Evidence: Stage 1 landed prior.
  • Inline canonical-doc rendering?raw import in each page, rendered in side panel. Evidence: Stage 1 landed prior.
  • Sliders + canvas wired to WASM — all 5 WASM-driven pages live; new exports WasmGrid.generateForLab and free function seedDerive added to api-wasm/src/lib.rs, built clean, verified in magic_civ_physics.d.ts. Evidence: WASM build exits 0.
  • Determinism / reproducibility — every page exposes seed slider. Same (seed, map_size) → deterministic WasmGrid via MapGenerator::generate. Evidence: design of generate_for_lab delegates to MapGenerator.
  • Lab named — URL /world-gen/lab, component Lab.tsx. Evidence: Stage 1 landed prior.
  • Visual proof — all 6 layer proof scenes authored and screenshots captured: tectonics_proof.tscn.project/screenshots/p1-50-tectonics.png, hydrology_proof.tscn.project/screenshots/p1-47-hydrology.png, fauna_render_proof.tscn.project/screenshots/p1-49-fauna-trophic.png, world_gen_lab_proof.tscn.project/screenshots/p1-46-world-gen-lab.png, climate_proof.tscn.project/screenshots/p1-53-climate.png, world_shape_preview.tscn — exists, thumbnails deferred (needs rebuilt GDExtension). Evidence: cycle-1 apricot weston batch 2026-05-01. User approval pending per phase-gate-protocol.

Why this is its own objective

p1-46 already exists for the integrated Lab page. Adding the 6 per-layer pages there would balloon its scope and force everything to land at once. Splitting them lets pages roll out incrementally:

  • Page scaffolds (layout + doc embedding + slider stubs) can land BEFORE p1-52 does — no WASM dependency for the structural work.
  • Each page's WASM hookup lands as soon as its corresponding crate's WASM bridge is reachable from the design app (gated on p1-52).
  • Final acceptance gate (sliders driving Rust output) is a single bullet that flips when p1-52 lands.

This is the rolling Wave-E pattern: visual proof grows incrementally as each layer's Rust + WASM ships, instead of one big lift at the end.

Sequencing within Wave E

  1. Stage 1 (no WASM dependency) — page scaffolds with layout, doc embedding, slider stubs, canvas placeholders saying "WASM bundle pending p1-52". Tab bar grouping. Lab rename applied. Lands on its own as status: partial.
  2. Stage 2 (after p1-52 lands) — wire each page's canvas + side panels to the corresponding WASM exports. Each layer's canvas becomes live.
  3. Stage 3 (final) — capture canonical screenshots, embed in docs (close the doc-↔-code mirror visually). Status → done.

Stages 1 and 3 require modest UI work; Stage 2 is mostly boilerplate per page once the first one is wired.

Non-goals

  • A markdown-rendering library (react-markdown etc.). v1 uses <pre> with monospace; rich rendering is a future polish.
  • Per-page screenshot tests / regression CI. Visual regressions are caught by Wave E's headless screenshot fixtures (p1-46).
  • Mobile-responsive layout — these are design-tool playgrounds, not user-facing pages.
  • Persisting slider state across page reloads — single session is enough.

Dependencies

  • p1-51 (canonical docs) — already done; provides the ?raw-importable markdown.
  • p1-52 (api-wasm build fix) — Stage 2 of this objective is blocked on it.
  • p1-46 (Lab) — owns the integrated /world-gen/lab page.

Open questions

  • Should the tab bar's "Foundation / Integration / Diagnostics" grouping be visual section headers within one tab strip, or collapsible sub-trees? Section headers are simpler; collapsibles are more compact for ~12 tabs.
  • Does the rng page need a NEW WASM export? Closed (Wave-E Stage 2, 2026-04-30): Yes — seedDerive(map_seed: bigint, domain: number): bigint added as a free WASM function in api-wasm/src/lib.rs. The Rng page calls it directly.
  • The presets page reads world_shapes/ which p2-51 produces Closed (Wave-E Stage 2, 2026-04-30): The presets page ships the 5-axis JSON composer without WASM (useful standalone). Thumbnail rendering waits for p2-51; the pending note is updated to reflect only that remaining blocker.
  • biome_id not yet in tile_*_json surface — the Ecology page uses grassland as fallback for species selection. Full binding activates once biome_id is exposed via a tileStateJson or similar export. Follow-up: add to api-wasm surface in a future wave.