Skip to content

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 on type with 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.md ownership-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; modepublic / team_only / private / whitelist / denylist; whitelist and denylist are arrays of player UUIDs (see ../FEATURES/planets/colonization.md#ownership-controls)

Relationships: - ownerPlayer (many-to-many via player_planets association). - sectorSector (FK sector_uuid). - genesis_deviceGenesisDevice (the device that formed this planet — see ./genesis-devices.md). - formationPlanetFormation (1:1 — see ./genesis-devices.md#planetformation). - regionRegion (see ./galaxy.md#region).

player_planets (association)

Columns: player_id, planet_id (composite PK), acquired_at. Both FKs CASCADE delete.