- T-1070: scaffold_bodies.py heightmap link now conditional (bake criteria
per import_heightmaps.py); surgical removal of the dead image line from
all 2,131 body pages lacking the file (267 with the file keep theirs)
- T-1071: 26 real link breaks fixed (knowledge/→concepts/, pre-governance
decision anchors, 9 phantom catalog companions unlinked, cygni relink to
the corporation page, wrong design-doc path); wiki/index.md counts fixed
(301 systems) + Economics nav section; corporations/index.md regenerated
from frontmatter (all 155, tier1.toml grouping — corrects 4 misfiled
tier-1 corps); 25 orphaned station GTTRs linked from 11 system pages
(own ##-heading so atlas sync cannot absorb it); GOVERNANCE.md +
star-system template rewritten to the generated model (DB owns
structured fields, wiki owns prose); triangles/index.md added
- Sol markers conversion REVERTED before commit: atlas_viewer.gd:433 still
renders the legacy geometry schema, so conversion would drop Sol's Atlas
overlays — split to T-1073 (convert together with the client read path)
Broken relative links: 2,180 → 25 (all remaining are intentional
_templates/ placeholders).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The corridor over-represented southern-African heritage (afrikaans on 15
systems; arab=2, persian/turkic=0) as an artifact of the earlier
name-balancing overcorrecting. Convert five genuinely-thin afrikaans
systems — whose distinctive threads are heritage-agnostic — into
Arab/Persian/Turkic founders so the cultural cascade is built on a
balanced set. Load-bearing mystery systems (Eerste Wacht / Helderoog /
Brandpunt etc.) are left untouched.
Droëland (GJ 914A) -> Marib (arab)
Stilwater (GJ 508A) -> Sawad (arab)
Koeberg (GJ 1245B) -> Akhgar (persian)
Skuilplek (GJ 722) -> Siginak (turkic)
Carnarvon (GJ 680) -> Golestan (persian; Mostert dynasty -> Farahani)
Result: afrikaans 15->10; arab 0->2, persian 0->2, turkic 0->1.
Full narrative retouch (not just names): gttr.md + index.md prose,
body/station proper_names, cultural_specialization, gttr_hook,
atlas_city_names, and the four brand-corps named after the converted
systems (corp IDs kept stable; only display names + products renamed).
Cross-references in neighbour systems, the catalog, the aggregate
drifter guides, and the atlas proposals are updated to match.
arab/persian/turkic added to _CULTURAL_HERITAGE so the values validate;
the full canonical 47-value migration remains #1016.
Also fixes a pre-existing canon bug: Sawad (GJ 508A) no longer claims
GJ 914A is "unsettled" — it is Marib, a three-century settlement.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Part 1 of #951. Per D-223, every markers.json is reduced to a flavored name pool —
names only, no positions/geometry. 2398 files; 25,264 names preserved across
rivers/mountains/oceans/cities/pois/roads/railroads. Positions now come from the
deterministic cascade (heightmap + drainage) and economic sim; names attach from the pool.
Expected fallout (next #951 steps): the tooling/planet-gen geometry pipeline and
import_economics read markers geometry, so regen-db breaks until the importer is
reworked for the names-only format. Sol markers (tooling/planet-gen/sol_markers/) not
yet handled. No push (batch until Phase 4 done).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Generated oort cloud and asteroid belt generic globe images via Gemini.
Background-masked with flood-fill (shadow-preserving). Donor fill script
copies matching globe.png from same planet_class+body_type pool with
per-body hash selection, no repeats within a system. 629 bodies filled,
3240/3240 now have globe.png.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Systematic sweep eliminated all city name cross-body collisions across the
273 inhabited bodies. Started from Forum Veritas/Jade Harbor/Fort Iron
clusters identified during the #849 analysis pass.
Strategy: use world proper_name as capital city name wherever unique.
For worlds sharing a proper_name, author corridor-appropriate alternates.
All edits synced to atlas_cities via generate_atlas.py --body.
Before: 119+ cross-body city collisions, worst-case ×20 (Jade Harbor)
After: 0 cross-body city collisions
Clusters eliminated: Forum Veritas ×10, Jade Harbor ×19, Fort Iron ×10,
Eisenstadt ×7, Fjordheim/Fjordholm ×6 each, Eisenberg/Eisenfels/Hanseong ×5
each, Ridge Marker ×5, plus 20+ smaller clusters down to ×2.
River/ocean collisions (Rio Grande ×23 rivers, Steinbruch ×19, etc.)
remain — these affect uninhabited secondary bodies at scale and require a
dedicated batch-script pass.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The upstream terrain pipeline assigns sparse IDs (range_1, range_50,
range_29...) and the prune pass drops entries but keeps original IDs.
This leaves 2394 bodies with non-sequential IDs across mountain_ranges,
rivers, and oceans.
Renumbered all feature IDs to sequential {prefix}_0, {prefix}_1, ...
preserving sort order. 24021 IDs fixed across 2394 bodies. No name
or geometry data changed — only the id field.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two fixes from observing the first Gemma 2 batch run on Sirius:
1) Prune oversized feature counts. The upstream terrain pipeline emits
every distinct mountain cluster as a separate `mountain_range` and
every flowing path as a separate `river`. At the atlas generator's
512×256 grid this produced bodies with 40-80 named ranges and
10-15 rivers — noise, not information. A single planet with 48
ridges isn't richer, it's unparseable.
`tooling/planet-gen/prune_atlas_features.py` walks every
`markers.json` under `wiki/star-systems/`, ranks each feature type
by a size proxy, and keeps only the top N:
- mountain_ranges: sorted by `area_cells`, top 8 per body
- rivers: sorted by path length, top 6 per body
- oceans / cities / pois: untouched (already small, or
hand-authored by generate_atlas.py)
Sol (GJ-0) is hardcoded-excluded from pruning so the hand-authored
Earth / Mars / moon content stays untouched.
Each pruned body gets its atlas_* rows re-synced via
`sync_markers_to_db` so the DB mirror stays consistent. Bodies
whose wiki folder has no matching row in `bodies` (14 pre-existing
orphans like GJ1156h-1, GJ34Ah-2, …) are pruned in-file but skip
the DB sync to avoid FK violations on atlas_body_grids.
First run results:
bodies scanned: 2394
bodies pruned: 1513
mountain ranges dropped: 11640
rivers dropped: 1382
Safe to re-run — idempotent when a body is already within the caps.
2) Grounded cosmopolitan fallback palette. When Gemma's 3 retries
all fail (dedup, blocklist, stem-cap, placeholder), the code falls
to `_FALLBACK_STEMS[corridor]`. The old table had 10 stems per
corridor, all Latin-institutional (Meridian, Concord, Prefecture,
Cardinal, Lumen, Foro, Tabula, Vox, Axis, Senatus), which produced
the same-y `Axis Spine / Axis Ridge / Axis Heights / Axis Scarp`
clusters the user flagged on Sirius — exactly the old epic-Latin
register the few-shot pools were rewritten to avoid.
Fallbacks now draw from a 30-45 stem grounded cosmopolitan list
per corridor matching the few-shot pool intent:
- core: 45 stems (Ashfield, Bellview, Cedarbrook,
Fairmont, Ironwood, Kirkwood, Linden, Meridian,
Northfield, Riverside, Westbrook, …)
- north_reach: 40 stems (Ashford, Bellfield, Clifford, Drayton,
Elmhurst, Garner, Holmwood, Kelsworth, …)
- west_reach: 35 stems (Altdorf, Bergfjord, Eikhof, Hoogland,
Järvenpää, Kloosterdam, Nieuwpoort, Sørholm,
Svarteberg, Torsfell, Voorhout, Weserhof, Östby, …)
- east_reach: 35 stems (Aomori, Baektu, Chōshi, Fukagawa,
Hanyang, Izumi, Takamine, Yurigawa, …)
- south_reach: 36 stems (Alves, Brandão, Évora, Gomes, Ribeiro,
Serra, Várzea, Hlanganani, Kilimi, …)
- deep_frontier: 30 stems (Okafor, Stenner, Weller, Kellogg,
Stonebrook, Dustgate, Blackwater, …)
Per-feature suffix lists also expanded (e.g. river suffixes now
include Brook, Stream, Flow, Creek on top of the original Run /
Water / Beck / Rill / Course). Net effect: 300-450 unique fallback
combinations per (corridor, feature_type), up from 50, in the same
grounded register the few-shot pools teach.
Also preserves aliases `inner_corridor`, `inner_orbit`, and
`sol-gateway-axis` as legacy-compatible keys pointing at the
administrative-English palette.
Combined effect on the next run:
- ~45% fewer features to name (pruned 13k/52k)
- ~9× more fallback variety per corridor when fallback does trigger
- Same grounding overhaul from the previous commit, now reaching
into the safety-net path
Implements the Phase 3 atlas content generator per D-191 §3, §8, and §9.
Pipeline per body (terrain-aware, deterministic per seed + body):
1. Simulate terrain via planet_simulation.simulate().
2. Analyse continents (flood-fill), habitability (temp/moisture/slope +
coastal bonus), river mouths, and a terrain A* cost grid.
3. Place cities sequentially — capital first (habitability + river-mouth
bias), then corridor growth via multi-source Dijkstra, quadrant-spread
penalty after 2 cities in a quadrant, port-on-new-continent bonus at
cities 3–4. ±25% noise for seed variation.
4. Generate roads and railroads as an MST over city positions, with
A* paths on the terrain cost grid (rail follows roads where possible).
5. Place a transit POI at the capital (15% chance to scatter to a
secondary city).
Output (canonical markers.json schema, pixel space per D-191 §8):
- cities: {id, name, kind, center:[r,c], population}
- roads: {id, name, kind, path:[[r,c],...]}
- railroads: {id, name, kind, path:[[r,c],...]}
- pois: {id, name, kind, center:[r,c]}
- existing rivers/oceans/mountain_ranges preserved untouched.
City names are left empty for gemma_naming.py (#833). Body population is
split across cities with geometric decay (capital ~50%, each subsequent
city half the previous). The 6 hand-authored bodies (Lendel, Edict,
Vuurkloof, Røros, Cairnside, Estrade) are detected by existing
`cities` and skipped for regeneration; their markers are still synced
to the DB index below.
Atlas index in systems.db (new):
- atlas_body_grids, atlas_cities, atlas_roads, atlas_railroads,
atlas_pois, atlas_rivers, atlas_oceans, atlas_mountain_ranges
- Scalar metadata mirror of every markers.json — the implant atlas app
and development queries can lookup cities/POIs/features without
scanning 267 JSON files. Polyline geometry stays in the markers.json
files next to the heightmaps (used by the renderer); the DB only
stores filterable scalar fields plus `point_count` as a length proxy.
- Schema lives in server/data/systems-schema.sql; generate_atlas.py
mirrors the CREATE TABLE IF NOT EXISTS block so it runs against any
DB state (matches the economy-db importer pattern).
- Populated and refreshed on every run. Each body's rows are deleted
and reinserted deterministically — no stale state.
Also fixes a pre-existing WIP bug in the quadrant-saturation penalty
loop (a stray outer `for r in range(GRID_H)` with unreachable breaks
meant only the NW quadrant was ever checked).
Runtime: 280s for all 267 inhabited bodies on a single core. 265 bodies
updated this run, 6 hand-authored bodies synced to DB without
regeneration.
Atlas index after run:
atlas_cities 329 (15 hand-authored + 314 awaiting #833)
atlas_roads 46
atlas_railroads 44
atlas_pois 287
atlas_rivers 2034
atlas_oceans 696
atlas_mountain_ranges 1953
atlas_body_grids 267
Full regeneration of ~2,600 bodies with:
- Correct atmosphere rim colors for extended planet classes
- Clean headings and profile tables (no underscores)
- Boreal/tropical cloud coverage at correct ranges
- Gas giants without meaningless terrain fields
- All heightmaps at 1024x512
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Scaffolded index.md, globe.png (512x512), heightmap.png (1024x512),
terrain.npz, and markers.json for ~2600 celestial bodies across the
Settled Reach. Heightmaps render at native simulation resolution.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
"Biome" describes per-zone vegetation classification (Whittaker table).
"Planet class" describes overall planetary character. The conflation
caused the planet generator to misclassify ~270 bodies as barren.
Scope: systems.db column, schema SQL, Rust atlas code, wiki table
headers (Biome → Class), atlas proposal JSONs, all docs/decisions,
tooling scripts. Also normalizes atmosphere vocabulary (breathable →
standard) and expands planet class mapping to all 26 wiki values.
Unknown classes default to temperate for modder safety.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
20 changes across 18 systems implementing the approved remediation plan
from the cultural diversity audit (docs/design/cultural-diversity-audit.md).
DB changes (15 bodies/stations in systems.db):
- Thai bodies: Saikaew (GJ 635B), Nakhon Sung (GJ 667C), Doi Kaeo (GJ 117)
- Khmer bodies: Banteay (GJ 434), Srok Thmei (GJ 866A)
- Ukrainian: Chornozem body + Svoboda station (GJ 729)
- Caribbean: Lavenille body (GJ 873), Accompong Works station (GJ 406)
- Malay: Pulau Baru body (GJ 555), Balai station (GJ 449)
- Scientists: Huygens Platform (GJ 251), Ramanujan Station (GJ 699),
van Leeuwenhoek Station (GJ 820B), Turing Survey (GJ 663A)
Wiki calibration note additions:
- GJ 635B/667C/117/434: Thai cultural presence (survey teams, founding cohorts)
- GJ 866A/873: Khmer/Caribbean community naming origin
- GJ 729: Ukrainian founding cooperative in west_reach
- GJ 1245A/75: Igbo/Nigerian heritage explicitly acknowledged
- GJ 172: Malay kelong dual-heritage in Kaelong name
- GJ 601A: Russian secondary founding stream in Ostmark
Horizon stations not renamed. No corridor reassignments.
Conservative: systems with existing identity untouched.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Complete Drifter's Guide coverage for the North Reach corridor.
49 new entries from hop 3 (Crown's Hollow) to hop 12 (Rekohu),
plus updated gttr-north.md index with all 55 north systems.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fremantle (GJ 273), Athabasca (GJ 1289), Carnarvon (GJ 680),
Enugu (GJ 75), Ratnagiri (GJ 575A), Pemberton (GJ 194B),
Murchison (GJ 716), Moyale (GJ 1292), Rekohu (GJ 770).
Commonwealth corridor from hop 4 to hop 12, with Early Arrival
exceptions (Cape, Igbo, Indian, East African heritage) and a
Gate Silence Survivor at the terminus.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove S-number from page headers and replace S-number references in
topology sections with GJ astronomical IDs. Headers now show
"**GJ XXX** | type | sector" instead of "**GJ XXX** | S-NNN | type | sector".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wiki pages are the single source of truth for all per-system data.
Each stub contains all 68 columns in YAML frontmatter, pre-filled
from star-map.json for identity/infrastructure fields. Includes
Sol (S-000/GJ 0) and Van Maanen's Star (S-057/GJ 35) with Sova
station content.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>