feat(@projects/@magic-civilization): ✨ update objectives priorities and team assignments
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
a22d540e0e
commit
8f257d0933
4 changed files with 231 additions and 30 deletions
|
|
@ -15,10 +15,10 @@
|
|||
| Priority | ✅ | 🔵 | 🟡 | 🔴 | ❌ | ⚫ | Total |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| **P0** | 43 | 0 | 0 | 0 | 0 | 0 | 43 |
|
||||
| **P1** | 33 | 1 | 9 | 0 | 17 | 1 | 61 |
|
||||
| **P2** | 33 | 0 | 2 | 1 | 7 | 2 | 45 |
|
||||
| **P1** | 33 | 1 | 9 | 0 | 19 | 1 | 63 |
|
||||
| **P2** | 33 | 0 | 2 | 1 | 9 | 2 | 47 |
|
||||
| **P3 (oos)** | 3 | 0 | 0 | 0 | 1 | 19 | 23 |
|
||||
| **total** | **112** | **1** | **11** | **1** | **25** | **22** | **172** |
|
||||
| **total** | **112** | **1** | **11** | **1** | **29** | **22** | **176** |
|
||||
|
||||
</td><td valign='top' style='padding-left:2em'>
|
||||
|
||||
|
|
@ -26,10 +26,10 @@
|
|||
|
||||
| Team Lead | Remaining |
|
||||
|---|---|
|
||||
| [terraformer](../team-leads/terraformer.md) | 9 |
|
||||
| [warcouncil](../team-leads/warcouncil.md) | 7 |
|
||||
| [asset-sprite](../team-leads/asset-sprite.md) | 6 |
|
||||
| [shipwright](../team-leads/shipwright.md) | 5 |
|
||||
| [terraformer](../team-leads/terraformer.md) | 5 |
|
||||
| [combat-dev](../team-leads/combat-dev.md) | 1 |
|
||||
| [simulator-infra](../team-leads/simulator-infra.md) | 1 |
|
||||
| [asset-audio](../team-leads/asset-audio.md) | 1 |
|
||||
|
|
@ -136,9 +136,11 @@
|
|||
| [p1-44](p1-44-buildings-as-producers.md) | ❌ missing | Buildings produce units, not the city center — per-building production queues | — | 2026-04-29 |
|
||||
| [p1-45](p1-45-batch-binary-freshness.md) | ❌ missing | "Batch binary freshness: rebuild GDExt before every autoplay batch" | [simulator-infra](../team-leads/simulator-infra.md) | 2026-04-30 |
|
||||
| [p1-46](p1-46-design-lab-terrain-dimensions.md) | 🟡 partial | Terrain Dimensions Lab — fix ridginess, bind 149 flora species, add Whittaker plot | [terraformer](../team-leads/terraformer.md) | 2026-04-30 |
|
||||
| [p1-47](p1-47-river-hydrology-network.md) | ❌ missing | River hydrology — D6 flow analysis, multi-hex lakes, cross-tile rivers | [terraformer](../team-leads/terraformer.md) | 2026-04-30 |
|
||||
| [p1-48](p1-48-flora-species-renderer.md) | ❌ missing | Flora species renderer — bind 149 species to world-map tile rendering | [terraformer](../team-leads/terraformer.md) | 2026-04-30 |
|
||||
| [p1-47](p1-47-river-hydrology-network.md) | ❌ missing | River hydrology — D6 flow analysis, hydraulic erosion, multi-hex lakes, cross-tile rivers | [terraformer](../team-leads/terraformer.md) | 2026-04-30 |
|
||||
| [p1-48](p1-48-flora-species-renderer.md) | ❌ missing | Flora species renderer — bind 149 species to world-map tile rendering (single source of truth) | [terraformer](../team-leads/terraformer.md) | 2026-04-30 |
|
||||
| [p1-49](p1-49-fauna-species-renderer.md) | ❌ missing | Fauna species renderer — 61 Game-1 species visible on encounter and lair tiles | [terraformer](../team-leads/terraformer.md) | 2026-04-30 |
|
||||
| [p1-50](p1-50-tectonic-prepass.md) | ❌ missing | Tectonic prepass — voronoi plates + boundary classification seeding elevation | [terraformer](../team-leads/terraformer.md) | 2026-04-30 |
|
||||
| [p1-51](p1-51-worldgen-canonical-design-docs.md) | ❌ missing | Worldgen canonical design docs — author the spec before any Rust | [terraformer](../team-leads/terraformer.md) | 2026-04-30 |
|
||||
| [p2-06](p2-06-export-pipeline.md) | ✅ done | Export pipeline for Windows / macOS / Linux | [shipwright](../team-leads/shipwright.md) | 2026-04-25 |
|
||||
| [p2-16](p2-16-audio-assets.md) | 🔵 in_progress | Audio assets — in-theme OSS launch pack + source ledger | [asset-audio](../team-leads/asset-audio.md) | 2026-04-27 |
|
||||
| [p2-22](p2-22-sprite-generation-pipeline.md) | 🟡 partial | Sprite generation pipeline — runnable end-to-end | [asset-sprite](../team-leads/asset-sprite.md) | 2026-04-25 |
|
||||
|
|
@ -196,7 +198,9 @@
|
|||
| [p2-46](p2-46-past-games-archive-replay-viewer.md) | ❌ missing | Past-games archive & replay viewer — `mc-replay` crate, on-disk archive, projection-based playback | [shipwright](../team-leads/shipwright.md) | 2026-04-30 |
|
||||
| [p2-47](p2-47-in-game-statistics-screens.md) | ❌ missing | In-game statistics screens — Civ-style 5-tab modal (Demographics / Graphs / Rankings / Replay / Histories) | [shipwright](../team-leads/shipwright.md) | 2026-04-30 |
|
||||
| [p2-48](p2-48-end-of-game-summary-screen.md) | ❌ missing | End-of-game summary screen — outcome banner, standings, score graph, awards, timeline, footer actions | [shipwright](../team-leads/shipwright.md) | 2026-04-30 |
|
||||
| [p2-49](p2-49-climate-axes-latitude-continentality.md) | ❌ missing | Climate axes refactor — latitude + continentality as first-class per-hex inputs | [terraformer](../team-leads/terraformer.md) | 2026-04-30 |
|
||||
| [p2-49](p2-49-climate-axes-latitude-continentality.md) | ❌ missing | Climate axes refactor — latitude + continentality + zonal winds as first-class per-hex inputs | [terraformer](../team-leads/terraformer.md) | 2026-04-30 |
|
||||
| [p2-50](p2-50-rng-determinism-pin.md) | ❌ missing | Deterministic RNG + seed-derivation pin across mc-mapgen / mc-climate / mc-ecology | [terraformer](../team-leads/terraformer.md) | 2026-04-30 |
|
||||
| [p2-51](p2-51-world-shape-knobs.md) | ❌ missing | Player-facing world-shape parameters on new-game screen | [terraformer](../team-leads/terraformer.md) | 2026-04-30 |
|
||||
|
||||
## Out of Scope (Game 2 / Game 3)
|
||||
|
||||
|
|
|
|||
145
.project/objectives/p1-51-worldgen-canonical-design-docs.md
Normal file
145
.project/objectives/p1-51-worldgen-canonical-design-docs.md
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
---
|
||||
id: p1-51
|
||||
title: Worldgen canonical design docs — author the spec before any Rust
|
||||
priority: p1
|
||||
status: missing
|
||||
scope: game1
|
||||
owner: terraformer
|
||||
updated_at: 2026-04-30
|
||||
wave: 0
|
||||
coordinates_with:
|
||||
- p1-46
|
||||
- p1-47
|
||||
- p1-48
|
||||
- p1-49
|
||||
- p1-50
|
||||
- p2-49
|
||||
- p2-50
|
||||
- p2-51
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
The Terraformer bundle (`p1-46`…`p2-51`) is an 8-objective procedural
|
||||
terrain pipeline spanning tectonics, hydrology, climate, ecology, RNG
|
||||
determinism, world-shape presets, and the design-app Terrain Dimensions
|
||||
Lab. Per **Rail 1** (`Rust is the simulation source of truth`,
|
||||
CLAUDE.md:13) and the project's three-tier doc system (canonical →
|
||||
engineering → JSON, per `.project/designs/README.md`), every Rust crate
|
||||
must mechanically implement an authored canonical specification — never
|
||||
the reverse.
|
||||
|
||||
This Wave-0 objective authors the **7 canonical design docs** at
|
||||
`public/games/age-of-dwarves/docs/terrain/` (and `…/docs/` for ecology
|
||||
binding) that gate all subsequent Wave A–E implementation. Each Rust
|
||||
crate's rustdoc references the canonical doc it implements; bridges
|
||||
(`api-gdext`, `api-wasm`) and consumers (Godot, design lab) consume
|
||||
what the canonical specs declare — not what someone interpolated.
|
||||
|
||||
The current TypeScript twins (`floraSpecies.ts`, `hydrology.ts`,
|
||||
`faunaSpecies.ts`) under `.project/designs/app/src/utils/worldGen/`
|
||||
exist precisely because this stage was skipped. Authoring the canonical
|
||||
docs first prevents that recurrence.
|
||||
|
||||
## Acceptance
|
||||
|
||||
- ◻ **`WORLDGEN_PIPELINE.md`** at `public/games/age-of-dwarves/docs/terrain/`
|
||||
— master overview + end-to-end data-flow diagram + module map:
|
||||
tectonics → erosion → hydrology → climate → biome classifier → flora
|
||||
binding → fauna binding. Cross-references all 7 Wave-A–E objectives.
|
||||
Single doc that lets any new contributor see the whole shape at once.
|
||||
- ◻ **`TECTONICS.md`** at `…/docs/terrain/` — Voronoi plate algorithm,
|
||||
plate-type taxonomy (cratonic / passive / active / volcanic_arc /
|
||||
rift / hotspot), boundary classification, elevation bias logic,
|
||||
exported fields `mountain_proximity`, `coast_proximity`. (Spec for
|
||||
`p1-50`; consumed by `p2-49` rain-shadow.)
|
||||
- ◻ **`HYDROLOGY.md`** at `…/docs/terrain/` — Hydraulic erosion
|
||||
pre-pass (Mei et al. simplified solver, ~5 sub-iterations), D6 flow
|
||||
direction, drainage accumulation, Strahler stream order,
|
||||
Planchon-Darboux lake fill, border-outflow rule, coarse-grid
|
||||
resolution strategy for >150×150 maps, exported field
|
||||
`riparian_distance`. (Spec for `p1-47`; consumed by `p1-48`/`p1-49`
|
||||
for riparian feedback + aquatic gate.)
|
||||
- ◻ **`CLIMATE.md`** at `…/docs/terrain/` — Latitude (signed
|
||||
hemispheric −1..+1), continentality (hex-BFS graph distance not
|
||||
Euclidean), zonal wind bands (trade / westerly / polar by latitude
|
||||
band), rain-shadow logic, west-coast maritime asymmetry as cheap
|
||||
ocean-current proxy, elevation lapse rate, derivations of
|
||||
`mean_temp` / `mean_precip` / `seasonality` / `aridity_index`,
|
||||
T_band / P_band 5-bucket discretisation. (Spec for `p2-49`; consumed
|
||||
by `p1-48`/`p1-49` index keying.)
|
||||
- ◻ **`ECOLOGY_BINDING.md`** at `…/docs/` (or extend
|
||||
`ecology-gameplay.md`) — `TerrainFloraIndex` keyed by
|
||||
`(biome_id, T_band, P_band)`; contribution-normalisation rule
|
||||
(rescale by sum, never clip); riparian-preference rule;
|
||||
lineage→glyph map (conifer / temperate-broadleaf /
|
||||
tropical-broadleaf / cactus / palm / aquatic / moss);
|
||||
`TerrainFaunaIndex` with trophic-overlap rule (≤1 apex per tile,
|
||||
predator requires `prey[]` present in self-or-adjacent), aquatic
|
||||
gate via `riparian_distance`, domain-coherence rules
|
||||
(air / land / marine / freshwater). (Spec for `p1-48` + `p1-49`.)
|
||||
- ◻ **`WORLDGEN_RNG.md`** at `…/docs/terrain/` — Pinned RNG
|
||||
(`Pcg64` from `rand_pcg`, version pinned in workspace Cargo.toml),
|
||||
`SeedDomain` enum, `seed::derive(map_seed, domain) -> u64` mixing
|
||||
function, save-format pin (RNG version + seed both written to
|
||||
saves), parity-test contract for WASM↔GDExt. (Spec for `p2-50`.)
|
||||
- ◻ **`WORLDGEN_PRESETS.md`** at `…/docs/terrain/` — World-shape
|
||||
preset catalogue with 5 axes (`landmass`, `climate`, `moisture`,
|
||||
`age`, `sea_level`), JSON schema for
|
||||
`public/games/age-of-dwarves/data/world_shapes/*.json`,
|
||||
preview-thumbnail discipline (rendered from a proof scene, never
|
||||
hand-painted). (Spec for `p2-51`.)
|
||||
- ◻ **Cross-references locked** — each implementation objective
|
||||
(`p1-46`…`p2-51`) gets a `canonical_doc:` frontmatter entry
|
||||
pointing at the matching doc above. Implementer agents read the
|
||||
canonical doc before writing Rust.
|
||||
- ◻ **Designs index updated** —
|
||||
`.project/designs/README.md` table extended with rows linking each
|
||||
canonical doc to its companion lab page (current `ForestLab`,
|
||||
future `TectonicsLab` / `ClimateLab` / `HydrologyLab`).
|
||||
- ◻ **CLAUDE.md instruction-router updated** — the "When the task
|
||||
involves…" table grows entries pointing at the new canonical docs
|
||||
for: tectonic plates / hydrology + erosion / climate axes / ecology
|
||||
binding / RNG determinism / world-shape presets.
|
||||
|
||||
## Why this matters (anti-pattern this prevents)
|
||||
|
||||
Without doc-first discipline, two consumers diverge: the design lab
|
||||
gets a TS implementation, Godot gets a Rust implementation, the
|
||||
canonical contract lives in nobody's head. The current TS twins
|
||||
(`floraSpecies.ts`, `hydrology.ts`, `faunaSpecies.ts`) at
|
||||
`.project/designs/app/src/utils/worldGen/` are exactly that failure
|
||||
mode — they're scheduled for deletion by `p1-47` / `p1-48` / `p1-49`
|
||||
with the explicit acceptance bullet "Pre-existing TS twin is deleted,
|
||||
not ported".
|
||||
|
||||
Every doc landed here becomes a 1-to-1 contract that constrains both
|
||||
the GDExt and WASM bridges to the same behaviour. Implementation
|
||||
agents working on Wave A-E can be given **only** the canonical doc +
|
||||
their objective acceptance and produce conforming Rust without
|
||||
further coordination.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Authoring the Rust code (`mc-mapgen`, `mc-climate`, `mc-ecology`) —
|
||||
that's Wave A-E objectives.
|
||||
- Authoring the JSON parameter files (extracted from the docs at
|
||||
Wave A-E implementation time).
|
||||
- Capturing canonical screenshots — that's Wave E (`p1-46`).
|
||||
- Rewriting `HEX_GEOMETRY.md` or other already-canonical docs — only
|
||||
authoring the missing 7. If existing docs (e.g.
|
||||
`terrain/TERRAIN_SYSTEM.md`, `CREATURE_ECOSYSTEM.md`) overlap, link
|
||||
them rather than duplicate.
|
||||
|
||||
## Dependencies
|
||||
|
||||
None — this is Wave 0. All other terraformer objectives become
|
||||
unblocked by this objective's completion.
|
||||
|
||||
## Why status: partial cannot occur here
|
||||
|
||||
Either a doc exists with all sections filled in, or it does not. There
|
||||
is no "partial doc" — the doc is the contract. Every acceptance bullet
|
||||
above is a single deliverable: the file exists at the path, with the
|
||||
content sketched above, reviewed for internal consistency. K=N or
|
||||
status stays `missing`.
|
||||
|
|
@ -8,6 +8,7 @@ objectives:
|
|||
- p1-48
|
||||
- p1-49
|
||||
- p1-50
|
||||
- p1-51
|
||||
- p2-49
|
||||
- p2-50
|
||||
- p2-51
|
||||
|
|
@ -96,22 +97,31 @@ Files / crates this lead may modify:
|
|||
|
||||
## Sequencing
|
||||
|
||||
The naive "single parallel sweep" ordering is wrong. The classifier
|
||||
axes change in p2-49, which invalidates flora/fauna `biomes[]` indexes
|
||||
built ahead of it. Correct order:
|
||||
The naive "single parallel sweep" ordering is wrong on two counts: the
|
||||
classifier axes change in p2-49 (which invalidates flora/fauna
|
||||
`biomes[]` indexes built ahead of it), AND no Rust code should be
|
||||
written before the canonical design docs exist (Rail 1 + the project's
|
||||
three-tier doc system). Correct order:
|
||||
|
||||
1. **Wave A (parallel)** — p1-50 (tectonics) + p2-49 (climate axes) +
|
||||
1. **Wave 0 (parallel) — DOCS FIRST** — p1-51 authors the 7 canonical
|
||||
design docs at `public/games/age-of-dwarves/docs/terrain/` (plus
|
||||
`ECOLOGY_BINDING.md` at `…/docs/`). Every Rust crate in Waves A–E
|
||||
mechanically implements one of these docs. NO IMPLEMENTATION
|
||||
WORK STARTS UNTIL WAVE 0 IS DONE.
|
||||
2. **Wave A (parallel)** — p1-50 (tectonics) + p2-49 (climate axes) +
|
||||
p2-50 (RNG pin). These rewrite the foundation; everything else
|
||||
depends on stable biome IDs and reproducible seeds.
|
||||
2. **Wave B (parallel)** — p1-47 (hydrology + erosion). Independent of
|
||||
3. **Wave B (parallel)** — p1-47 (hydrology + erosion). Independent of
|
||||
climate; only needs the post-tectonic elevation field.
|
||||
3. **Wave C (parallel)** — p1-48 (flora) + p1-49 (fauna). Both consume
|
||||
4. **Wave C (parallel)** — p1-48 (flora) + p1-49 (fauna). Both consume
|
||||
stable biome IDs (Wave A) and water topology (Wave B).
|
||||
4. **Wave D** — p2-51 (player-facing world-shape knobs). Once the
|
||||
5. **Wave D** — p2-51 (player-facing world-shape knobs). Once the
|
||||
pipeline parameters are stable, expose them on the new-game screen.
|
||||
5. **Wave E** — p1-46 (lab as integration / proof). Whittaker plot,
|
||||
6. **Wave E** — p1-46 (lab as integration / proof). Whittaker plot,
|
||||
ridginess fix, screenshot fixtures, all against the post-refactor
|
||||
axes.
|
||||
axes — and the lab finally becomes a thin WASM consumer of the
|
||||
Rust core (TS twins deleted in their respective implementation
|
||||
waves).
|
||||
|
||||
## Escalation
|
||||
|
||||
|
|
@ -141,6 +151,8 @@ built ahead of it. Correct order:
|
|||
|
||||
Terraformer does NOT run a cron loop initially. The owned objectives
|
||||
get a wave-sequenced `/experts-team` parallel sweep per the ordering
|
||||
above. Once Wave E (p1-46) lands with proof screenshots in
|
||||
above — starting with Wave 0 (p1-51 canonical design docs), then
|
||||
proceeding through Waves A–E only after their gating canonical doc
|
||||
exists. Once Wave E (p1-46) lands with proof screenshots in
|
||||
`.project/screenshots/`, the bundle is closed. Subsequent work invoked
|
||||
on demand.
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
{
|
||||
"generated_at": "2026-04-30T22:05:58Z",
|
||||
"generated_at": "2026-04-30T22:33:30Z",
|
||||
"totals": {
|
||||
"in_progress": 1,
|
||||
"partial": 11,
|
||||
"stub": 1,
|
||||
"done": 112,
|
||||
"missing": 25,
|
||||
"in_progress": 1,
|
||||
"stub": 1,
|
||||
"oos": 22,
|
||||
"total": 172
|
||||
"missing": 29,
|
||||
"partial": 11,
|
||||
"total": 176
|
||||
},
|
||||
"objectives": [
|
||||
{
|
||||
|
|
@ -918,27 +918,27 @@
|
|||
"scope": "game1",
|
||||
"owner": "terraformer",
|
||||
"updated_at": "2026-04-30",
|
||||
"summary": "The Terrain Dimensions Lab at `/world-gen/forest-lab` (lab tab) currently\nclassifies the 17 base biomes and renders cross-tile flora/minerals/fauna\noverlays driven by 4 biome sliders + 3 toggleable overlay layers. Three\nknown gaps:\n\n1. **Ridginess slider has zero effect at default elevation 0.65.** The\n classifier (`terrain.ts:118`) only consults ridginess when\n `elevation > 0.85 ∧ ridginess > 0.92` for the volcano case. Anywhere\n else, the slider does nothing — the user verified this on the live\n lab and flagged it.\n2. **The lab loads 0 of 149 flora species.** Trees / shrubs / ground\n cover are generic per terrain. The 149 species in\n `public/resources/ecology/flora/species/*.json` carry rich schema\n (`biomes[]`, `lineage`, `tags` with layer info, `quality_tier`,\n `canopy_contribution`) that the lab ignores entirely.\n3. **No Whittaker T×P plot inset** — the user can move sliders but has\n no visual map of where they are in biome space."
|
||||
"summary": "The Terrain Dimensions Lab at `/world-gen/forest-lab` (lab tab) currently\nclassifies the 17 base biomes and renders cross-tile flora/minerals/fauna\noverlays driven by 4 biome sliders + 3 toggleable overlay layers. Three\nknown gaps:\n\n1. **Ridginess slider has zero effect at default elevation 0.65.** The\n classifier (`terrain.ts:118`) only consults ridginess when\n `elevation > 0.85 ∧ ridginess > 0.92` for the volcano case. Anywhere\n else, the slider does nothing — the user verified this on the live\n lab and flagged it.\n2. **The lab loads 0 of 149 flora species.** Trees / shrubs / ground\n cover are generic per terrain. The 149 species in\n `public/resources/ecology/flora/species/*.json` carry rich schema\n (`biomes[]`, `lineage`, `tags` with layer info, `quality_tier`,\n `canopy_contribution`) that the lab ignores entirely.\n3. **No Whittaker T×P plot inset** — the user can move sliders but has\n no visual map of where they are in biome space.\n\nThis objective is the **integration / proof surface** of the Wave-E\nterraformer bundle. It must land **after** p1-50, p2-49, p2-50 (Wave A),\np1-47 (Wave B), and p1-48/p1-49 (Wave C). The Whittaker plot, ridginess\nbehaviour, and flora binding all consume the post-refactor axes."
|
||||
},
|
||||
{
|
||||
"id": "p1-47",
|
||||
"title": "River hydrology — D6 flow analysis, multi-hex lakes, cross-tile rivers",
|
||||
"title": "River hydrology — D6 flow analysis, hydraulic erosion, multi-hex lakes, cross-tile rivers",
|
||||
"priority": "p1",
|
||||
"status": "missing",
|
||||
"scope": "game1",
|
||||
"owner": "terraformer",
|
||||
"updated_at": "2026-04-30",
|
||||
"summary": "Water bodies in the current map are per-hex terrain types\n(`ocean`, `coast`, `lake`, `inland_sea`) with no connectivity. Real\ngeographic water is **topological**: rivers are DAGs from headwaters to\nocean, lakes are multi-hex polygons, coastlines are polylines along\nland/water borders.\n\nThe data already encodes this in:\n\n- `public/games/age-of-dwarves/data/terrain/terrain_blends.json` —\n `riverside_forest`, `shore`, `cliff`, `bog_edge` ecotones (cross-tile)\n- 10+ fauna species with `river` / `lake` / `wetland` biomes\n (bald_eagle, alligator, otter, kingfisher, beaver, etc.)\n- 4 riparian flora species: `lotus`, `papyrus`, `giant_water_lily`,\n `pioneer_sedge`\n\nBut there is **no rendering pass** that uses the topology. This\nobjective adds D6 flow-direction analysis on the elevation grid,\ndrainage-area accumulation, lake-basin filling, and a cross-tile\nrenderer that draws rivers as bezier paths through hex edges and lakes\nas multi-hex continuous fills."
|
||||
"summary": "Water bodies in the current map are per-hex terrain types\n(`ocean`, `coast`, `lake`, `inland_sea`) with no connectivity. Real\ngeographic water is **topological**: rivers are DAGs from headwaters to\nocean, lakes are multi-hex polygons, coastlines are polylines along\nland/water borders.\n\nThe data already encodes this in:\n\n- `public/games/age-of-dwarves/data/terrain/terrain_blends.json` —\n `riverside_forest`, `shore`, `cliff`, `bog_edge` ecotones (cross-tile)\n- 10+ fauna species with `river` / `lake` / `wetland` biomes\n (bald_eagle, alligator, otter, kingfisher, beaver, etc.)\n- 4 riparian flora species: `lotus`, `papyrus`, `giant_water_lily`,\n `pioneer_sedge`\n\nBut there is **no rendering pass** that uses the topology. This\nobjective adds:\n\n1. A single hydraulic-erosion iteration that carves valleys before\n drainage analysis (so rivers sit in valleys, not on ridges).\n2. D6 flow-direction analysis on the eroded elevation grid.\n3. Drainage-area accumulation, lake-basin filling.\n4. A cross-tile renderer that draws rivers as bezier paths through\n hex edges and lakes as multi-hex continuous fills.\n\nHydrology computes topology only. Riparian feedback into flora\nselection lives in p1-48; aquatic-domain fauna gating lives in p1-49."
|
||||
},
|
||||
{
|
||||
"id": "p1-48",
|
||||
"title": "Flora species renderer — bind 149 species to world-map tile rendering",
|
||||
"title": "Flora species renderer — bind 149 species to world-map tile rendering (single source of truth)",
|
||||
"priority": "p1",
|
||||
"status": "missing",
|
||||
"scope": "game1",
|
||||
"owner": "terraformer",
|
||||
"updated_at": "2026-04-30",
|
||||
"summary": "`public/resources/ecology/flora/species/*.json` defines **149 species**\nwith rich schema:\n\n- `biomes[]` — which terrain types support the species\n- `tags[]` including layer (`layer_canopy` / `layer_understory` /\n `layer_ground` / `layer_fungal`) and structure (`structure_woody` /\n `conifer` / `broadleaf` / `evergreen`)\n- `lineage` — taxonomic group (`conifers`, `broadleaf_trees`,\n `tropical_broadleaf`, `cacti`, `palms`, `aquatic_plants`,\n `mosses_lichens`, etc.)\n- `quality_tier` (0–10), `canopy_contribution`,\n `undergrowth_contribution`, `fungi_contribution`\n- `drought_tolerance`, `fire_resistance`, `growth_rate`\n\nBut the world-map renderer (`mc-render` or Godot tilemap layer) draws\ngeneric green circles for forest tiles. This objective wires the 149\nspecies data into the canvas / TileMap rendering so a \"forest\" tile in\ntemperate Europe shows oak / beech / birch and a \"forest\" tile in\ntropical climate shows mahogany / teak / strangler_fig — each instance\npicked from the species pool that lists this terrain in its `biomes[]`."
|
||||
"summary": "`public/resources/ecology/flora/species/*.json` defines **149 species**\nwith rich schema:\n\n- `biomes[]` — which terrain types support the species\n- `tags[]` including layer (`layer_canopy` / `layer_understory` /\n `layer_ground` / `layer_fungal`) and structure (`structure_woody` /\n `conifer` / `broadleaf` / `evergreen`)\n- `lineage` — taxonomic group (`conifers`, `broadleaf_trees`,\n `tropical_broadleaf`, `cacti`, `palms`, `aquatic_plants`,\n `mosses_lichens`, etc.)\n- `quality_tier` (0–10), `canopy_contribution`,\n `undergrowth_contribution`, `fungi_contribution`\n- `drought_tolerance`, `fire_resistance`, `growth_rate`\n\nBut the world-map renderer (`mc-render` or Godot tilemap layer) draws\ngeneric green circles for forest tiles. This objective wires the 149\nspecies data into the canvas / TileMap rendering so a \"forest\" tile in\ntemperate climate shows oak / beech / birch and a \"forest\" tile in\ntropical climate shows mahogany / teak / strangler_fig — each instance\npicked from the species pool that lists this terrain in its `biomes[]`.\n\n**Single source of truth (Rail 1):** the selector is implemented ONCE\nin `mc-ecology` (Rust), exposed to Godot via GDExtension and to the\ndesign-lab via WASM. NO TypeScript twin."
|
||||
},
|
||||
{
|
||||
"id": "p1-49",
|
||||
|
|
@ -950,6 +950,26 @@
|
|||
"updated_at": "2026-04-30",
|
||||
"summary": "`public/games/age-of-dwarves/data/manifests/fauna.json` whitelists **61\nGame-1 species** with rich JSON schema in\n`public/resources/ecology/fauna/species/*.json`:\n\n- `domain` (land / air / marine / freshwater)\n- `trophic_level` (apex_predator / predator / herbivore / omnivore)\n- `biomes[]`\n- `prey[]` — actual food-web edges\n- `ecology_tier` (1–10 rarity / strength)\n- `forms_lairs` + `lair_type`\n- `lineage` (canines, ursids, cervids, raptors, etc.)\n- `traits[]` including `size_*`\n\nBut the world-map renderer draws abstract icons for lairs and no\noverlay at all for ambient fauna. This objective wires the species\ndata into the renderer so a wolf lair shows a wolf silhouette, a bear\ncave shows a bear, a harpy nest shows a winged figure."
|
||||
},
|
||||
{
|
||||
"id": "p1-50",
|
||||
"title": "Tectonic prepass — voronoi plates + boundary classification seeding elevation",
|
||||
"priority": "p1",
|
||||
"status": "missing",
|
||||
"scope": "game1",
|
||||
"owner": "terraformer",
|
||||
"updated_at": "2026-04-30",
|
||||
"summary": "The current `mc-mapgen` elevation field is pure fBm noise. Continents\nare amorphous, mountain ranges are noise-shaped blobs, and there is no\ngeological reason for a peak to be where it is. Real continents have\n**plate boundaries**: mountains arc along convergent edges, rifts and\nmid-ocean ridges along divergent edges, transform faults run linear.\n\nThis objective adds a lo-fi tectonic prepass that runs in <500 ms on a\n200×200 map and biases the existing fBm field. Full multi-step plate\nsimulation (`g2-05-tectonics-lithology`) stays deferred to Game 2; this\nis the cheap version that captures 80% of the visual win.\n\nThe prepass also produces `mountain_proximity` and `coast_proximity`\nfields that p2-49 (rain shadow) and p1-47 (drainage divides) consume\nas first-class inputs."
|
||||
},
|
||||
{
|
||||
"id": "p1-51",
|
||||
"title": "Worldgen canonical design docs — author the spec before any Rust",
|
||||
"priority": "p1",
|
||||
"status": "missing",
|
||||
"scope": "game1",
|
||||
"owner": "terraformer",
|
||||
"updated_at": "2026-04-30",
|
||||
"summary": "The Terraformer bundle (`p1-46`…`p2-51`) is an 8-objective procedural\nterrain pipeline spanning tectonics, hydrology, climate, ecology, RNG\ndeterminism, world-shape presets, and the design-app Terrain Dimensions\nLab. Per **Rail 1** (`Rust is the simulation source of truth`,\nCLAUDE.md:13) and the project's three-tier doc system (canonical →\nengineering → JSON, per `.project/designs/README.md`), every Rust crate\nmust mechanically implement an authored canonical specification — never\nthe reverse.\n\nThis Wave-0 objective authors the **7 canonical design docs** at\n`public/games/age-of-dwarves/docs/terrain/` (and `…/docs/` for ecology\nbinding) that gate all subsequent Wave A–E implementation. Each Rust\ncrate's rustdoc references the canonical doc it implements; bridges\n(`api-gdext`, `api-wasm`) and consumers (Godot, design lab) consume\nwhat the canonical specs declare — not what someone interpolated.\n\nThe current TypeScript twins (`floraSpecies.ts`, `hydrology.ts`,\n`faunaSpecies.ts`) under `.project/designs/app/src/utils/worldGen/`\nexist precisely because this stage was skipped. Authoring the canonical\ndocs first prevents that recurrence."
|
||||
},
|
||||
{
|
||||
"id": "p2-06",
|
||||
"title": "Export pipeline for Windows / macOS / Linux",
|
||||
|
|
@ -1492,13 +1512,33 @@
|
|||
},
|
||||
{
|
||||
"id": "p2-49",
|
||||
"title": "Climate axes refactor — latitude + continentality as first-class per-hex inputs",
|
||||
"title": "Climate axes refactor — latitude + continentality + zonal winds as first-class per-hex inputs",
|
||||
"priority": "p2",
|
||||
"status": "missing",
|
||||
"scope": "game1",
|
||||
"owner": "terraformer",
|
||||
"updated_at": "2026-04-30",
|
||||
"summary": "`mc-mapgen::sampleCell` (and the design-lab twin in `terrain.ts:213`)\nderives `cold` from\n`abs(row/rows - 0.5) * 2 * (1 - climate)` — an implicit latitude proxy\nthat doesn't expose:\n\n- **Continentality** — distance from ocean, drives seasonal swing and\n base aridity (Siberia vs Ireland)\n- **Seasonality** — latitude amplitude (tropic vs arctic)\n- **Rain shadow** — windward / leeward of mountains (wet Pacific NW\n vs dry Great Basin)\n- **Elevation lapse rate** — ~6.5°C/km cooling\n\nThe classifier consumes the collapsed `cold` value, producing biomes\nthat don't differentiate maritime temperate from continental temperate,\nor windward rainforest from leeward rain shadow.\n\nThis objective decomposes the climate input into independent per-hex\nfields — `latitude`, `continentality`, `prevailing_wind_dir` — then\nderives mean T, mean P, seasonality, evapotranspiration deficit. The\nbiome classifier consumes the derived values, exposing\nmaritime / continental and rain-shadow distinctions at last."
|
||||
"summary": "`mc-mapgen::sampleCell` (and the design-lab twin in `terrain.ts:213`)\nderives `cold` from\n`abs(row/rows - 0.5) * 2 * (1 - climate)` — an implicit latitude proxy\nthat doesn't expose:\n\n- **Continentality** — graph distance from ocean, drives seasonal\n swing and base aridity (Siberia vs Ireland)\n- **Seasonality** — latitude amplitude (tropic vs arctic)\n- **Rain shadow** — windward / leeward of mountains (wet Pacific NW\n vs dry Great Basin)\n- **Elevation lapse rate** — ~6.5°C/km cooling\n- **West-coast asymmetry** — without ocean current simulation, mid-\n latitude west coasts must still feel maritime; east coasts must\n still feel continental.\n\nThe classifier consumes the collapsed `cold` value, producing biomes\nthat don't differentiate maritime temperate from continental temperate,\nor windward rainforest from leeward rain shadow.\n\nThis objective decomposes the climate input into independent per-hex\nfields — `latitude`, `continentality`, `wind_band` — then derives mean\nT, mean P, seasonality, evapotranspiration deficit. The biome\nclassifier consumes the derived values, exposing maritime / continental\nand rain-shadow distinctions at last."
|
||||
},
|
||||
{
|
||||
"id": "p2-50",
|
||||
"title": "Deterministic RNG + seed-derivation pin across mc-mapgen / mc-climate / mc-ecology",
|
||||
"priority": "p2",
|
||||
"status": "missing",
|
||||
"scope": "game1",
|
||||
"owner": "terraformer",
|
||||
"updated_at": "2026-04-30",
|
||||
"summary": "Every terraformer-owned objective claims \"deterministic from seed\", but\nno objective specifies (a) which RNG, (b) the seed-mixing function,\n(c) the version pin that survives `cargo update`. Today, the worldgen\npipeline calls `rand::thread_rng()` and `StdRng::seed_from_u64(seed)`\ninconsistently across crates. `StdRng` is explicitly documented as\n**not stable across rand versions** — saves break silently on dep\nbumps.\n\nThis objective pins a versioned RNG and a single seed-derivation\nfunction for all worldgen — tectonics, hydrology, climate, species\nselection. Lands as a small infrastructure objective so Wave A of the\nterraformer schedule (p1-50, p2-49) is built on a stable foundation,\nnot retrofitted later."
|
||||
},
|
||||
{
|
||||
"id": "p2-51",
|
||||
"title": "Player-facing world-shape parameters on new-game screen",
|
||||
"priority": "p2",
|
||||
"status": "missing",
|
||||
"scope": "game1",
|
||||
"owner": "terraformer",
|
||||
"updated_at": "2026-04-30",
|
||||
"summary": "The terraformer pipeline now exposes ~15 internal parameters\n(plate count, tectonic strength, fbm octaves, sea level, latitude\ngradient, continentality decay, rain-shadow factor, erosion\niterations, drainage threshold, etc.). Designers tune these in the\nforest lab; **players see none of them**. The new-game screen ships\n\"Map Size\" and not much else.\n\nIndustry baseline (Civ 6, Old World, Songs of Conquest) exposes 4–6\nhigh-level shape knobs. Each knob is a *preset* that derives several\ninternal parameters at once. This objective wires that surface from\nJSON presets through `mc-mapgen` parameters into the Godot game-setup\nscene."
|
||||
},
|
||||
{
|
||||
"id": "g2-01",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue