Colonization & Colony Management¶
Covers the lifecycle from contracting pioneer transit at the region's Capital Sector through running a Planetary Capital.
Two paths to a colony¶
1. Traditional colonization¶
Requires: - 10,000 pioneers in cargo (1 cargo space each, riding in cryosleep transit pods). - 10,000 credits investment (the founding-grant fee paid to the destination claim). - An uncolonized planet you can land on.
Result: Outpost (Phase 1, citadel level 1) with 100–1,000 starting population.
2. Genesis Device terraforming¶
See galaxy/genesis-devices.md.
- Basic Genesis (1 device) → Outpost.
- Enhanced Genesis (3 devices) → Outpost (better planet-type roll).
- Advanced Genesis (Colony Ship sacrifice) → instant Settlement (Phase 2, citadel level 2) with 5,000 settled pioneers, +10% production, 4 turrets, basic shields.
Pioneer migration contracts¶
A planet doesn't begin with population — it begins with a transit contract. Volunteer pioneers continuously enrol with the regional Migration Authority for resettlement on frontier worlds, and each region's Capital Sector hosts the Pioneer Office that registers and dispatches them. Players broker pioneer transit by contracting at the Office, ferrying the cohort in cryosleep transit pods, and fulfilling the migration contract on landing. The cargo commodity colonists represents one cohort of pioneers in transit (one pioneer per cargo unit).
Securing a contract¶
- Pioneer migration contracts are issued only at the Capital Sector of every region (sector 1 in Terran Space; the random Capital in player regions; Central Nexus Starport Prime in the Gateway Plaza cluster of the Nexus).
- Class-0 station, special inventory.
- Always available — pioneer demand far exceeds available transit capacity.
Per-pioneer fee (✅ Shipped)¶
The per-pioneer fee is dynamically priced. Source: services/gameserver/src/services/trading_service.py — COMMODITY_PRICE_RANGES["colonists"] = {min: 30, max: 80}, calculate_dynamic_price().
Per-pioneer fee at the Pioneer Office is computed as:
supply_ratio = station.commodity.quantity / capacity # 0.0 – 1.0
midpoint = base_price × (1.5 - supply_ratio)
fee = midpoint × 1.15 (SELL_SPREAD)
final = clamp(fee, 30, 80)
Drivers:
- Pioneer roster depth at the Office is the only live signal — heavy contracting drains the available roster, raising the per-pioneer fee toward 80; periodic intake refreshes it back toward 30.
- The 15% spread is the same one used for every commodity (SELL_SPREAD = 1.15).
- Federation tax / region control do not currently feed into the formula.
Effective range a player will see: ~30–80 cr per pioneer, dependent on roster depth at contracting time. Bulk colonization runs (10,000 pioneers) deplete the roster enough to noticeably push the fee up mid-contract.
Transit¶
- 1 cargo space per pioneer (cryosleep transit pod).
- For 10,000 pioneers you need 10,000 cargo space — multiple trips for any non-Cargo Hauler ship.
- Standard cargo loss rules apply: pioneers lost on ship destruction; the contracts void and the regional roster reabsorbs replacements.
Fulfilling the contract¶
When you colonize:
- Cargo colonists decremented by 1,000 (pioneers disembark on the destination world).
- Credits decremented by 10,000 (founding-grant fee paid to the destination claim).
- Planet.colonists += 1,000 (matches the L1 Outpost cap; growth fills toward higher caps as the citadel upgrades).
- Planet.max_colonists initialized to the L1 cap (1,000); Planet.max_population initialized to habitability_score × 1,000.
- Player added to player_planets association table — recognized as the founder of record.
Planet types¶
Canonical planet types (models/planet.py:PlanetType). 5 are Genesis-rollable (OCEANIC, DESERT, ICE, VOLCANIC, MOUNTAINOUS — see ../galaxy/genesis-devices.md#planet-type-weights and ADR-0014). The rest appear only via natural sources — bang-imported planets, special encounters, operator-seeded sectors — never as Genesis output. nexus_generation_service generates JUNGLE and TROPICAL as colonizable worlds alongside the Genesis-rollable types; GAS_GIANT is a real body but cannot be landed on or claimed.
JUNGLE, TROPICAL, ARCTIC, and GAS_GIANT carry neutral 1.0 production multipliers (services/gameserver/src/services/planetary_service.py NEUTRAL_TYPE_EFFICIENCY).
| Type | Fuel mult | Organics mult | Equip mult | Fuel cap | Org cap | Equip cap | Growth/day | Habitability % | Native life chance |
|---|---|---|---|---|---|---|---|---|---|
| TERRA (Capital welcome) | 0 | 0 | 0 | ∞ | ∞ | ∞ | ∞ | 100 | — |
| MOUNTAINOUS | 0.6 | 0.4 | 1.5 | 8,000 | 5,000 | 15,000 | +0.3% | 60–75 | 40% |
| OCEANIC | 1.5 | 0.4 | 0.6 | 15,000 | 5,000 | 8,000 | +0.4% | 60–75 | 75% |
| DESERT | 0.4 | 1.5 | 0.6 | 5,000 | 15,000 | 8,000 | +0.2% | 30–45 | 25% |
| VOLCANIC | 1.0 | 0.0 | 2.0 | 8,000 | 0 | 15,000 | +0.1% | 10–25 | 10% |
| BARREN | 0.0 | 0.0 | 1.5 | 0 | 0 | 20,000 | −0.1% | 0 | 5% |
| ICE | 0.8 | 1.2 | 0.5 | 10,000 | 15,000 | 8,000 | −0.2% | 35–50 | 30% |
| TROPICAL | 1.0 | 1.0 | 1.0 | — | — | — | — | 80–100 | — |
| JUNGLE | 1.0 | 1.0 | 1.0 | — | — | — | — | 60–90 | — |
| ARCTIC | 1.0 | 1.0 | 1.0 | — | — | — | — | — | — |
| GAS_GIANT (uncolonizable) | 1.0 | 1.0 | 1.0 | — | — | — | — | — | — |
BARREN and ICE planets have negative natural growth — without continuous immigration or terraforming, the colony shrinks.
TROPICAL, JUNGLE, ARCTIC, and GAS_GIANT carry neutral 1.0 production multipliers; per-type stockpile caps, growth rates, and native-life chances are not yet defined for them. 📐 Design-only — these per-type tuning numbers await canonization; the neutral fallback applies in the interim.
Colony lifecycle phases¶
Colonies progress through five phases, each tied to a citadel level (see citadels.md for the structural side):
| Phase | Pop range | Citadel level | Notes |
|---|---|---|---|
| 1 — Outpost | 0–1,000 | 1 | Survival focus, minimal defense |
| 2 — Settlement | 1,001–5,000 | 2 | Basic shield, moderate production |
| 3 — Colony | 5,001–15,000 | 3 | Specialization, defense grid |
| 4 — Major Colony | 15,001–50,000 | 4 | Industrial scale, orbital platforms unlock |
| 5 — Planetary Capital | 50,001–200,000 | 5 | Fortress, max upgrades |
Promotion between phases requires meeting population, resource, and prerequisite thresholds — see citadels.md for the full upgrade matrix.
Production growth is multiplicative across phases: - Outpost → Settlement: ~5×. - Settlement → Colony: ~3×. - Colony → Major Colony: ~4×. - Major Colony → Planetary Capital: ~5×.
Population capacity¶
Two independent ceilings interact, and the runtime invariants must hold all of them simultaneously:
Planet.max_colonists— citadel-tier workforce ceiling. Driven by citadel level: L1 Outpost = 1,000, L2 Settlement = 5,000, L3 Colony = 15,000, L4 Major Colony = 50,000, L5 Planetary Capital = 200,000 (see citadels.md). Bumped automatically when the citadel upgrades. Caps the workforce-side production input.Planet.max_population— habitability-derived demographic ceiling. Total inhabitants (colonists + dependents — children, retirees, non-contributors).
Canonical formula:
max_population = habitability_score × 1,000
Examples: - Habitability 100 (TERRA) → 100,000 max population. - Habitability 60 (MOUNTAINOUS / OCEANIC) → 60,000. - Habitability 25 (VOLCANIC) → 25,000. - Habitability 0 (BARREN) → 0 — orbital habitats only.
The two ceilings work together — citadel caps the workforce, habitability caps total demographic — and never substitute for each other. A high-habitability planet at L1 still caps colonists at 1,000 (citadel-bound), but its population may grow toward the habitability ceiling as families and dependents accumulate. A low-habitability planet at L5 still caps total inhabitants at habitability × 1000 regardless of citadel tier.
Runtime invariants:
- colonists ≤ max_colonists (citadel cap).
- population ≤ max_population (habitability cap).
- colonists ≤ population (working-age subset of total demographic).
When habitability changes (terraforming completes, hazard mutates the score, etc.), max_population recomputes from the formula above — the recompute is a trigger fired by the habitability mutation, not a separate rule. Citadel upgrades fire the same recompute on max_colonists.
✅ Shipped — world generation derives max_population = habitability_score × 1,000 at colony seeding (services/gameserver/src/services/genesis_service.py:542, services/gameserver/src/services/nexus_generation_service.py:544); in-game habitability mutations recompute from the same formula.
The runtime habitability-effects helper (services/planetary_service.py:946 get_habitability_effects) reports effectiveMaxColonists = max_colonists × (habitability/100) — keep this view; it's the workforce-side limiter that pairs with max_population as the demographic-side limiter.
Population growth¶
Source: services/gameserver/src/services/planetary_service.py:914 (_calculate_production_rates).
Daily formula:
colonist_rate = colonists × 0.01 × (habitability_score / 100)
i.e. base growth = 1% per day, scaled linearly by habitability. With a specialization bonus applied:
colonist_rate ×= specialization.production.colonists # e.g. agricultural
Per-planet-type effective daily growth (base 1% × habitability midpoint):
| Type | Habitability midpoint | Effective daily growth |
|---|---|---|
| TERRA | 100 | ~1.0% |
| MOUNTAINOUS | 67 | ~0.67% |
| OCEANIC | 67 | ~0.67% |
| DESERT | 37 | ~0.37% |
| ICE | 42 | ~0.42% |
| VOLCANIC | 17 | ~0.17% |
| BARREN | 0 | 0% |
These formula-derived numbers are the canonical effective growth rates at the habitability midpoint of each type. The simpler "Growth/day" column in the planet-types table above (+0.3% / +0.4% / +0.2% / +0.1% / −0.1% / −0.2% across MOUNTAINOUS / OCEANIC / DESERT / VOLCANIC / BARREN / ICE; TERRA is uncapped) is a player-facing summary that abstracts the formula — players see the summary value in UI; the production tick uses the formula. The two views diverge because the summary uses simplified per-type baselines while the formula scales by actual current habitability.
Other growth modifiers¶
- Siege:
colonist_rate = 0whilePlanet.under_siegeis true (planetary_service.py:937). ✅ Shipped. - Specialization: agricultural / balanced configurations multiply colonist growth via
_calculate_specialization_bonuses. ✅ Shipped. - Specialization identity (per ADR-0087): a colony's specialization also shapes its non-economic strengths — Military gives ×1.5 planet-defense effectiveness in siege/combat, Research gives ×1.5 research-point output, and Balanced gives +10% all-round (production / defense / research). ✅ Shipped.
- Terraforming: raises
habitability_score, which directly raisescolonist_rate; see terraforming.md. Terraforming completion also floorspopulation_growthto 1.0 / 1.5 / 2.0 depending on tier (services/terraforming_service.py:481). - Negative natural growth for BARREN / ICE in the planet-type table: 📐 Design-only — current code clamps
habitabilityto a minimum of 1 before the multiplier and never produces a negative rate. To match the table, the production tick needs an explicit decline branch whenhabitability_score < threshold(e.g.,< 20).
Overcrowding¶
📐 Design-only. Neither max_population nor max_colonists is enforced as a cap on colonist_rate in planetary_service._calculate_production_rates. Target rule (legacy intent):
- At
population ≥ max_population: growth halts (colonist_rate = 0). - Above
0.9 × max_population: linear taper ofcolonist_ratefrom 100% → 0%. - No decay below the cap — overcrowding stops growth, it does not shrink the colony.
Implement in the production-tick path; cite services/gameserver/src/services/planetary_service.py:_calculate_production_rates.
Gourmet food luxury bonus¶
Status: 📐 Design-only — bonus is documented; production-tick code does not yet apply it.
A planet stockpile carrying any nonzero amount of gourmet_food receives a flat luxury bonus while supplies last:
- +5% to colonist growth rate (multiplies
colonist_rateafter habitability scaling). - +5% to production tick output (multiplies the per-bucket production amount before specialization bonuses).
The bonus consumes gourmet_food at 1 unit per 1,000 colonists per day (proportional to the population it's feeding). When the stockpile depletes, the bonuses cease until the planet is resupplied. Gourmet food is sourced from Class-10 stations (the canonical gourmet_food buyer/seller per economy/trading.md:30) or via interregional trade.
Why this is in the spec: gourmet food sits a tier above organics in the commodity catalog. Organics keeps the colony alive; gourmet food is the luxury input that makes a colony thrive.
Low-habitability resource cost penalty¶
📐 Design-only. Legacy spec calls for +20% resource costs (life support / environmental control) when habitability_score is below a threshold (target: < 30). No code path applies this penalty today — production output is multiplied by habitability, but no resource-consumption multiplier exists. If kept, document the threshold and apply the multiplier in the production tick alongside the existing siege multiplier.
Colonist allocation¶
Planet.fuel_allocation, organics_allocation, equipment_allocation — three buckets, each a head-count of colonists assigned to that role (Integer columns, not percentages). Sum may be ≤ Planet.colonists; any unallocated colonists are idle (no production, no consumption penalty). Adjustable any time, instantly, no cost. The production-tick formula multiplies these head-counts directly into the per-commodity rate (see ../../SYSTEMS/planetary-production-tick.md#production-rates).
Production: see production.md.
Optimal allocation depends on planet type. Example with 10,000 colonists: - Oceanic (1.5× fuel): 7,000 fuel / 1,500 organics / 1,500 equipment. - Mountainous (1.5× equipment): 1,500 / 1,500 / 7,000. - Other types: allocate based on the type's multiplier profile and empire needs (e.g., DESERT favors organics, VOLCANIC favors equipment, ICE has no strong dominant axis).
The percentage-style examples some legacy notes used (e.g., "70% fuel") are presentation-layer only — the player UI may render allocations as sliders that map percentages to head-counts, but the persisted columns and the production-tick math are head-counts.
Colony management actions¶
Daily¶
- Withdraw produced resources (production stops at storage cap).
- Adjust allocation as market prices shift.
- Monitor drone count and shield strength.
Strategic¶
- Citadel upgrades (resources + time + prerequisites; see citadels.md).
- Production upgrades (+10% per level, max level 10 per resource).
- Defensive investments (drones, shields, orbital platforms, rail guns; see defense.md).
- Terraforming (see terraforming.md).
Ownership controls¶
- Transfer ownership to another player (5% transfer fee, recipient must accept).
- Abandonment & inactivity reclamation (PL4b —
abandonment_service.py, the single writer): two paths revert a planet to unowned while structures / citadel / population / resources persist on the row (that developed-world inheritance is the reclaim premium). - Voluntary abandon (
POST /planets/{planet_id}/abandon, owner-only): forfeiture, 0 compensation, blocked while the planet is under siege. ✅ Shipped. - Involuntary inactivity reclaim: a daily sweep flags a planet whose owner's
last_game_loginis older thanINACTIVITY_DAYS(90 days); aRECLAIM_GRACE_DAYS(7-day) window after the flag must pass before any other player may reclaim.POST /planets/{planet_id}/reclaimcharges the reclaimer a flat 50,000 cr + 5,000 each of ore/organics/equipment, atomic with the ownership flip.GET /planets/{planet_id}/reclaim-statusexposes the flag / grace-end / eligibility for the UI. ✅ Shipped. - Displaced-owner compensation: see Displaced-owner compensation below.
- Landing rights (
Planet.landing_rightsJSONB): one of five modes —public(anyone),team_only(owner's team-mates only),private(owner only),whitelist(specific player UUIDs inlanding_rights.whitelist[]),denylist(anyone except UUIDs inlanding_rights.denylist[]). Mode changes apply immediately to subsequent landing attempts; ships already on-planet are not evicted by a mode change. ✅ Shipped —_check_landing_allowedenforces all five modes fail-closed; the owner-onlyPUT /planets/{planet_id}/landing-rightssetter writes the mode. - Tax rate (
Planet.tax_rate, Float 0.00–0.20): owner can charge a production tax on team-mates landing on the planet (extracts a percentage of resources withdrawn from planet stockpiles to the team-mate's cargo, deposits to the owner's safe). Defaults to 0.0 (no tax) for owner-team and friendlies; non-team landings always pay 0% (no tax mechanism for non-team since they shouldn't be landing in the first place under most landing-rights modes). 🚧 Partial — the column is reserved (Float, nullable) but the skim is not wired: no taxable resource-egress event has a route, so no percentage is extracted today.
Displaced-owner compensation¶
When an inactive owner is displaced by an involuntary reclaim, they are paid COMPENSATION_FRACTION = 0.4 × sunk cost, where sunk cost is claim_fee + Σ CITADEL_LEVELS[n].upgrade_cost for n = 2..level (anchored to the real in-code citadel upgrade ladder: L2 = 50k, L3 = 150k, L4 = 500k, L5 = 2M). The payout is capped at the sunk cost so the flow can never be a money pump, and is paid only if the displaced owner's tenure was ≥ TENURE_FLOOR_DAYS (7 days). For an L0/L1 planet (upgrade_cost 0) the payout is 0.4 × 10,000 = 4,000 against a 10,000 claim fee — a guaranteed loss, so abandon/reclaim is never net-positive. Source: abandonment_service.py:39-49. ✅ Shipped.
🚧 Partial — transfer fees and the tax-rate skim remain documented-but-unwired; abandonment, reclamation, and the five-mode landing-rights ACL are shipped.
Player-facing affordances¶
- Planet management UI: phase, population, growth rate, allocation sliders, storage levels, defense rating.
- Resource collection panel (transfer to docked ship's cargo).
- Citadel upgrade timer with prerequisite tracker.
- Map overlay showing all your owned planets across regions.
- Income feed showing passive credit/resource gains.
- Population graphs and "days until citadel cap" projections.
Colonist profession system¶
📐 Design-only. A profession layer sits over the three-bucket allocation model: generic colonists are trained (irreversibly) into twelve specialized roles (Engineering, Scientific, Military, Economic) that stack percentage bonuses on top of base production, defense, research, and terraforming. Specialization cap scales with citadel phase from 0% at Outpost to 75% at Planetary Capital, and training requires citadel L3+. No code path exists today — Planet has no profession column and there is no colonist_professions table.
Full mechanics, the per-profession bonus table, training and retraining flow, cross-system effects, and target source-file map live in professions.md.
Source map¶
| Topic | Path |
|---|---|
| Planetary service | services/gameserver/src/services/planetary_service.py |
| Growth + production tick | services/gameserver/src/services/planetary_service.py:_calculate_production_rates |
| Habitability effects helper | services/gameserver/src/services/planetary_service.py:get_habitability_effects |
| Planet model | services/gameserver/src/models/planet.py |
| Player ↔ planet association | services/gameserver/src/models/planet.py:player_planets |
| Planet API routes | services/gameserver/src/api/routes/planets.py |
| Admin colonization tools | services/gameserver/src/api/routes/admin_colonization.py |
| Genesis-based creation | services/gameserver/src/services/genesis_service.py |
| Citadel upgrades | services/gameserver/src/services/citadel_service.py |
| Terraforming | services/gameserver/src/services/terraforming_service.py |
| Population commodity pricing | services/gameserver/src/services/trading_service.py (COMMODITY_PRICE_RANGES["colonists"], calculate_dynamic_price) |