4.3 KiB
4.3 KiB
| id | title | priority | status | scope | owner | updated_at | wave | canonical_doc | coordinates_with | evidence | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| p1-48 | Flora species renderer — bind 149 species to world-map tile rendering (single source of truth) | p1 | done | game1 | terraformer | 2026-05-01 | C | public/games/age-of-dwarves/docs/ECOLOGY_BINDING.md |
|
|
Summary
public/resources/ecology/flora/species/*.json defines 149 species
with rich schema:
biomes[]— which terrain types support the speciestags[]including layer (layer_canopy/layer_understory/layer_ground/layer_fungal) and structure (structure_woody/conifer/broadleaf/evergreen)lineage— taxonomic group (conifers,broadleaf_trees,tropical_broadleaf,cacti,palms,aquatic_plants,mosses_lichens, etc.)quality_tier(0–10),canopy_contribution,undergrowth_contribution,fungi_contributiondrought_tolerance,fire_resistance,growth_rate
Wave C landed the Rust selector, WASM + GDExt bridges, and integration tests.
The visual-proof bullets (tooltip, lab integration) are Wave-E work — relocated
to p1-46. The TS twin (floraSpecies.ts) was deleted; Lab.tsx has
TODO(p1-46) markers where the WASM calls will be wired in.
Single source of truth (Rail 1): the selector is implemented ONCE
in mc-ecology (Rust), exposed to Godot via GDExtension and to the
design-lab via WASM. NO TypeScript twin.
Acceptance
- ✓ Species pool builder — module
src/simulator/crates/mc-ecology/src/flora_select.rsbuildsTerrainFloraIndexkeyed by(biome_id, T_band, P_band). Note: module path isflora_select.rs, notspecies.rs(which is reserved for the fauna Species struct). Objective path corrected per Wave-C doc-↔-code parity (Wave closing checklist §3). - ✓ Per-tile species selection — deterministic pick via
mc_mapgen::seed::derive(map_seed, SeedDomain::FloraSelect)mixed withtile_rng(domain_seed, col, row). Same tile yields same species set across loads. - ✓ Contribution normalisation rule — weights rescaled by dividing
by sum, never clipped. Implemented in
pick_flora_for_tile. - ✓ Riparian feedback — tiles with
riparian_distance <= 1receive 1.4× weight boost for aquatic/riparian species. Verified byflora_selection::riparian_species_appear_near_watertest. - ✓ Lineage → glyph mapping — documented in ECOLOGY_BINDING.md §5;
FloraSpec::layer()returnsFloraLayerenum carrying the layer tag. Glyph dispatch lives in the presentation shell as per spec. - ✓ Layer stratification —
pick_flora_for_tilesorts output: canopy → understory → ground → fungal. - ✓ WASM ↔ GDExt parity —
WasmFloraIndex(api-wasm) andGdFloraSelector(api-gdext) both callpick_flora_for_tilewith identical parameters. Both return{id, name, lineage, layer, quality_tier}per species. Parity is structural (same Rust function, same inputs → same outputs). - ✓ Determinism gate —
mc-ecology/tests/flora_selection.rs: 6 tests including determinism golden-vector (10 seeds × 5 biomes) pass. - ✓ Soil-layer acknowledgement — module rustdoc in
flora_select.rsdocuments g2-06 retrofit point. - ✓ Tooltip integration — world-map tile tooltip shows top-3 flora
species names per stratum (canopy / understory / ground), deduped and
sorted by
quality_tierdesc. Delegated to p1-46 (Wave E) and now landed:WasmFloraIndex.tileFloraJson()wired into Lab.tsx info card. Evidence:.project/designs/app/src/pages/WorldGen/Lab.tsx(centreFlora memo + EcoSection render).
Non-goals
- Per-species animation / sway — static icons only.
- Successional drift over turns — one-shot pick at map gen, not dynamic.
- Custom sprite assets per species — procedural canvas glyphs only.
- Soil/lithology-driven species filtering — defer to
g2-06. - TypeScript reimplementation of the selector — explicitly forbidden.
Dependencies
- p2-49 (climate axes) —
T_band,P_bandkeys depend on derived (T, P) being stable. - p1-47 (hydrology) —
riparian_distanceis consumed here. - p2-50 (RNG pin) — selection determinism.