From fc3b7485c64f515711d917c9209a75b33e9ede3a Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Tue, 24 Mar 2026 17:28:40 +0100 Subject: [PATCH] feat(schema): add bodies and stations tables to systems.db MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New tables for the celestial body hierarchy below system level: - bodies: planets, moons, gas giants, asteroid belts, oort clouds with physical properties, settlement data, and cultural overrides - stations: orbital/surface facilities with type, population, docking class, and gate infrastructure flag Naming convention: GJ-{n}b (planet), GJ-{n}b-1 (moon), GJ-{n}b-S1 (station), GJ-{n}-oort (oort cloud). Self-referential parent_body_id for moon→planet relationships. Co-Authored-By: Claude Opus 4.6 (1M context) --- docs/backups/settledreach.db.backup | Bin 851968 -> 962560 bytes server/data/systems-schema.sql | 73 ++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/docs/backups/settledreach.db.backup b/docs/backups/settledreach.db.backup index 49f7ec8b87b473e4779ed51b54e03432ebd9aca9..49b0f27785c53e8d6bb7f739f7757e24fe7a2d2d 100644 GIT binary patch delta 55199 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 QgC8f~O!lvG|L^O61AMw-fB*mh delta 8705 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 qTx}F4^ZIqhdCzIDJWE8nCcDn9r!;6#--K( diff --git a/server/data/systems-schema.sql b/server/data/systems-schema.sql index 22aaf85e5..d84cebd93 100644 --- a/server/data/systems-schema.sql +++ b/server/data/systems-schema.sql @@ -121,6 +121,72 @@ CREATE TABLE IF NOT EXISTS system_culture ( -- narrative_hook, calibration_note) lives in wiki markdown files only. -- No DB mirror — read the file if you need the text. +-- Celestial bodies — planets, moons, gas giants, asteroid belts, oort clouds +-- Naming convention: +-- GJ-{n}b/c/d... — planets (innermost first) +-- GJ-{n}Ab/c/d... — planets orbiting primary (binary systems) +-- GJ-{n}d-1 — first moon of third planet +-- GJ-{n}-oort — oort cloud region +-- GJ-{n}-belt — asteroid belt +CREATE TABLE IF NOT EXISTS bodies ( + body_id TEXT PRIMARY KEY, + system_id TEXT NOT NULL REFERENCES star_systems(system_id), + parent_body_id TEXT REFERENCES bodies(body_id), -- NULL for planets; parent planet for moons + + -- Classification + body_type TEXT NOT NULL, -- planet, moon, gas_giant, asteroid_belt, oort_cloud + orbit_index INTEGER, -- innermost = 1 (planets around star, moons around planet) + proper_name TEXT, -- "Xin Chengdu", NULL for unnamed + + -- Physical + mass_class TEXT, -- terrestrial, super_earth, ice_giant, gas_giant, dwarf + atmosphere TEXT, -- breathable, thin, toxic, none, dense + surface_gravity REAL, -- in g (Earth = 1.0), NULL for gas giants + biome_summary TEXT, -- temperate, arid, frozen, oceanic, volcanic, barren, mixed + hydrosphere TEXT, -- ocean, ice, rivers, none, subsurface + + -- Settlement + inhabited INTEGER NOT NULL DEFAULT 0, + population INTEGER DEFAULT 0, + economic_role TEXT, -- manufacturing, agricultural, extraction, research, transit + founding_age_years INTEGER, + settlement_pattern TEXT, -- urban_concentrated, dispersed_rural, orbital_only, domed, cave + + -- Cultural (inherited from system, can override) + cultural_corridor TEXT, -- override system corridor if different + industrial_corridor TEXT, -- MVG, Gate_Corp, DSMC, Prometheus, Agricultural_Syndic + + -- Rendering + terrain_reference TEXT, -- heightmap path when authored, NULL otherwise + screenshot_path TEXT, -- planetary shader screenshot path + + updated_at TEXT DEFAULT (datetime('now')) +); + +-- Stations and orbital facilities +-- Naming: GJ-{n}b-S1 (first station orbiting planet b), GJ-{n}-oort-S1 (horizon station) +CREATE TABLE IF NOT EXISTS stations ( + station_id TEXT PRIMARY KEY, + system_id TEXT NOT NULL REFERENCES star_systems(system_id), + orbits_body_id TEXT REFERENCES bodies(body_id), + + -- Classification + station_type TEXT NOT NULL, -- horizon, commercial, military, research, industrial, agricultural, transit + proper_name TEXT, -- "Chengdu Orbital", "Horizon Station" + + -- Settlement + population INTEGER DEFAULT 0, + economic_role TEXT, + governance_type TEXT, -- can differ from system governance + + -- Infrastructure + docking_class TEXT, -- major, standard, restricted, none + has_gate_infrastructure INTEGER DEFAULT 0, + district_count INTEGER DEFAULT 1, + + updated_at TEXT DEFAULT (datetime('now')) +); + -- Indexes -- astronomical_id removed: system_id IS the GJ catalog number CREATE INDEX IF NOT EXISTS idx_star_systems_sector ON star_systems(geographic_sector); @@ -132,3 +198,10 @@ CREATE INDEX IF NOT EXISTS idx_historical_events_system ON historical_events(sys CREATE INDEX IF NOT EXISTS idx_system_factions_dominant ON system_factions(dominant_faction); CREATE INDEX IF NOT EXISTS idx_system_economy_tier ON system_economy(economic_tier); CREATE INDEX IF NOT EXISTS idx_system_culture_archetype ON system_culture(primary_archetype); +CREATE INDEX IF NOT EXISTS idx_bodies_system ON bodies(system_id); +CREATE INDEX IF NOT EXISTS idx_bodies_parent ON bodies(parent_body_id); +CREATE INDEX IF NOT EXISTS idx_bodies_type ON bodies(body_type); +CREATE INDEX IF NOT EXISTS idx_bodies_inhabited ON bodies(inhabited); +CREATE INDEX IF NOT EXISTS idx_stations_system ON stations(system_id); +CREATE INDEX IF NOT EXISTS idx_stations_orbits ON stations(orbits_body_id); +CREATE INDEX IF NOT EXISTS idx_stations_type ON stations(station_type);