Stack review (Hoshe + Tyre) of T-1083+T-1082+T-1080. Every finding fixed or disposed: - believability.rs sample_indices: replace the rejection-sampling loop (could stall when n ≈ take) with deterministic partial Fisher-Yates — O(n), guaranteed termination, distinct, sorted (Hoshe+Tyre). - believability.rs drainage proxy: exclude water-body districts (all elev 0, no banks) and require both wet + dry voxels — they were passing vacuously and inflating the metric (Hoshe). - believability.rs read_cities: log skipped malformed rows instead of dropping silently (Hoshe). - voxel.rs: add the 3 WaterBody zones to all_families_no_panic_at_extreme_positions + fix the "7 families" comment (Hoshe). - climate_constants.toml: bold warning that [moisture_gradient] is not loaded until T-1032 — tune ClimateConstants::default() (Tyre). - Q-123: record the per-zone "water renders wet" threshold + the land-relative vegetation-present denominator as calibration items (Tyre + the open 7th criterion). - T-1083 ticket: note the sampling-fix attribution (landed in the T-1082 commit). Believability golden regenerated (sampler + drainage fixes moved the metrics). clippy --all-targets -D warnings clean; 1580 lib tests + harness pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
104 lines
5.2 KiB
TOML
104 lines
5.2 KiB
TOML
# Climate constants for district temperature derivation (T-1024, D-239 §2, D-240).
|
||
#
|
||
# Source-canonical — loaded by the Rust simulation at runtime.
|
||
# Changing these constants does NOT require a DB migration (runtime file, not DB).
|
||
# To tune: edit here, rerun the server, inspect Atlas temperature maps.
|
||
#
|
||
# Three tables are required:
|
||
# [planet_class_temperature] — per-class [cold_end, warm_end] °C band (D-240).
|
||
# [greenhouse_offset_c] — mean-annual base temperature offset by atmosphere class.
|
||
# [diurnal_amplitude_c] — day/night swing AMPLITUDE by atmosphere class.
|
||
#
|
||
# Temperature derivation formula (D-240):
|
||
# (cold, warm) = planet_class_temperature[planet_class] # envelope
|
||
# t_lat = warm - (warm - cold) * (|latitude_deg| / 90) # latitude lerp
|
||
# greenhouse modulates within the band
|
||
# elevation lapse pulls toward cold end
|
||
# seed nudge ±~3°C
|
||
# CLAMP to [cold, warm] — body can never derive outside its class band.
|
||
#
|
||
# No atmosphere → temperature_c = None (airless body; D-227).
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Planet class temperature envelopes (D-240).
|
||
# Each entry: [cold_end_c, warm_end_c] — the band a body of this class stays in.
|
||
# Prefix rules: "cold_*" shifts both ends ~10°C colder; "hot_*" ~10°C warmer;
|
||
# "warm_*" ~5°C warmer. Unknown class falls back to "temperate" band.
|
||
# ---------------------------------------------------------------------------
|
||
[planet_class_temperature]
|
||
frozen = [-90.0, -25.0]
|
||
ice = [-90.0, -25.0]
|
||
boreal = [-35.0, 12.0]
|
||
cold_arid = [-40.0, 20.0]
|
||
temperate = [-12.0, 28.0]
|
||
oceanic = [-12.0, 28.0]
|
||
subtropical = [ 2.0, 34.0]
|
||
warm_ocean = [ 2.0, 34.0]
|
||
tropical = [ 16.0, 40.0]
|
||
arid = [ -5.0, 45.0]
|
||
hot_arid = [ 20.0, 58.0]
|
||
volcanic = [ 30.0, 90.0]
|
||
geothermal = [ 30.0, 90.0]
|
||
|
||
[greenhouse_offset_c]
|
||
# Greenhouse warming contribution per atmosphere class — used as a fractional
|
||
# nudge toward the warm end of the class band, not an absolute Kelvin offset.
|
||
# "none" is not present — airless bodies skip the climate branch entirely (D-227).
|
||
# Values represent a 0.0–1.0 fraction of the band width to add toward warm end.
|
||
# thin=0.1 (slightly warmer), breathable/standard=0.25, toxic=0.25, dense=0.55
|
||
thin = 0.10
|
||
standard = 0.25
|
||
toxic = 0.25
|
||
breathable = 0.25
|
||
dense = 0.55
|
||
|
||
[diurnal_amplitude_c]
|
||
# Day/night swing amplitude (°C). The actual swing is ±amplitude around the
|
||
# mean temperature; the morning minimum is T_mean - amplitude, noon maximum is
|
||
# T_mean + amplitude. Thick/dense atmosphere = small swing (heat redistribution);
|
||
# thin/no atmosphere = large swing.
|
||
#
|
||
# "none" is excluded — airless bodies have no climate temperature (D-227).
|
||
# Values are plausible physics; tune without recompile by editing this file.
|
||
thin = 50 # ~50°C day/night swing: large, like Mars
|
||
standard = 15 # ~15°C: Earth-like moderate swing
|
||
toxic = 20 # intermediate: thick but maybe less redistribution
|
||
breathable = 15 # synonym for standard
|
||
dense = 3 # ~3°C: Venus-like near-uniform temperature
|
||
|
||
# ---------------------------------------------------------------------------
|
||
[hydrosphere_maritime]
|
||
# Maritime moderation (D-240): scales the equator→pole temperature gradient by
|
||
# hydrosphere. 1.0 = full gradient (dry world swings the whole class band);
|
||
# < 1.0 compresses toward the band midpoint (water-rich worlds are milder at
|
||
# both poles and equator). Keys = actual bodies.hydrosphere vocabulary in
|
||
# systems.db. "minimal"/"trace"/"none"/absent default to 1.0 in code.
|
||
liquid_water = 0.6 # large surface liquid — strongly moderated
|
||
ocean = 0.6
|
||
"ocean-coastal" = 0.6
|
||
extensive = 0.6
|
||
rivers = 0.8 # partial surface water — mild moderation
|
||
"rivers-lakes" = 0.8
|
||
moderate = 0.8
|
||
ice = 0.85 # frozen surface — slight moderation
|
||
subsurface_liquid = 0.9
|
||
subsurface = 0.95 # buried water — minimal surface effect
|
||
subsurface_ice = 0.95
|
||
|
||
# ---------------------------------------------------------------------------
|
||
[moisture_gradient]
|
||
# !! NOT LOADED AT RUNTIME until T-1032 wires TOML loading. The LIVE source is
|
||
# !! ClimateConstants::default() in server/src/atlas/district_profile.rs — editing
|
||
# !! these values here alone has NO effect (the file header's "tune: edit here"
|
||
# !! does not yet apply to this table). Change BOTH, or change the Rust default.
|
||
# Per-district moisture spatial gradient (T-1080, D-239 §2). Integer points
|
||
# subtracted from the body's hydrosphere moisture *ceiling* so the field varies
|
||
# across the body instead of being a single constant (the bug: moisture_q = 80 for
|
||
# every district -> uniform vegetation/terrain). Wet at coast/lowland/tropics, drier
|
||
# toward interior/highland/poles. Provisional magnitudes — Q-123 calibrates. Mirrors
|
||
# the embedded ClimateConstants::default(); not yet loaded at runtime (TOML wiring is
|
||
# T-1032), kept in sync by hand like the other tables.
|
||
lat_penalty = 20 # lost equator->pole (x |latitude|/90)
|
||
elev_penalty = 15 # lost low->high elevation (x elev_q/100, rain-shadow)
|
||
continental_penalty = 20 # lost coast->interior (x (100 - ocean_fraction_q)/100)
|