# Next step — Fauna & Flora (derived carrying-capacity densities) > Status: **planned, not yet implemented.** This is the next World-Creation stage after > climate. Approved design captured here so it can be picked up verbatim (e.g. after the > project moves to another machine — the auto-memory does not travel, this doc does). ## Decision summary - **Derived carrying-capacity map**, not a live simulation: vegetation + wildlife **density scalars** recomputed each tick from the climate fields + terrain, exactly like biomes/climate. It answers *"what could live here"*, not *"what is living/evolving here"*. - The actual **time-evolving ecosystem** (population growth, migration, predator-prey, extinction, seasons, species) is reserved for the future **Live World** real-time mode (year/season timescales — not the My geological clock). - Fauna uses a **herbivore + carnivore** food-chain split. - Fields are **derived / not saved** (deterministic functions of climate) → **no save-format change**. New config knobs ride the v6 self-describing save with no break. ## Part A — Biosphere fields (`src/sim/`, raylib-free) - **`Planet.hpp`**: declare `void computeBiosphere();` + accessors `const std::vector& vegetation()/herbivores()/carnivores() const`. Add scratch members `std::vector sVeg, sHerb, sCarn;` (not saved). - **New `src/sim/PlanetBiosphere.cpp`** — `Planet::computeBiosphere()` (run *after* `computeClimate()`; reads `sTemp` + `sMoist`): - **Vegetation (flora)** `sVeg[i] ∈ [0,1]`: `0` on water (`elev ≤ seaLevel`). On land, an NPP-style **Liebig minimum** of a temperature factor and a moisture factor: - `tF = clamp((sTemp[i] − bioVegTempMin)/(bioVegTempOpt − bioVegTempMin), 0, 1)` - `mF = clamp(sMoist[i]/bioVegMoistRef, 0, 1)` - `sVeg = min(tF, mF)` → lush warm-wet, ~0 in ice/desert/alpine (cold- or water-limited), matching the biomes. - **Herbivores** `sHerb[i] = clamp(sVeg[i] · bioHerbProductivity, 0, 1)` (capacity scales with plant productivity). - **Carnivores** `sCarn[i]`: present only where prey is abundant, ramping with it: `sCarn = sHerb > bioCarnPreyMin ? clamp((sHerb − bioCarnPreyMin)/(1 − bioCarnPreyMin) · bioCarnScale, 0, 1) : 0` → concentrated in the richest regions (an energy-pyramid feel, visually distinct from the broader herbivore pattern). - **`src/sim/Planet.cpp` `generate()`**: call `computeBiosphere()` after `classifyBiomes()`. ## Part B — Config knobs (`PlanetTypes.hpp` + `PlanetIO.cpp`) Add to `PlanetConfig` + `CONFIG_FIELDS` + `validateConfig`: | key | default | meaning | |---|---|---| | `bioVegTempMin` | −5 °C | below this, no plant growth | | `bioVegTempOpt` | 15 °C | at/above this, temperature isn't limiting | | `bioVegMoistRef` | 0.5 | normalized moisture at which water isn't limiting | | `bioHerbProductivity` | 0.9 | herbivore capacity per unit vegetation | | `bioCarnPreyMin` | 0.30 | min herbivore density to support carnivores | | `bioCarnScale` | 1.0 | carnivore density ramp above the prey threshold | ## Part C — Rendering (`src/render/`) - **`Colors.{hpp,cpp}`**: `ColorMode` += `Vegetation`, `Herbivores`, `Carnivores`; add `vegColor` (barren tan → lush green), `herbColor` (pale → amber/orange), `carnColor` (pale → red/violet); extend `colorModeName`. - **`Viewer.cpp`**: `recolor()` adds the three cases (read the accessors, empty-guarded); `refreshView()` calls `planet.computeBiosphere()` after `classifyBiomes()`. - **`ViewerInput.cpp`**: `KEY_EIGHT` → Vegetation, `KEY_NINE` → Herbivores, `KEY_ZERO` → Carnivores (each `recolor()`). The top-center view-name label already shows the mode. - **`ViewerRender.cpp` `renderHUD`**: controls line gains `8 veg 9 herbiv 0 carniv`. - **`Panels.cpp` `cellInfo()`**: add a life line — `vegetation X% herbivores Y% carnivores Z%` (guarded on the arrays being sized). ## Verification (headless — extend the `src/sim` test set with `PlanetBiosphere.cpp`) - **Vegetation:** 0 on ocean & Ice cells; near-0 on Desert; high (>0.6) on warm-wet Forest; all in [0,1]; finite; deterministic. - **Fauna food chain:** `sHerb` correlates with `sVeg`; `sCarn[i] > 0 ⇒ sHerb[i] > bioCarnPreyMin` and carnivore-positive cells are a strict subset of herbivore-rich cells; all in [0,1]; deterministic. - `test_logic`, biomes+config, climate suites still pass; app builds clean; no save change. - **GUI:** `8` lush green continents thinning to barren in deserts/poles/peaks; `9` grazer density following productivity; `0` predators concentrated in the richest belts; cell info shows vegetation/herbivore/carnivore %. ## Out of scope (future / Live World) Time-evolving populations (growth, migration, predator-prey, extinction), seasons, and species/typed organisms — all part of the future **Live World** real-time simulation that runs the finished planet at hours/days/weeks/months with dynamic weather + life.