Planet — Schema¶
Status: 🚧 Partial — Planet core, citadel/siege/terraforming/genesis, and ADR-0073 naming are all committed; tax_rate and landing_rights (ownership controls) are absent … · ⚠︎ contains code↔spec divergence (impl audit 2026-06-16)
Habitable / colonizable bodies and their lifecycle state. Companion docs: ../FEATURES/planets/colonization.md, ../FEATURES/planets/citadels.md, ../FEATURES/planets/defense.md.
Schema status¶
Per ADR-0066 D-V1, schema-level implementation status is consolidated here. Field descriptions describe the target schema.
Design-only on Planet:
ARTIFICIAL— one enum value ontypewith no world-generation or production path yet. The other 11 values (TERRA / DESERT / OCEANIC / ICE / VOLCANIC / BARREN / MOUNTAINOUS / GAS_GIANT / JUNGLE / ARCTIC / TROPICAL) are live canonical types.tax_rate,landing_rights— ownership-control fields per../FEATURES/planets/colonization.mdownership-controls section.
All other columns on this page are committed.
Planet¶
Source: services/gameserver/src/models/planet.py
Purpose: Habitable / colonizable body in a sector; the long-form economic and defensive base for players.
Fields:
| name | type | constraints | notes |
|---|---|---|---|
| id | UUID | PK | |
| name | String(100) | not null | original worldgen string; the final fallback in the display chain |
| auto_name | String(100) | nullable | generated default name (654-name corpus + prefix/suffix compound generator, services/gameserver/src/services/planet_naming_service.py / data/planet_names.py); backfilled = name for pre-existing worlds, set at genesis. See ../FEATURES/galaxy/star-systems.md#planet-discovery-naming |
| custom_name | String(100) | nullable | discoverer-set name; layered over auto_name. Display precedence: custom_name → auto_name → name. Written by POST /api/v1/planets/{id}/name, gated on discovered_by |
| discovered_by | UUID FK players.id | nullable | the player who first discovered this world (null = undiscovered / worldgen-seeded); sole rename authority. Set when a player views the sector's /system |
| discovered_at | DateTime | nullable | timezone-aware timestamp of first discovery |
| sector_id | Integer | not null | integer alongside UUID |
| sector_uuid | UUID FK sectors.id | nullable, CASCADE | |
| owner_id | UUID | nullable | not a FK constraint — ownership is also tracked via the player_planets association table |
| type | Enum planet_type |
not null | 12 values total (per ADR-0014). 11 are live canonical types: TERRA / DESERT / OCEANIC / ICE / VOLCANIC / BARREN / MOUNTAINOUS / GAS_GIANT / JUNGLE / ARCTIC / TROPICAL. GAS_GIANT, JUNGLE, ARCTIC, and TROPICAL carry neutral 1.0 production multipliers (services/gameserver/src/services/planetary_service.py NEUTRAL_TYPE_EFFICIENCY); nexus_generation_service generates JUNGLE and TROPICAL as colonizable worlds and GAS_GIANT as an uncolonizable body. ARTIFICIAL has no world-generation or production path yet. Genesis devices roll into a subset of these per ADR-0014. |
| status | Enum planet_status |
default UNINHABITABLE | UNINHABITABLE/HABITABLE/COLONIZED/DEVELOPED/TERRAFORMING/DYING/RESTRICTED |
| size, position | Integer | defaults 5 / 3 | 1-10; orbital position |
| gravity | Float | default 1.0 | |
| specialization | String(50) | nullable | |
| atmosphere | String | nullable | |
| temperature, water_coverage, habitability_score, radiation_level | numeric | various | |
| resource_richness | Float | default 1.0 | 0.0-3.0 multiplier |
| resources | JSONB | default {} | |
| special_resources | ARRAY(String) | default [] | |
| fuel_ore, organics, equipment, fighters | Integer | defaults 0 | stockpiles |
| colonized_at | DateTime | nullable | |
| population, max_population | BigInteger | defaults 0 | Total demographic count — includes working-age colonists plus dependents (children, retirees, non-contributors). The actuarial number that drifts upward over a colony's lifetime. BigInteger for very large established colonies; widened in migration dbbfad27a7ef. max_population = habitability_score × 1,000 (canonical formula, see ../FEATURES/planets/colonization.md#population-capacity); recomputed when habitability changes. |
| population_growth | Float | default 0.0 | Per-tick growth rate applied to population (and proportionally to colonists). |
| colonists, max_colonists | Integer | default 0 / 1000 | Working-age contributing settlers — the gameplay-facing counter that drives production formulas. Always colonists ≤ population. max_colonists is the citadel-tier workforce cap (L1 1k → L5 200k per ../FEATURES/planets/citadels.md#levels-and-capacities); recomputed when the citadel upgrades. Population continues to grow at higher tiers as the city accumulates dependents. |
| fuel_allocation, organics_allocation, equipment_allocation | Integer | defaults 0 | Head-count of colonists assigned to each production role, not a percentage. Sum ≤ colonists; unallocated head-count is idle. Multiplied directly into the per-tick production formula — see ../SYSTEMS/planetary-production-tick.md. |
| economy, production | JSONB | defaults | production has fuel/organics/equipment/research keys |
| production_efficiency | Float | default 1.0 | |
| factory_level, farm_level, mine_level, research_level | Integer | defaults 0 | |
| defense_level, shields, weapon_batteries, defense_turrets, defense_shields, defense_fighters | Integer | defaults 0 | |
| last_attacked, last_production | DateTime | nullable | |
| active_events | JSONB | default [] | |
| under_siege | Boolean | default false | |
| siege_started_at, siege_attacker_id | mixed | nullable | siege state added in migration a1b2c3d4e5f6 |
| citadel_level | Integer | default 0 | 0-5 (migration e3f4a5b6c7d8) |
| citadel_upgrading | Boolean | default false | |
| citadel_upgrade_started_at, citadel_upgrade_complete_at | DateTime | nullable | |
| citadel_safe_credits, citadel_safe_max | BigInteger | defaults 0 | |
| citadel_drone_capacity | Integer | default 0 | |
| citadel_max_population | BigInteger | default 0 | |
| genesis_created | Boolean | default false | |
| genesis_device_id | UUID FK genesis_devices.id | nullable | |
| genesis_tier | String(20) | nullable | basic/enhanced/advanced (migration a3f7c2d91e54) |
| formation_status | String(20) | nullable | forming/complete |
| formation_started_at, formation_complete_at | DateTime | nullable | |
| region_id | UUID FK regions.id | nullable | |
| tax_rate | Float | default 0.0 | 0.00–0.20; production tax the planet owner takes from team-mate landings (see ../FEATURES/planets/colonization.md#ownership-controls) |
| landing_rights | JSONB | default {"mode": "public"} |
landing-rights JSONB; mode ∈ public / team_only / private / whitelist / denylist; whitelist and denylist are arrays of player UUIDs (see ../FEATURES/planets/colonization.md#ownership-controls) |
Relationships:
- owner → Player (many-to-many via player_planets association).
- sector → Sector (FK sector_uuid).
- genesis_device → GenesisDevice (the device that formed this planet — see ./genesis-devices.md).
- formation → PlanetFormation (1:1 — see ./genesis-devices.md#planetformation).
- region → Region (see ./galaxy.md#region).
player_planets (association)¶
Columns: player_id, planet_id (composite PK), acquired_at. Both FKs CASCADE delete.