C++/raylib semi-realistic fantasy/sci-fi planet generator on a fixed icosphere grid (Eulerian: properties flow over fixed cells). World-creation stages: tectonics, continental drift & erosion, hydrology (rivers/lakes), climate (temperature + orographic precipitation), and biome classification. Engine in src/sim (raylib-free, headless-testable), viewer in src/render. See CLAUDE.md and docs/ (design-notes.md, fauna-flora-plan.md = next step). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4.9 KiB
4.9 KiB
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: declarevoid computeBiosphere();+ accessorsconst std::vector<double>& vegetation()/herbivores()/carnivores() const. Add scratch membersstd::vector<double> sVeg, sHerb, sCarn;(not saved).- New
src/sim/PlanetBiosphere.cpp—Planet::computeBiosphere()(run aftercomputeClimate(); readssTemp+sMoist):- Vegetation (flora)
sVeg[i] ∈ [0,1]:0on 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).
- Vegetation (flora)
src/sim/Planet.cppgenerate(): callcomputeBiosphere()afterclassifyBiomes().
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; addvegColor(barren tan → lush green),herbColor(pale → amber/orange),carnColor(pale → red/violet); extendcolorModeName.Viewer.cpp:recolor()adds the three cases (read the accessors, empty-guarded);refreshView()callsplanet.computeBiosphere()afterclassifyBiomes().ViewerInput.cpp:KEY_EIGHT→ Vegetation,KEY_NINE→ Herbivores,KEY_ZERO→ Carnivores (eachrecolor()). The top-center view-name label already shows the mode.ViewerRender.cpprenderHUD: controls line gains8 veg 9 herbiv 0 carniv.Panels.cppcellInfo(): 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:
sHerbcorrelates withsVeg;sCarn[i] > 0 ⇒ sHerb[i] > bioCarnPreyMinand 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:
8lush green continents thinning to barren in deserts/poles/peaks;9grazer density following productivity;0predators 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.