Skip to content

Terraforming

Shipped — five-level project ladder, flat-column persistence, habitability-points model.

Long-term improvements to existing colonies' habitability. Distinct from Genesis Devices (which create planets — see galaxy/genesis-devices.md).

The model is habitability points, not growth percentages: each level adds a fixed integer to Planet.habitability_score (0–100), and habitability drives population cap, growth multiplier, and morale through a single shared formula in planetary_service.get_habitability_effects. See ADR-0002 for the design rationale.

Five-level project ladder

Authoritative source: services/gameserver/src/services/terraforming_service.py:TERRAFORMING_LEVELS.

Level Name Cost (cr) Duration (h) Habitability boost Organics Equipment
1 Basic Atmospheric 100,000 72 +10 500 200
2 Climate Stabilization 250,000 120 +15 1,500 500
3 Ecosystem Seeding 500,000 168 +20 3,000 1,000
4 Biome Engineering 1,000,000 240 +25 5,000 2,000
5 Full Terraformation 2,000,000 336 +30 10,000 5,000

Boost is applied as a single integer addition to habitability_score, capped at TERRAFORMING_MAX_HABITABILITY = 100.

Resource sourcing: organics and equipment are drawn from the planet's own stockpile (Planet.organics, Planet.equipment) — not from the player's ship cargo. The level cannot start if either stock is below the requirement. Credits are deducted from the player.

Levels are independent, not sequential. The code does not enforce "Level 2 requires Level 1 complete" or any citadel-level prerequisite. Any owned planet below the skip threshold can start any level if resources are available.

Mechanics

services/terraforming_service.py:start_terraforming:

  1. Verify planet is owned by the player.
  2. Verify habitability_score < TERRAFORMING_MIN_TARGET (90).
  3. Verify no terraforming already active on the planet.
  4. Verify player credits and planet stockpile cover the level's recipe.
  5. Deduct credits from player; deduct organics + equipment from planet stockpile.
  6. Set Planet.terraforming_active = True, terraforming_target, terraforming_start_time, terraforming_progress = 0.0, status = TERRAFORMING.
  7. Push a metadata entry into the planet's active_events JSONB list with shape {type: "terraforming", level, level_name, credit_cost, organics_cost, equipment_cost, habitability_boost, duration_hours, started_at}.

Tick-based progression

process_terraforming_tick(planet_id) advances habitability by 1–3 points, scaled by population:

  • Base increment: TERRAFORMING_BASE_INCREMENT = 1.
  • Population bonus: +1 per TERRAFORMING_POPULATION_SCALE = 1000 colonists/population.
  • Cap: TERRAFORMING_MAX_INCREMENT = 3.

So a planet with ≥ 2,000 population terraforms at the maximum 3 points/tick; a planet with < 1,000 progresses at the minimum 1 point/tick.

🚧 Partialprocess_terraforming_tick exists and is correct, but no scheduler currently calls it. Nothing in the codebase invokes the tick today; running it requires manual API or admin action. Wiring it into the regular planet-tick worker is outstanding work.

Completion

_complete_terraforming runs when habitability_score reaches terraforming_target:

  • Apply the level's habitability_boost (capped at 100).
  • Recompute max_population and max_colonists as current * (habitability_score / 100).
  • Floor population_growth at:
  • 2.0 if habitability ≥ 80,
  • 1.5 if habitability ≥ 60,
  • 1.0 if habitability ≥ 40.
  • Clear terraforming_active, terraforming_target, terraforming_start_time; set terraforming_progress = 100.0.
  • Remove the terraforming entry from active_events.
  • Set status = COLONIZED (if populated) or HABITABLE (if empty).

Cancellation

TERRAFORMING_CANCEL_REFUND = 0.50 — cancelling a project refunds 50% of the credit cost. Organics and equipment are not refunded (treated as consumed in-process).

Skip threshold

Planets with habitability_score ≥ 90 (TERRAFORMING_MIN_TARGET) cannot start a new project — start_terraforming raises.

Habitability effects

planetary_service.get_habitability_effects:

  • effective_max_colonists = base_max_colonists * (habitability / 100).
  • growth_multiplier = habitability / 100 (applied to base growth).
  • morale_bonus = +1 per 10 habitability above 50.

Population growth in _calculate_production: colonist_rate = colonists * 0.01 * (habitability / 100) per day.

This is how habitability points translate to the growth-rate intuition. A Level 1 terraform on a starting-habitability-50 planet (+10 → 60) raises the growth multiplier from 0.50 to 0.60, a 20% relative increase. A Level 5 from 50 to 80 takes it from 0.50 to 0.80, a 60% relative increase.

Planet model state

The terraforming columns on planets (added in migration b2c3d4e5f6a7_add_terraforming_columns_to_planets):

Column Type Purpose
terraforming_active Boolean Project is in progress.
terraforming_target Integer (nullable) Target habitability score for the active project.
terraforming_start_time DateTime (nullable) When the active project began.
terraforming_progress Float 0.0–100.0, percentage of target reached.

Per-level metadata (cost, boost, duration, level name) lives in the planet's active_events JSONB column under a {type: "terraforming"} entry. There is no separate terraforming_projects table — see ADR-0002. Multiple concurrent projects on a single planet are not representable.

Planet types

The full enum is in DATA_MODELS/entities.md (12 values: TERRAN, MOUNTAINOUS, OCEANIC, DESERT, VOLCANIC, BARREN, ICE, JUNGLE, ARCTIC, TROPICAL, GAS_GIANT, ARTIFICIAL). The eight types in active gameplay use, with their per-type production multipliers, storage caps, base growth rates, and habitability ranges, are catalogued in colonization.md. The Star-Trek-class ↔ descriptive-name mapping is M_CLASS = TERRAN, L_CLASS = MOUNTAINOUS, O_CLASS = OCEANIC, K_CLASS = DESERT, H_CLASS = VOLCANIC, D_CLASS = BARREN, C_CLASS = ICE.

JUNGLE, ARCTIC, TROPICAL, GAS_GIANT, and ARTIFICIAL are present in the enum but have no production-multiplier definitions in colonization.md. Treat them as design-only until the Star-Trek-class mapping is extended.

📐 Design-only — planet-type reclassification. The legacy design specified that completing Level 5 may upgrade a hostile planet's type (D_CLASS → H_CLASS, C_CLASS → K_CLASS). The implemented _complete_terraforming does not modify planet.type; only habitability_score changes. If reclassification becomes desired again, the rule belongs in _complete_terraforming and would need a deliberate ADR amendment.

📐 Design-only — cost scaling at high habitability. The legacy spec scaled cost by ×1.25 above 40, ×1.5 above 70, ×2.0 above 90 starting habitability. Live costs are flat per level. The skip threshold at 90 makes the ×2.0 band moot in practice; the ×1.25 / ×1.5 bands could be restored as level_config["cost"] * scaling_factor(planet.habitability_score) if needed.

📐 Design-only — Terraform Engineers profession. The legacy PLANETARY_COLONIZATION.md design includes a Terraform Engineers profession (training queue, monthly progress driven by engineer count, scaling resource costs). No profession system exists in code today. The current model derives tick speed from total population, not specialised engineers.

Strategic considerations

  • Early game: prefer Genesis Devices for new planets — much cheaper than full terraforming an existing hostile world.
  • Mid game: Level 1–2 terraform on M/L/O-Class planets to lift habitability into the 60–80 band where the growth multiplier and morale bonus compound.
  • Late game: Level 5 to push strategically-located worlds (e.g. a Barren planet on a critical trade route) toward 100 habitability, unlocking maximum population cap and growth.

ROI sketch:

  • Advanced Genesis (350,000 cr) → ~30 days to break-even on Settlement-phase production.
  • Full sequence Level 1 → 5 (3,850,000 cr + 20,000 organics + 8,700 equipment) → ~180 days to break-even on a rescued Barren world (capped at 100 habitability, but the climb from 0 takes the full ladder).

The terraform path makes sense only when the planet's location justifies the long payoff.

Player-facing affordances

  • Terraforming panel per planet showing current habitability, active project, time remaining, expected boost.
  • Cost preview before starting (credits + planet-stockpile organics + planet-stockpile equipment).
  • Cancel button surfacing the 50%-credits refund warning and that resources are not refunded.
  • Empire view showing terraforming progress across all owned planets.

Source map

Topic Path
Terraforming service services/gameserver/src/services/terraforming_service.py
Habitability effects on capacity / growth / morale services/gameserver/src/services/planetary_service.py:get_habitability_effects
Per-day colonist growth services/gameserver/src/services/planetary_service.py:_calculate_production
Planet model services/gameserver/src/models/planet.py
Terraforming columns migration services/gameserver/alembic/versions/b2c3d4e5f6a7_add_terraforming_columns_to_planets.py
Genesis (related) services/gameserver/src/services/genesis_service.py
Planet API services/gameserver/src/api/routes/planets.py
Admin terraforming view services/gameserver/src/api/routes/admin_colonization.py
Design rationale ADR/0002-terraforming-formula-model.md