Continues the core-world cohesion pass. All markers.json edits synced to
atlas_* tables. apply_name_fixes.py extended with all new fix tables.
GJ244Ad Edict (400M pop): 5 fixes — 2 lazy mountain names replaced with
Edict-vocabulary terms ("The Statute", "Charter Spur"); 3 cardinal oceans
replaced with cross-referential names (Veil Shelf → Veil Institute POI,
Concord Mere → Concord Assembly Archive POI, Charter Tarn → Charter Spur
mountain). Note: "Westwall" flagged by Gestalt not found in markers.json
or DB; stale data issue. Arcs established: Charter-, Concord-, Veil-.
GJ380c Lendel (900M pop): 2 fixes — "Pale Run" river renamed "Durneth
Beck" (cross-refs Durneth Range; "beck" = British stream); "Tember Ridge"
renamed "Tember Spine" (keeps stem, removes lazy Ridge suffix). Aldren-
stem arc (capital + river + exchange) is intentional — preserved.
GJ699b Verada (1.9B pop): 8 fixes — all 3 rivers renamed from civic-grid
names to geographic names (Verada Reach, The Meridian, Capitol Beck); 5
oceans renamed to replace architectural/district suffixes with geographic
ones (Prospect Sea, Haven Sea, Meridian Sound, Capitol Mere, Sterling
Pool). Arcs: Capitol- (city + river + ocean), Meridian- (river + ocean),
Haven/Port- (city + ocean).
GJ699b-1 Verada moon: 8 fixes — all 8 mountains renamed from street
addresses (Grandview Avenue, Harmony Boulevard, Beacon Street, etc.) to
geological/institutional cross-references. The moon's peaks now carry the
names of Verada's civic institutions as seen from orbit: Tribunal Spur,
Zenith Spine, Keystone Scarp, Ironwood Spur, Consulate Scarp, Prefecture
Spur, Barnard Heights, Verada Scarp (largest range).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
301 lines
14 KiB
Python
301 lines
14 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
apply_name_fixes.py — Apply curated name replacements to markers.json files.
|
|
|
|
Usage:
|
|
python3 tooling/planet-gen/apply_name_fixes.py [--dry-run]
|
|
|
|
Edits name fields only; all geometry (path, center, area_fraction) is preserved.
|
|
After running, call generate_atlas.py --body <id> for each body to sync DB.
|
|
|
|
Decisions: D-191 (markers.json format, corridor palettes)
|
|
"""
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
REPO_ROOT = (Path(__file__).resolve().parent / ".." / "..").resolve()
|
|
WIKI = REPO_ROOT / "wiki" / "star-systems"
|
|
|
|
DRY_RUN = "--dry-run" in sys.argv
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Name replacement tables per body
|
|
# Format: { body_dir_key: { "feature_type": { "old_name": "new_name" } } }
|
|
# feature_type: cities | rivers | oceans | mountain_ranges | pois
|
|
# ---------------------------------------------------------------------------
|
|
|
|
FIXES: dict[str, dict[str, dict[str, str]]] = {
|
|
|
|
# -----------------------------------------------------------------------
|
|
# GJ 144 — Ran system
|
|
# Verified against actual markers.json files (DB is stale).
|
|
# -----------------------------------------------------------------------
|
|
|
|
# Kallast (GJ144d) — 2B pop, agricultural, urban_concentrated, ocean world
|
|
# Current state (from markers.json): good Nordic naming pass done; residual
|
|
# lazy/generic oceans remain. Fix: rename remaining generics, add cross-ref
|
|
# with mountain "Seterfjellet" (ocean → "Seterfjord"), fix POI, and rename
|
|
# "Aldren Pass" to avoid cross-system collision with Lendel (GJ380c capital
|
|
# "Aldren" and river "The Aldren").
|
|
# Narrative hook: "Rán's Landing" city (names the star), "Rán's Run" and
|
|
# "Ranfall Beck" rivers (shared Rán stem = cross-referencing done). Adding
|
|
# Seterfjord → Seterfjellet link completes the second cross-reference arc.
|
|
"GJ-144/bodies/GJ144d": {
|
|
"rivers": {
|
|
# Avoid cross-system stem collision with Lendel (GJ380c) "Aldren"
|
|
"Aldren Pass": "Randalfoss",
|
|
},
|
|
"oceans": {
|
|
# Still generic — large ocean near mountains → name ties to Seterfjellet
|
|
"Boulder Bluff": "Keldmere",
|
|
# "High Mesa" for an ocean is nonsensical
|
|
"High Mesa": "Seterfjord",
|
|
},
|
|
"pois": {
|
|
"Summit Point": "Kallast Gate Terminal",
|
|
},
|
|
},
|
|
|
|
# Vethis (GJ144e) — 1.2B pop, agricultural, dispersed_rural
|
|
# Current state: partial naming pass done. Remaining: cardinals (West Bend),
|
|
# earth-echoes (Blue Ridge), generics (Stone Point, Ironside Run, Golden
|
|
# Valley, Broad Fork), "Ash" stem overuse (Ashbluff Sea + Ashstone Ridge +
|
|
# Ashvale = 3 features), "Iron" stem overuse (Irongate + Ironside Run = 2).
|
|
# Fixes cross-reference existing named features:
|
|
# Grey- stem: Greywash + Greywash Fork + Greystone Ridge (intentional arc)
|
|
# Thorn- stem: Thorncrests + Thornrun (mountain visible from river)
|
|
# Kel- stem: Kelbridge + Kelside Run (river serving the city)
|
|
# Veth- stem: Vethis + Veth Delta + Veth Mere (planet name echoed in geography)
|
|
"GJ-144/bodies/GJ144e": {
|
|
"rivers": {
|
|
"West Bend": "Greywash Fork", # cardinal → cross-refs Greywash river
|
|
"Blue Ridge": "Ashvale Beck", # earth-echo → cross-refs Ashvale city
|
|
"Stone Point": "Thornrun", # generic → cross-refs Thorncrests mtn
|
|
"Ironside Run": "Kelside Run", # Iron overuse → cross-refs Kelbridge
|
|
},
|
|
"oceans": {
|
|
# Ashbluff Sea: "Ash" prefix already on Ashvale city + Ashstone Ridge mtn
|
|
"Ashbluff Sea": "Veth Mere", # Ash overuse → cross-refs Veth Delta
|
|
},
|
|
"mountain_ranges": {
|
|
"Golden Valley": "Greymoor Range", # generic → cross-refs Greywash river
|
|
"Broad Fork": "Keld Spur", # generic → Nordic "keld" (spring)
|
|
# Ashstone Ridge: "Ash" overuse (Ashvale + Veth Mere rename frees slot)
|
|
"Ashstone Ridge": "Greystone Ridge", # Ash overuse → cross-refs Greywash
|
|
},
|
|
"pois": {
|
|
"Ridge Crossing": "Vethis Gate Terminal",
|
|
},
|
|
},
|
|
|
|
# -----------------------------------------------------------------------
|
|
# GJ 71 — Tau Ceti system
|
|
# Verified against actual markers.json files (DB is stale).
|
|
# -----------------------------------------------------------------------
|
|
|
|
# Threshold (GJ71c) — 600M pop, agricultural, urban_concentrated
|
|
# Fix: replace "Aethelred" (Anglo-Saxon; breaks the all-Latin-personal-name
|
|
# pattern of the six rivers: Octavius, Septimus, Quintus, Valeria, Marcus).
|
|
# Narrative: All six rivers named after the original Commission survey team.
|
|
"GJ-71/bodies/GJ71c": {
|
|
"rivers": {
|
|
"Aethelred": "Gaius",
|
|
},
|
|
},
|
|
|
|
# Arden (GJ71d) — 500M pop, agricultural, dispersed_rural
|
|
# Fix cross-body stem duplicates:
|
|
# "Concordia Hall" city → exact stem match with GJ71c ocean "Concordia"
|
|
# "Basilica Nova" river → exact name match with GJ71c POI "Basilica Nova"
|
|
# GJ71d-1 has been independently updated — Forum Major no longer conflicts.
|
|
# Capital "Palaestra" and other names are clean — keep.
|
|
"GJ-71/bodies/GJ71d": {
|
|
"cities": {
|
|
"Concordia Hall": "The Praxis", # Concordia = GJ71c sea
|
|
},
|
|
"rivers": {
|
|
"Basilica Nova": "Via Principia", # exact match = GJ71c POI name
|
|
},
|
|
},
|
|
|
|
# Verantis (GJ71d-1) — 20M pop, transit moon of Arden
|
|
# Already updated in a prior pass (capital=Praetorium, mountains all
|
|
# renamed to unique Latin institutional names). No changes needed.
|
|
# "GJ-71/bodies/GJ71d-1": {}, # skip
|
|
|
|
# -----------------------------------------------------------------------
|
|
# GJ 244A — Sirius system
|
|
# Verified against actual markers.json files (DB matches).
|
|
# Note: "Westwall" flagged by Gestalt does NOT appear in Edict markers.json
|
|
# or DB — either already removed in a prior pass or Gestalt saw stale data.
|
|
# -----------------------------------------------------------------------
|
|
|
|
# Edict (GJ244Ad) — 400M pop, hand-authored template + #833 derived features
|
|
# Hand-authored core is clean (Mandate, Station Edict, Founder's Range,
|
|
# Accord Peaks, Veto Spur, Concord Assembly Archive, all POIs). Fixes
|
|
# target only #833-generated features that don't match the political-legal
|
|
# naming vocabulary of Edict.
|
|
# Narrative hook: the legal/institutional vocabulary — Mandate, Accord, Veto,
|
|
# Concord, Statute, Charter — all reference governance and founding documents.
|
|
# Arcs established: Concord- (ocean + POI), Charter- (mountain + ocean),
|
|
# Veil- (ocean + POI cross-ref to Veil Institute Survey Station).
|
|
"GJ-244A/bodies/GJ244Ad": {
|
|
"mountain_ranges": {
|
|
# "Keel" is a nautical term — wrong vocabulary for a political world
|
|
"Keel Ridge": "Charter Spur", # charter = Edict's founding document
|
|
# "Sanction" fits but "Ridge" suffix is lazy
|
|
"Sanction Ridge": "The Statute", # distinctive; drops generic suffix
|
|
},
|
|
"oceans": {
|
|
# Cardinal direction names; replace with Edict-vocabulary terms
|
|
"Upper Shelf": "Veil Shelf", # cross-refs Veil Institute Survey Station
|
|
"Southern Melt": "Concord Mere", # cross-refs Concord Assembly Archive POI
|
|
"Eastern Tarn": "Charter Tarn", # cross-refs mountain "Charter Spur"
|
|
},
|
|
},
|
|
|
|
# -----------------------------------------------------------------------
|
|
# GJ 380 — Groombridge system
|
|
# Verified against actual markers.json files.
|
|
# Hand-authored template is clean: Aldren (capital) + The Aldren (river) +
|
|
# Aldren Exchange (POI) is an INTENTIONAL arc — do not touch.
|
|
# "Meridian Risk HQ" POI is a corporation proper noun — not geography.
|
|
# -----------------------------------------------------------------------
|
|
|
|
# Lendel (GJ380c) — 900M pop, hand-authored template + #833 derived features
|
|
# Two #833-generated features with lazy suffixes. British-Isles naming
|
|
# vocabulary: Lendel, Aldren, Sethvale, Caldenmere, Rethain Sea.
|
|
# "Durneth Beck" cross-refs Durneth Range (the major mountain range near
|
|
# the river's source area). "Tember Spine" keeps the "Tember" stem but
|
|
# drops the lazy "Ridge" suffix.
|
|
"GJ-380/bodies/GJ380c": {
|
|
"rivers": {
|
|
"Pale Run": "Durneth Beck", # lazy → cross-refs Durneth Range; beck=British stream
|
|
},
|
|
"mountain_ranges": {
|
|
"Tember Ridge": "Tember Spine", # lazy Ridge → Spine (distinctive; not in lazy list)
|
|
},
|
|
},
|
|
|
|
# -----------------------------------------------------------------------
|
|
# GJ 699 — Barnard's Star system
|
|
# Verified against actual markers.json files.
|
|
# -----------------------------------------------------------------------
|
|
|
|
# Verada (GJ699b) — 1.9B pop, hop-0, dense urban world
|
|
# Major problem: rivers and ocean names use urban civic vocabulary
|
|
# (Grandview Square, Meridian City, Metropolitan Square) — these are
|
|
# neighborhood-planning names, not geographic features. Rivers especially
|
|
# cannot be named "Grandview Square" or "Meridian City". Oceans have
|
|
# district-style names that duplicate on sibling bodies.
|
|
# Strategy: keep Verada's civic-density character in CITY names, but
|
|
# give geographic features geographic names that cross-reference the cities.
|
|
# Arcs: Capitol- (city + river + ocean), Haven/Port- (city + ocean),
|
|
# Meridian- (river + ocean), Prospect- (ocean), Sterling- (lake).
|
|
"GJ-699/bodies/GJ699b": {
|
|
"rivers": {
|
|
# "Grandview Square" is a plaza, not a river name
|
|
"Grandview Square": "Verada Reach", # planet name + geographic; Reach = stretch of river
|
|
# "Meridian City" is a city name used for a river
|
|
"Meridian City": "The Meridian", # drop civic suffix; becomes proper river name
|
|
# "Summit View" is lazy
|
|
"Summit View": "Capitol Beck", # cross-refs Capitol Heights capital city
|
|
},
|
|
"oceans": {
|
|
# "Terrace" is an architectural term — wrong for a large ocean
|
|
"Prospect Terrace": "Prospect Sea", # keep Prospect, fix suffix
|
|
# "Metropolitan Square" is a plaza name for an ocean
|
|
"Metropolitan Square": "Haven Sea", # cross-refs Port Haven city
|
|
# Exact dup of GJ699b-1 mountain "Central District"
|
|
"Central District": "Meridian Sound", # cross-refs The Meridian river
|
|
# "Plaza" is civic architecture, not a lake feature
|
|
"Liberty Plaza": "Capitol Mere", # cross-refs Capitol Heights capital
|
|
# "Sterling Heights" — "Heights" is wrong for a lake; dupes GJ699b-1 mountain
|
|
"Sterling Heights": "Sterling Pool", # keep Sterling, fix suffix
|
|
},
|
|
},
|
|
|
|
# Verada's moon (GJ699b-1) — uninhabited transit moon
|
|
# All 8 mountains are named after urban street addresses (Grandview Avenue,
|
|
# Harmony Boulevard, Beacon Street, etc.) — this is entirely wrong for
|
|
# mountain ranges. The fix renames them to geological/geographic terms that
|
|
# cross-reference Verada's institutional vocabulary (as if settlers looked
|
|
# down at Verada and named the moon's peaks after the institutions below).
|
|
# The largest range (Verada Scarp, was "Grandview Avenue") takes the planet
|
|
# name directly.
|
|
"GJ-699/bodies/GJ699b-1": {
|
|
"mountain_ranges": {
|
|
"Grandview Avenue": "Verada Scarp", # largest range; named after parent body
|
|
"Central District": "Barnard Heights", # names the star; distinct from all Verada names
|
|
"Harmony Boulevard": "Keystone Scarp", # cross-refs Keystone Junction on Verada
|
|
"Capitol Heights": "Tribunal Spur", # cross-refs Tribunal Tower on Verada
|
|
"Meridian Plaza": "Zenith Spine", # cross-refs Zenith Station on Verada
|
|
"Liberty Square": "Ironwood Spur", # cross-refs Ironwood Borough on Verada
|
|
"Metropolitan Way": "Consulate Scarp", # cross-refs Consulate Way on Verada
|
|
"Beacon Street": "Prefecture Spur", # cross-refs Prefecture Hall on Verada
|
|
},
|
|
},
|
|
}
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Helpers
|
|
# ---------------------------------------------------------------------------
|
|
|
|
def apply_fixes(body_key: str, fixes: dict[str, dict[str, str]]) -> bool:
|
|
"""Load markers.json for body_key, apply name fixes, write back. Returns True on change."""
|
|
parts = body_key.split("/")
|
|
path = WIKI / Path(*parts) / "markers.json"
|
|
|
|
if not path.exists():
|
|
print(f" SKIP {body_key}: markers.json not found at {path}")
|
|
return False
|
|
|
|
with open(path) as f:
|
|
markers = json.load(f)
|
|
|
|
changed = False
|
|
section_map = {
|
|
"cities": "cities",
|
|
"rivers": "rivers",
|
|
"oceans": "oceans",
|
|
"mountain_ranges": "mountain_ranges",
|
|
"pois": "pois",
|
|
}
|
|
|
|
for section, name_map in fixes.items():
|
|
feature_list = markers.get(section_map[section], [])
|
|
for feature in feature_list:
|
|
old_name = feature.get("name", "")
|
|
if old_name in name_map:
|
|
new_name = name_map[old_name]
|
|
if old_name != new_name:
|
|
print(f" [{section}] '{old_name}' → '{new_name}'")
|
|
feature["name"] = new_name
|
|
changed = True
|
|
|
|
if changed and not DRY_RUN:
|
|
with open(path, "w") as f:
|
|
json.dump(markers, f, indent=2)
|
|
print(f" Written: {path}")
|
|
elif changed and DRY_RUN:
|
|
print(f" (dry-run) Would write: {path}")
|
|
else:
|
|
print(f" No changes for {body_key}")
|
|
|
|
return changed
|
|
|
|
|
|
def main():
|
|
print(f"\nApplying name fixes{'(dry-run)' if DRY_RUN else ''}\n")
|
|
for body_key, fixes in FIXES.items():
|
|
print(f"=== {body_key} ===")
|
|
apply_fixes(body_key, fixes)
|
|
print()
|
|
print("Done.\n")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|