A second, reference-style export alongside exportMapImage(): renders at ~8K and labels every named geography feature and every living settlement (settlement names weren't drawn as text anywhere before this), using a greedy priority-based placement pass that only draws a label if its box doesn't collide with one already placed -- so text never overlaps regardless of how densely settlements cluster. Keeps label font size well below the resolution scale, since scaling text 1:1 with a bigger canvas would just reproduce the same crowding at a bigger size. Also uses the plain colour-mode vcolors rather than displayColors(), since in Live World the latter is day/night-dimmed -- a reference atlas should read the same everywhere, not have an arbitrary half of it darkened by whatever moment it was exported.
426 lines
28 KiB
Markdown
426 lines
28 KiB
Markdown
# Planet Sim - World Creation
|
|
|
|
Fixed icosphere geometry; properties (elevation, plate, age, climate, biome) flow
|
|
over it. World creation runs as continuous, overlapping stages on a geological clock:
|
|
tectonics (boundary stress forms mountains/trenches) → continental drift & erosion →
|
|
hydrology (rivers/lakes) → climate (temperature/precipitation) → biomes → biota
|
|
(flora/fauna/funga). Initial
|
|
terrain forming is a generator (a couple hundred paced ticks, ~3 s, auto-pauses at
|
|
equilibrium), then drift/erosion/etc. continue. Press R to reseed, SPACE to pause.
|
|
(The eventual goal is a separate slow real-time "Live World" weather/life mode.)
|
|
|
|
## Build (Nobara / Linux)
|
|
|
|
Dependencies (raylib build needs these dev headers):
|
|
|
|
sudo dnf install cmake gcc-c++ mesa-libGL-devel libX11-devel \
|
|
libXrandr-devel libXinerama-devel libXcursor-devel libXi-devel \
|
|
wayland-devel libxkbcommon-devel
|
|
|
|
Then:
|
|
|
|
cmake -B build -DCMAKE_BUILD_TYPE=Release
|
|
cmake --build build -j
|
|
./build/planetsim
|
|
|
|
raylib 5.5 is fetched automatically via CMake FetchContent.
|
|
|
|
OpenMP parallelizes the tectonic step (auto-detected by CMake; ships with
|
|
gcc, no extra package needed). It's optional -- without it the sim still runs,
|
|
serial. The step is memory-bandwidth-bound, so `OMP_NUM_THREADS=4` to `8` gives
|
|
the full ~2.8x speedup; the default uses all cores for no extra gain:
|
|
|
|
OMP_NUM_THREADS=6 ./build/planetsim
|
|
|
|
## Controls
|
|
|
|
LMB drag orbit camera (in the 3D view)
|
|
wheel zoom
|
|
hover show cell info (works in the 3D globe and the 2D map)
|
|
click open tile detail panel (subtiles grid, hoverable) + overlay
|
|
C close the detail panel
|
|
1 .. 7 color by elevation / plate / age / crust type / biome / temperature / precipitation
|
|
8 / 9 / 0 color by biota density: flora / fauna / funga
|
|
B toggle plate borders (on by default)
|
|
D toggle per-plate drift arrows + P<id> labels (on by default)
|
|
G toggle lat/lon graticule (+ degree numbers on the 2D map edges)
|
|
J toggle rivers (Phase 2.5 hydrology)
|
|
H start/stop Phase 2.5 (hydrology: rivers, lakes, fluvial erosion)
|
|
L generate biota population (flora/fauna/funga; settled world; re-press regenerates)
|
|
W enter / leave Live World (slow real-time clock; settled world)
|
|
N toggle the day/night terminator (Live World)
|
|
T toggle the tide-coloured coastline (Live World)
|
|
O toggle ocean-current arrows (warm = poleward/red, cold = equatorward/blue)
|
|
K toggle weather clouds/rain cover (Live World)
|
|
V toggle volcano markers (Live World; cones + eruption glow, build into islands)
|
|
M toggle place-name labels (names continents/oceans/ranges/rivers/lakes; Atlas tab)
|
|
E ecoregions colour view (names ecological provinces on first use; Eco tab)
|
|
I habitability heat map (where civilization can thrive)
|
|
U settlements: the dawn of civilization on first press, then toggle markers (Civ tab)
|
|
P territory / realms view + borders + war fronts + alliance/rivalry arcs (Realms tab)
|
|
X culture / faiths view + cultural borders (peoples/ethos/religion in the Cultures tab)
|
|
Z wealth / trade view + trade routes (sea/river/overland; prosperity feeds city growth)
|
|
Y follow-cam: cycle the 3D camera through active storms (Live World; off after last)
|
|
. / , step the live clock forward / back by one rate-unit (auto-pauses; back also
|
|
rewinds weather + storms via an undo history)
|
|
wheel over the 2D map: zoom toward cursor (1-8x); drag pans when zoomed
|
|
SPACE pause while forming / re-evolve once settled (or the on-screen button)
|
|
[ / ] drift speed (My/s) -- in Live World: live clock rate (hours/s -> up to ~20 years/s)
|
|
S single tectonic tick (in Live World: step the clock forward, like '.')
|
|
F fast-forward Phase-1 forming to settled (instant)
|
|
R reseed planet (restart forming)
|
|
+ / - subdivision level (detail), 1..7
|
|
F5 / F9 save / load full state (planet.save)
|
|
F12 screenshot to screenshot.png
|
|
F11 export the 2D map as a high-resolution (~4K) PNG (also a toolbar button)
|
|
Shift+F11 export a labeled atlas (~8K, every place/settlement name, no overlap; toolbar button)
|
|
F2 reload planet.cfg (validated) and regenerate
|
|
F1 toggle the clickable toolbar menu (top-right of the 3D globe; a button/
|
|
checkbox/dropdown for every key above, built with raygui)
|
|
|
|
CLI flags (applied before the first load/generate):
|
|
|
|
--seed N override the config seed
|
|
--config PATH use an alternate config file instead of planet.cfg
|
|
|
|
## Files (written in the working directory)
|
|
|
|
planet.cfg human-editable key=value config of every PlanetConfig parameter;
|
|
auto-created on first run, reload live with F2. Range-checked on
|
|
load; an invalid file reverts to safe defaults (not overwritten).
|
|
planet.save binary snapshot (versioned, currently v22: +diplomacy; v21
|
|
+conflict/wars; v20 +settlements; v19 +ecoregions; v18
|
|
+geography salt; v17 +geography/atlas; v16 +event log; v15
|
|
+stateful volcanoes; v13 +Live World clock rate; v12
|
|
+step-back history (~40 frames, so a load can rewind storms);
|
|
v11 +weather systems/storms; v10 +weather fields; v9 +moons;
|
|
v8 +Live World clock; v7 +biota): seed + config + full planet state; F5
|
|
writes it, F9 reloads and resumes deterministically. As of v6
|
|
the config is stored as a self-describing key=value block (like
|
|
planet.cfg), so adding/removing config fields no longer breaks saves
|
|
(unknown keys ignored, missing keys default). v6 cannot load pre-v6
|
|
saves (one-time break) -- regenerate them.
|
|
|
|
## Config (planet.cfg, or PlanetConfig defaults in code)
|
|
|
|
radius 6.371e6 m (Earth) -- free to change
|
|
subdivisions 5 (~10k cells, ~223 km/cell)
|
|
plateCount 12
|
|
seaLevel 0 m
|
|
axialTilt 23.44 deg obliquity: leans the 3D globe + spin axis (visual; seasons later)
|
|
|
|
Tectonic tuning (also PlanetConfig): relief builds gradually toward an
|
|
isostatic equilibrium instead of saturating to the clamp.
|
|
|
|
continentBase 300 m resting elevation of continental crust
|
|
oceanBase -6000 m deep abyssal floor (oldest oceanic crust)
|
|
upliftGain 1.3e5 m/tick per unit convergence stress
|
|
beltWidth 3 cell-rings a mountain belt spreads inland
|
|
relax 0.02 isostatic relaxation toward base, per tick
|
|
|
|
Orogeny + seafloor (PlanetConfig): tall, persistent mountains and age-based
|
|
ocean depth. The orogeny boosts (collision/arc/persistence) are drift-only --
|
|
Phase 1 forms as before; tall mountains grow during Phase-2 drift.
|
|
|
|
collisionFactor 1.8 continent-continent uplift (Himalaya); raise = taller
|
|
arcFactor 1.4 continental subduction-arc uplift (Andes)
|
|
isostaticPersist 0.85 how strongly high crust resists relax (0..<1)
|
|
rootScale 2500 m above continentBase where persistence saturates
|
|
peakSoftCapStart 7000 m below this a tick's uplift always takes (P=1)
|
|
peakSoftCapEnd 12000 m at/above this uplift never takes (P=0); also the elev clamp
|
|
peakFailDrop 200 m max random drop when the grow roll loses (drift-only)
|
|
ridgeDepth -2500 m shallow elevation of brand-new crust at a ridge
|
|
seafloorSubsidence 280 m per sqrt(My): seafloor deepens with crustal age
|
|
seafloorSeedAge 80 My initial oceanic age spread at generation
|
|
|
|
Hydrology (PlanetConfig, Phase 2.5): macro drainage network + fluvial erosion.
|
|
Drift keeps running at a finer timestep during hydrology. (Config keys keep the
|
|
`phase3*` names for save/cfg compatibility; the UI labels this "Phase 2.5".)
|
|
|
|
phase3AfterMy 300 My drift before the "Start Phase 2.5?" prompt
|
|
phase3DtScale 0.2 hydrology timestep = cflDtMy()*this (finer = slower drift)
|
|
rainfall 1.0 uniform precip per cell (drainage-area unit)
|
|
riverThreshold 25 discharge above which a cell is a river (lower = richer network)
|
|
riverIncision 0.02 K in stream-power incision K*Q^m*S^n*dt (raise = carve faster)
|
|
riverDischargeExp 0.5 m (discharge exponent)
|
|
riverSlopeExp 1.0 n (slope exponent)
|
|
riverTransport 0.1 transport capacity coefficient (cap = this*Q*S)
|
|
depFrac 0.25 fraction of excess sediment deposited per cell
|
|
|
|
Biomes (PlanetConfig, Phase 3): per-cell biome classification thresholds. Temperature
|
|
= biomeEquatorTemp - biomePoleDrop*(|lat|/90)^biomeLatExp - biomeElevLapse*elevAbove.
|
|
|
|
biomeEquatorTemp 30 C temperature at the equator, sea level
|
|
biomePoleDrop 58 C equator->pole temperature drop
|
|
biomeLatExp 1.3 >1 keeps mid-latitudes temperate (cold concentrates at poles)
|
|
biomeElevLapse 0.006 C lost per metre above sea level
|
|
biomeIceTemp -9.5 C below -> Ice (polar caps + snowcaps); raise = bigger caps
|
|
biomeTundraTemp 2 C below (and above ice) -> Tundra/Taiga
|
|
biomeTaigaTemp 10 C cool + wet -> boreal forest
|
|
biomeSavannaTemp 22 C warm + moderate moisture -> savanna
|
|
biomeMountainElev 3000 m above sea level -> Mountains
|
|
biomeHillsElev 1200 m above sea level -> Hills
|
|
biomeBeachBand 60 m above sea level + adjacent ocean -> Beach
|
|
biomeLowlandElev 500 m wetlands only below this elevation
|
|
biomeWetlandMoist 0.72 moisture above this (low lowland) -> Wetland
|
|
biomeDesertMoist 0.28 moisture below this -> Desert
|
|
biomeGrassMoist 0.50 moisture below this -> Grassland/Savanna, else Forest
|
|
biomeTaigaMoist 0.40 cool + above this -> Taiga (else Tundra)
|
|
biomeLakeMinDepth 20 m filled-basin depth above sea level counting as a Lake
|
|
biomeSeasonWeight 0.6 winter temp weight in the Tundra/Taiga cutoffs (0 = annual mean only)
|
|
|
|
Seasons (PlanetConfig): axialTilt (above) drives per-cell summer/winter temps; color key 6
|
|
cycles temperature -> summer -> winter -> seasonality.
|
|
|
|
seasonAmpMax 18 C max seasonal half-range at full tilt/latitude/interior
|
|
seasonLatExp 1.2 latitude shape exponent (>1 pushes swing toward the poles)
|
|
seasonOceanFactor 0.15 ocean/coast seasonal-swing floor (thermal inertia)
|
|
seasonContinentRings 6 ocean-distance rings to reach full continentality (1 ~ 223 km)
|
|
|
|
Climate (PlanetConfig, Phase 3): temperature uses the biome* temp params above;
|
|
precipitation advects ocean moisture along zonal winds (windward rain, leeward rain
|
|
shadow, dry interiors) then diffuses it. Color modes 6 (temperature) / 7 (precipitation).
|
|
|
|
climateOceanMoisture 1.0 moisture air carries leaving the ocean (source)
|
|
climateRainEfficiency 0.5 fraction of available moisture*belt that rains per cell
|
|
climateOrographic 3.0 extra rain per unit normalized upslope (windward)
|
|
climateOroRefHeight 500 m upslope that counts as one orographic unit
|
|
climateContinentality 0.05 fractional moisture lost per inland cell (dries interiors)
|
|
climateWindPasses 50 moisture-advection iterations (steady state)
|
|
climateMoistureSmooth 12 precipitation diffusion passes (raise = smoother, more grass/forest)
|
|
climateCurrentFactor 4 C max coastal warming/cooling from ocean currents (0 = off; O shows arrows)
|
|
|
|
Biota (PlanetConfig): flora/fauna/funga. Density scalars drive color modes 8/9/0;
|
|
the discrete slot/point population is generated on demand (L) and saved (v7).
|
|
|
|
bioVegTempMin -5 C below this no plant growth
|
|
bioVegTempOpt 15 C at/above this temperature isn't limiting (flora)
|
|
bioVegMoistRef 0.5 normalized moisture where water isn't limiting (flora)
|
|
bioFaunaProductivity 0.9 herbivore carrying capacity per unit vegetation
|
|
bioCarnPreyMin 0.30 min local prey (fauna density) to support carnivores
|
|
bioCarnScale 1.0 carnivore weight ramp above the prey threshold
|
|
bioFungaMoistRef 0.4 normalized moisture where fungi aren't water-limited
|
|
bioFungaFloraWeight 0.6 how much fungi lean on flora (organic matter), 0..1
|
|
bioFungaTempMin -15 C above this fungi are not cold-limited (cold-tolerant)
|
|
bioRegionBonus 0.5 weight boost for archetypes present in same-biome neighbours
|
|
bioFloraSlots 12 max distinct flora per cell (point budget caps abundance)
|
|
bioFaunaSlots 10 max distinct fauna per cell
|
|
bioFungaSlots 8 max distinct funga per cell
|
|
bioFloraPoints 20 flora point budget at full density (scaled by density)
|
|
bioFaunaPoints 16 fauna point budget at full density
|
|
bioFungaPoints 14 funga point budget at full density
|
|
|
|
Live World (PlanetConfig): the slow real-time clock (hours -> weeks/months) over the
|
|
finished planet -- a moving day/night terminator, a live seasonal temperature cycle and a
|
|
moving snow line. axialTilt (above) drives the seasonal declination. Press W to enter.
|
|
|
|
dayLengthHours 24 hours in one planetary day (rotation -> day/night)
|
|
yearLengthDays 365.25 days in one planetary year (orbit -> seasons)
|
|
snowTemp 0 C land below the live temperature shows snow
|
|
seaIceTemp -2 C ocean below the live temperature shows sea ice
|
|
tideAmplitude 0.6 m equilibrium-tide scale per unit tide-raising weight
|
|
tideSunFactor 0.46 sun's tide weight relative to a unit moon (Earth ~0.46)
|
|
|
|
Moons (1-3, randomized in generateMoons() + saved v9): orbit on the live clock, raise the
|
|
tides with the sun, and render as small lit spheres with phases, orbit rings and eclipses.
|
|
|
|
Weather (PlanetConfig, Live World): a dynamic clouds/rain cycle on the live clock (key K),
|
|
saved v10. Evaporate over warm seas -> advect along the wind -> condense -> rain -> dissipate.
|
|
|
|
weatherEvapRate 0.4 /h ocean evaporation toward marine saturation
|
|
weatherWindKmh 45 km/h wind speed advecting humidity/cloud
|
|
weatherSatBase 0.4 air saturation at 0 C (lower = cloudier)
|
|
weatherSatTempCoef 0.025 saturation rise per +1 C
|
|
weatherCondense 0.6 /h supersaturation -> cloud
|
|
weatherOrographic 0.0009 extra condensation per m of windward upslope
|
|
weatherRainThresh 0.5 cloud cover above this rains
|
|
weatherRainRate 0.5 /h rain rate from excess cloud
|
|
weatherCloudDissip 0.12 /h cloud clearing
|
|
weatherSystemMax 8 max concurrent moving weather systems
|
|
weatherSpawnRate 0.06 /h genesis probability scale
|
|
weatherSystemSpeed 28 km/h drift speed of systems
|
|
weatherTropicalSST 26 C min sea-surface temp for tropical genesis
|
|
weatherSystemRadius 0.16 rad angular radius of a system's cloud/rain shield
|
|
weatherSystemCloud 1.2 /h cloud stamped at a system core
|
|
weatherSystemRain 1.6 /h rain at a system core
|
|
weatherHurricaneStr 0.6 strength above which a tropical system is a hurricane/typhoon
|
|
|
|
Live info tabs (Live World): the panel beside the 2D map has Sky, Tides, Weather and Events.
|
|
Events are a saved, capped journal (newest 200) for storm genesis/intensification, volcano
|
|
dormancy, eruptions and volcanic-island breaches; clicking an event selects and centres its cell.
|
|
|
|
Volcanoes (PlanetConfig, Live World, key V): placed by tectonic context on entering Live World,
|
|
then integrated as stateful lifecycle agents: grow, go dormant, explode, puff ash, and regrow
|
|
weaker. Step-back snapshots include volcano state. Saved v15+.
|
|
|
|
volcanoProbRidge 0.55 per-cell placement prob on a young spreading-ridge cell
|
|
volcanoProbBorder 0.06 per-cell placement prob on a normal plate-border cell
|
|
volcanoProbInterior 0.003 per-cell placement prob elsewhere (hotspots)
|
|
volcanoMaxCount 60 global cap (reservoir-sampled, ratios preserved)
|
|
volcanoBuildRate 0.02 m/h of growth at activity=1 while growing
|
|
volcanoFreeHeight 1000 m absolute height below which vents cannot go dormant
|
|
volcanoInitialBuildMax 2500 m max pre-built height when Live World starts
|
|
volcanoMaxHeight 3200 m built height where dormancy becomes certain
|
|
volcanoDormancyRate 1.0 per-year dormancy hazard scale above free height
|
|
volcanoDormantMinYears 120 minimum dormancy before explosion
|
|
volcanoDormantMaxYears 1200 maximum dormancy before explosion
|
|
volcanoExplodeDropFrac 0.20 fraction of built height shaved by explosion
|
|
volcanoActivityDecay 0.70 activity multiplier after each explosion
|
|
volcanoDeadActivity 0.05 growth stops at/below this activity
|
|
volcanoBlastRadius 0.09 radian radius of the instant explosion ash blast
|
|
volcanoBlastCloud 1.5 cloud cover added inside the blast
|
|
volcanoAshMinYears 0.5 minimum sustained ash emission after explosion
|
|
volcanoAshMaxYears 3.0 maximum sustained ash emission after explosion
|
|
volcanoAshPuffCellsPerWeek 2.0 average local cells puffed per week
|
|
volcanoAshCloud 0.9 cloud cover injected by sustained ash
|
|
volcanoAshCooling 6 C peak local cooling under an active ash plume
|
|
|
|
Geography / atlas (PlanetConfig, key M): extract + name geographic features from the frozen
|
|
terrain (continents, islands, oceans, seas, lakes, mountain ranges, peaks, rivers). Generated
|
|
once on a settled world, saved v17. The foundation of the civilization arc.
|
|
|
|
geoContinentMinCells 40 land component >= this many cells = Continent (else Island)
|
|
geoSeaMaxCells 60 ocean basin <= this many cells = Sea (else Ocean)
|
|
geoOceanSepRadians 1.4 min angular gap between ocean-basin centres (higher = fewer oceans)
|
|
geoOceanDeep 4 min rings from land for a cell to seed an ocean basin
|
|
geoMountainElev 2500 m min elevation for a mountain-range cell
|
|
geoRangeMinCells 4 min cells for a named mountain range
|
|
geoRiverMinDischarge 80 min mouth discharge for a named river
|
|
geoMaxRivers 40 cap on named rivers (largest by discharge)
|
|
geoMaxPeaks 40 cap on named peaks (highest)
|
|
|
|
Civilization (PlanetConfig, key U): settlements placed once on the best fertile cells, then their
|
|
population grows/declines on the Live World clock toward a food-driven carrying capacity. Saved v20.
|
|
|
|
civMaxSettlements 80 cap on settlement sites
|
|
civMinSpacingRadians 0.06 soft suppression scale around each pick (lower = tighter clusters)
|
|
civClusterExp 3.0 habitability weighting for placement (higher = clusters on the best land)
|
|
civMinHabitability 0.22 don't place a settlement below this habitability
|
|
civSeedPopulation 250 initial village population
|
|
civGrowthRate 0.02 logistic growth rate per year
|
|
civMaxPopulation 2e6 carrying capacity at habitability 1
|
|
civTownPop 5000 population at/above which a settlement is a Town
|
|
civCityPop 100000 population at/above which a settlement is a City
|
|
civAbandonPop 50 below this = abandoned/ruins (can revive)
|
|
civHabWaterWeight 0.45 habitability weight of water access (rivers/lakes/coast)
|
|
civHabFoodWeight 0.40 habitability weight of food (flora/fauna + ecoregion productivity)
|
|
civHabTempOpt 18 C most comfortable annual-mean temperature
|
|
civHabElevPenalty 2500 m high terrain steeply penalised above this
|
|
civSiteVariety 1.0 0 = flat city sizes; higher = big rivers/coasts host far larger cities
|
|
civGrowthMin 0.25 growth-rate floor at habitability 0 (rate scales with habitability)
|
|
civHarvestVar 0.25 year-to-year harvest swing (scaled by continentality)
|
|
civDroughtStrength 0.70 how hard a full drought cuts a region's carrying capacity
|
|
civDroughtPeriod 8 yr drought-noise epoch length (drought duration scale)
|
|
civDroughtThresh -0.15 drought-onset threshold (lower = rarer)
|
|
civDroughtArid 0.50 extra drought-proneness in arid regions
|
|
civColdYearStrength 0.50 crop loss in a rare cold year, x the cell's cold exposure
|
|
civFloodBonus 0.25 fertile-silt bonus on river cells (rare flood disaster)
|
|
civFamineRate 0.15 /yr accelerated population loss when food < population
|
|
civStormDeathRate 0.50 /yr deaths from a full-strength storm over a settlement
|
|
civHurricaneDeathMult 3.0 extra storm-death multiplier for a hurricane/typhoon
|
|
|
|
Territory & nations (PlanetConfig, key P — derived from settlements, not saved): each settlement
|
|
projects a size-scaled influence range; nearby smaller towns become vassals of a larger capital
|
|
(a kingdom/empire), the rest are city-states; land cells inside a settlement's reach are its
|
|
territory, leaving wilderness frontiers between realms.
|
|
|
|
civTerritoryBase 0.035 rad base influence radius of any settlement
|
|
civTerritoryScale 0.05 rad extra reach per log10 of population (big cities reach far)
|
|
civTerritoryMax 0.35 rad cap on a single settlement's reach
|
|
civVassalRange 1.5 x a capital's range = how far it annexes towns into its realm
|
|
civEmpireMinMembers 5 settlements in a realm to count as an empire
|
|
civEmpirePop 5e6 total realm population to count as an empire
|
|
|
|
Conflict & war (PlanetConfig, save v21 — stateful; shows on the Territory view P + Events/Realms tabs):
|
|
neighbouring realms grow hostile and fight; casualties shrink frontier cities; the winner conquers a
|
|
city (its allegiance flips) or sacks it (ruins); conquered foreign/distant cities revolt, so empires
|
|
rise and fall. Runs on the yearly Live-World tick.
|
|
|
|
warMaxConcurrent 6 cap on simultaneous active wars
|
|
warDeclareRate 0.12 war-declaration chance scale (x hostility)
|
|
warAmbition 1.0 hostility weight of the size gap (strong preys on weak)
|
|
warIdeology 0.8 hostility weight of culture + faith difference
|
|
warBorder 0.5 hostility weight of contested frontier
|
|
warWarlikeMult 1.4 military-strength bonus for a Warlike-ethos realm
|
|
warCasualtyRate 0.06 per war-year frontier-city population loss (loser more)
|
|
warConquerScore 0.6 |warscore| past which the winner takes a city
|
|
warSackChance 0.3 chance a taken city is razed to ruins instead of flipped
|
|
warExhaustion 1.5 |warscore| past which a war ends in peace (also a 60-yr cap)
|
|
warRevoltRate 0.04 per-year base revolt chance of a held foreign/distant city
|
|
warMinRealmPop 2000 realms below this population don't start wars
|
|
|
|
Diplomacy (PlanetConfig, save v22 — on the Territory view P): realm-pair attitudes drift into alliances /
|
|
rivalries; allies never fight + join each other's wars (coalitions); wars end in truces. Runs in the same
|
|
yearly stepConflict tick; green arcs = alliances, dark-red arcs = rivalries.
|
|
|
|
diploDriftRate 0.06 per-year attitude change scale
|
|
diploAffinity 1.0 attitude pull from shared culture + faith (vs difference)
|
|
diploWarPenalty 0.5 extra per-year attitude drop while two realms are at war
|
|
diploTruceYears 12 post-war truce length (no new war between the two)
|
|
diploWarGrudge 0.4 one-off attitude drop when a war between them ends (a scar)
|
|
diploAllyThreshold 0.5 attitude at/above which two realms are allied
|
|
diploNonAggThreshold 0.2 attitude at/above which they sign a non-aggression pact
|
|
diploRivalThreshold -0.5 attitude at/below which they become rivals
|
|
|
|
Trade & economy (PlanetConfig, key Z — derived, not saved): trade routes link nearby settlements (sea /
|
|
river / overland); prosperity accrues at hubs and boosts population growth; trade feeds diplomacy + war
|
|
motivation. Recomputed each sim year; sea cyan / land+river amber routes + a gold wealth heat map.
|
|
|
|
tradeLandRange 0.10 rad overland trade reach
|
|
tradeSeaRange 0.30 rad extra reach when both settlements are coastal (sea route)
|
|
tradeRiverBonus 0.06 rad reach bonus when either settlement sits on a river
|
|
tradeMinVolume 0.05 links below this volume are dropped
|
|
tradeProsperityWeight 0.8 how much a hub's prosperity multiplies its carrying capacity
|
|
tradeWarBlock 0.0 trade-volume factor between realms at war (0 = blockade)
|
|
tradeAllyBonus 1.5 trade-volume factor between allied realms
|
|
tradeDiploBonus 0.1 attitude nudge/yr between trade-partner realms (reward alliance)
|
|
tradeTemptWar 0.3 war-hostility weight of a wealthy weak target (tempt war)
|
|
|
|
Colonization (PlanetConfig, derived, no save bump): once per sim year a kingdom+ realm founds a new
|
|
settlement on good unclaimed land -- overland, or across water from a coastal member (islands). Colonies
|
|
are bound to the founder by allegiance + a colonial supply trade link, surviving while the founder lives.
|
|
|
|
civColonizeRate 0.15 per-eligible-realm per-year chance to found a colony
|
|
civColonyMinPop 2e5 a realm must reach this total population to colonize (kingdoms+)
|
|
civColonyMinHab 0.30 minimum habitability of a colony site
|
|
civColonyReach 0.12 rad overland colonization reach from a realm settlement
|
|
civColonySeaReach 0.35 rad extra reach over water from a coastal member (islands / abroad)
|
|
civColonySpacing 0.05 rad a colony must be at least this far from every settlement
|
|
civMaxColonies 120 cap on colonies founded beyond civMaxSettlements
|
|
civColonySupply 2.0 prosperity from the overlord supply link (keeps colonies alive)
|
|
|
|
Culture, beliefs & governments (key X — derived from settlements + geography, not saved): settlements
|
|
on a continent share a culture (a people with an environment-driven ethos + a religion); each realm
|
|
gets a government type folded into its name (Republic of X / Duchy of X / X Theocracy / ...); realms
|
|
stay mono-cultural. No config knobs — the ethos/faith/government rules are constants in
|
|
src/sim/PlanetCulture.cpp (computeCultures).
|
|
|
|
## Headless logic test (no display)
|
|
|
|
g++ -std=c++17 -O2 -Isrc/sim test_logic.cpp src/sim/IcoSphere.cpp \
|
|
src/sim/Planet.cpp src/sim/PlanetTectonics.cpp src/sim/PlanetDrift.cpp \
|
|
src/sim/PlanetErosion.cpp src/sim/PlanetHydrology.cpp \
|
|
src/sim/PlanetBiomes.cpp src/sim/PlanetClimate.cpp src/sim/PlanetLive.cpp \
|
|
src/sim/PlanetOcean.cpp src/sim/PlanetWeather.cpp src/sim/PlanetVolcano.cpp \
|
|
src/sim/PlanetBiota.cpp \
|
|
src/sim/PlanetFloraGen.cpp src/sim/PlanetFaunaGen.cpp src/sim/PlanetFungiGen.cpp \
|
|
src/sim/NameGen.cpp src/sim/PlanetGeography.cpp src/sim/PlanetEcoregions.cpp \
|
|
src/sim/PlanetCiv.cpp src/sim/PlanetNation.cpp src/sim/PlanetCulture.cpp src/sim/PlanetConflict.cpp src/sim/PlanetTrade.cpp \
|
|
src/sim/PlanetIO.cpp -o /tmp/t && /tmp/t
|
|
|
|
# Same source list for every suite: swap test_logic.cpp -> test_biota / test_live / test_ocean /
|
|
# test_weather / test_volcano / test_geography / test_ecoregions / test_civ / test_nation / test_culture / test_conflict / test_diplomacy / test_trade / test_colony.
|
|
# The CMake build also includes test_events for the viewer event journal.
|
|
|
|
Verifies geometry, plate assignment, gradual non-saturating relief and
|
|
determinism. Run after changing Planet::step().
|
|
|
|
## Notes for later phases
|
|
|
|
- Cell has a `subgrid` shared_ptr hook (null in phase 1) for the future
|
|
fine-resolution per-cell mesh (phases 4/5: civilization/culture).
|
|
- `neighbors` adjacency already built -> reuse for diffusion, climate,
|
|
cross-cell-boundary interaction.
|
|
- elevation is continuous meters (double); climate in phase 3 can read it
|
|
as a smooth function, not coarse bands.
|