Two features (the ecoregions layer was authored locally and was still
uncommitted; civilization Step 2 builds on top and is intermingled in shared
files, so they land together):
Ecoregions (v19, PlanetEcoregions.*, key E):
- generateEcoregions() flood-fills cells sharing biome + land/water context +
productivity band into named ecological provinces (dominant flora/fauna/funga
+ per-kind productivity), a separate sEcoRng. ColorMode::Ecoregion + an Eco
tab + cell-info dominants. Saved v19 (v18 geography reshuffle salt already in).
Civilizations Step 2 (v20, PlanetCiv.*, keys U/I):
- computeHabitability(): derived per-cell food/livability (climate comfort +
water access (rivers/lakes/coast) + food (flora/fauna + ecoregion
productivity), gated by freezing winters / high terrain). ColorMode::
Habitability (key I).
- placeSettlements() (key U, "the dawn"): one-time greedy placement on the best
well-spaced fertile cells (separate sCivRng; named from the continent's
NameGen bank). The set is fixed, so the only mutable per-step state is each
settlement's population.
- stepCivilization(): logistic growth toward K = civMaxPopulation*habitability,
cut where an active volcano ashes the area, so settlements grow / decline /
are abandoned (floored at 1 so a site can revive). Tiers village->town->city.
Runs in liveAdvance; detectLiveEvents logs kind=3 events.
- Step-back snapshots only the population vector (WeatherSnapshot.settlementPop).
3D + 2D tier-sized markers + city/town labels, a Civ tab, cell-info line.
buildGeometry() clears settlements on reseed. Save v20; sCellSettlement
rebuilt on load. civ* config knobs.
New test_ecoregions.cpp + test_civ.cpp; all 10 headless suites pass; GUI build
clean. CLAUDE.md / design-notes / BUILD.md updated (roadmap Step 2 done).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Feedback fixes on the just-shipped atlas:
- Ocean basins: the connected world ocean was always one feature ("1 ocean",
unrealistic). Now generateGeography partitions it via a distance-from-land
watershed -- greedy farthest-first deep-water centres (geoOceanSepRadians apart,
>= geoOceanDeep rings from land) + multi-source BFS Voronoi over the ocean
graph. Each basin -> a named Ocean (or Sea if small). Defaults (sep 1.4 rad,
deep 4) give ~4-6 oceans on an Earth-like world, 1 on a waterworld. New geo*
knobs geoOceanSepRadians / geoOceanDeep.
- Shared names: features now dedupe on the PROPER-NOUN root (not the formatted
string), so a continent "Karn", a "Karn River" and "Karn Mountains" can't
coexist. NameGen also avoids identical adjacent syllables ("shio-shio").
- New islands: Planet::nameNewLand(cell) adds a volcanic island to the atlas on
the fly when it breaches the sea -- joins an adjacent landmass or mints a fresh
unique Island name; the island-formation WorldEvent now carries that name.
test_geography adds: proper-noun-root uniqueness, nameNewLand join vs mint.
All 8 headless suites pass; GUI build clean. Docs updated. (Save still v17 --
GeoFeature layout unchanged.)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The foundation of the civilization arc: name the world so everything civic
(territory, borders, place-of-origin) can reference it. This is pure derived
geometry + a deterministic namer, so it lives in the raylib-free engine and is
fully testable headless. No agents/clock yet -- those come in later steps.
- NameGen.{hpp,cpp} (new): deterministic procedural name generator (xorshift
syllable banks; bankForRegion gives each continent a "language" so its rivers/
mountains share a sound). Reused by the whole civ arc later.
- PlanetGeography.{hpp,cpp} (new): Planet::generateGeography() extracts named
features by connectivity over the fixed grid -- continents/islands (connected
land), oceans/seas (connected water), lakes (inland filled basins), mountain
ranges + peaks (connected high terrain), rivers (largest discharge mouths
traced upstream via flowTo). Separate RNG (sGeoRng) keeps tectonic determinism
intact; per-cell index arrays (sCellLand/Water/Range/River) give O(1) lookup.
- Save v17: geography block (feature records with names + per-cell region arrays)
appended in writeState/readState; readState gains hasGeography; pre-v17 saves
load with none (regenerated on M). geo* config knobs + validation.
- Render: key M toggles place-name labels on globe (manual projection) + 2D map
(minor features only when zoomed); a 5th "Atlas" live-info tab lists features
by kind (click a row -> focusCell); cell-info shows a "region" line. Generated
lazily on a settled world (M) or on entering Live World (W).
- test_geography.cpp (new, in CMake foreach): extraction, per-cell membership,
river-traces-to-sink, names unique/deterministic, RNG isolation, v17 round-trip.
All 8 headless suites pass; GUI build clean. Docs updated (CLAUDE/design-notes/
BUILD), incl. the multi-step civilization roadmap.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>