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:
- Verify planet is owned by the player.
- Verify
habitability_score < TERRAFORMING_MIN_TARGET(90). - Verify no terraforming already active on the planet.
- Verify player credits and planet stockpile cover the level's recipe.
- Deduct credits from player; deduct organics + equipment from planet stockpile.
- Set
Planet.terraforming_active = True,terraforming_target,terraforming_start_time,terraforming_progress = 0.0,status = TERRAFORMING. - Push a metadata entry into the planet's
active_eventsJSONB 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:
+1perTERRAFORMING_POPULATION_SCALE = 1000colonists/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.
🚧 Partial — process_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_populationandmax_colonistsascurrent * (habitability_score / 100). - Floor
population_growthat: - 2.0 if habitability ≥ 80,
- 1.5 if habitability ≥ 60,
- 1.0 if habitability ≥ 40.
- Clear
terraforming_active,terraforming_target,terraforming_start_time; setterraforming_progress = 100.0. - Remove the terraforming entry from
active_events. - Set
status = COLONIZED(if populated) orHABITABLE(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 = +1per 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 |