Skip to content

Genesis Deploy

Purpose

Genesis devices are the only mechanism for creating new planets in the universe. The genesis-deploy pipeline runs the pre-flight check, registers a "forming" planet on the sector, kicks the 48-hour formation timer (or skips it for the advanced ship-sacrifice tier), and finalizes the planet on completion. The pipeline is transactional, rate-limited, and integrates with combat (formed-planet defense) and the realtime bus (progress events).

Inputs

The pipeline reads: - The deploying Player row (locked) — current_ship_id, current_sector_id, credits, is_docked, is_landed, settings.genesis_purchases. - The current Ship row — type, genesis_devices cargo capacity, hull/shield headroom. - The target Sector — counts existing planets, faction permissions, sector legality. - GENESIS_TIERS config — cost, planet-type weights, habitability range, resource richness, size range, ship-sacrifice flag. - GENESIS_CAPACITY_BY_SHIP — per-ship-type device capacity. - MAX_PURCHASES_PER_WEEK = 3, MAX_PLANETS_PER_SECTOR = 5.

The system fires on: - POST /api/v1/genesis/deploy{sector_id, tier}. - GET /api/v1/genesis/planet/{id}/status — formation status query (auto-completes if elapsed). - Scheduled tick — auto-completes any formation whose formation_complete_at has passed without a status query.

Process

Pre-flight (atomic, lock held)

1.  validate tier ∈ {basic, enhanced, advanced}
2.  load Player WITH ROW LOCK
3.  load Ship (Player.current_ship_id)
4.  assert Ship not None
5.  assert Player.current_sector_id == sector_id
6.  assert not Player.is_docked
7.  assert not Player.is_landed
8.  load Sector; assert exists
9.  count(Planets in sector) < MAX_PLANETS_PER_SECTOR
10. weekly_purchase_count(Player) < MAX_PURCHASES_PER_WEEK
11. Player.credits >= tier.cost
12. ship_genesis_capacity(Ship) > 0
13. if tier.requires_ship_sacrifice:
        assert Ship.type == COLONY_SHIP
14. (optional design) sector legality:
        - sector not in protected zone
        - distance from Federation Space ≥ 5 jumps
        - distance from nearest existing planet ≥ 2 sectors
        - faction permission (region governance / treaty)
15. (optional design) anti-monopoly:
        Player owns ≤ 25% of region's planets

Any check failing aborts the transaction with a clear error before any mutation.

Deployment sequence — standard tier

                ┌──────────────────────┐
                │  Pre-flight passes   │
                └──────────┬───────────┘
                           ▼
                ┌──────────────────────┐
                │  Roll planet attrs:  │
                │  - planet_type       │ (weighted by tier)
                │  - habitability      │ (range from tier)
                │  - resource_richness │
                │  - size              │
                │  - generated name    │
                └──────────┬───────────┘
                           ▼
                ┌──────────────────────┐
                │  Insert Planet row   │
                │   status=TERRAFORMING│
                │   formation_status=  │
                │     "forming"        │
                │   formation_started  │
                │   formation_complete │
                │     = now + 48h      │
                │   resources = 0      │
                │   owner = player     │
                └──────────┬───────────┘
                           ▼
                ┌──────────────────────┐
                │  Player.credits     -│
                │  weekly purchase log │
                └──────────┬───────────┘
                           ▼
                ┌──────────────────────┐
                │  Insert player_     +│
                │   planets ownership  │
                └──────────┬───────────┘
                           ▼
                ┌──────────────────────┐
                │  Commit transaction  │
                │  Emit realtime event │
                │  genesis_deployed    │
                └──────────────────────┘

Deployment sequence — advanced tier (Colony Ship sacrifice)

Same pre-flight + roll, then:

1. Insert Planet immediately as STATUS = "complete"
   - formation_status = "complete"
   - resources seeded per planet type
   - habitability bonus applied (Settlement phase, citadel level 2,
     5,000 colonists, +10% production, 4 turrets, basic shields)
2. Mark Ship.is_destroyed = True, Ship.is_active = False, Ship.status = "DESTROYED"
3. Set Player.current_ship_id = None  (ship-service later assigns escape pod)
4. Player.credits -= 250,000
5. Insert ownership
6. Commit
7. Emit `genesis_deployed` (advanced) + `ship_destroyed` (sacrifice)

The advanced tier bypasses the 48-hour wait at the cost of the entire Colony Ship.

Formation timer & completion

The formation phase is wall-clock based, not turn-based:

  1. Planet.formation_complete_at = formation_started_at + 48h.
  2. Two completion paths:
  3. Lazy — any GET /api/v1/genesis/planet/{id}/status request that finds now ≥ formation_complete_at calls _complete_formation(planet) and commits.
  4. Scheduled — a background tick scans Planet WHERE formation_status = 'forming' AND formation_complete_at < now, completes each, broadcasts.
  5. _complete_formation(planet):
  6. Set formation_status = "complete".
  7. Set status = HABITABLE (or per-type equivalent).
  8. Seed initial resources (fuel_ore, organics, equipment) from tier and richness.
  9. Initialize colonists = 0, max_colonists = size * 2000.
  10. Emit genesis_complete and notification to owner.

During the 48-hour window: - Player is intended to remain in the sector ("locked"); leaving may forfeit (design choice). - The player's action cap can be reduced for the duration (design: 50 turns/day). - Other players entering the sector see the forming planet but cannot interact with it (no land, no attack).

Rate limiting

  • MAX_PURCHASES_PER_WEEK = 3 enforced via a rolling-7-day count from Player.settings.genesis_purchases.
  • Each purchase appends {tier, timestamp}; old entries pruned during read.
  • MAX_PLANETS_PER_SECTOR = 5 enforced at pre-flight via SQL count.

Multi-player Genesis (design)

For team genesis (multiple players pooling devices on a shared planet): - All members must remain in the sector for the 48 h. - Ownership shares recorded on player_planets.contribution_percent. - Departure of any member fails the sequence — devices lost.

Outputs / state changes

Per deployment: - Planet row inserted (forming or complete depending on tier). - player_planets ownership row. - Player.credits decremented. - Player.settings.genesis_purchases appended. - For advanced tier: Ship.is_destroyed = True, Player.current_ship_id = None.

Per formation completion: - Planet.formation_status, status, resources updated. - Audit log entry.

Events emitted: - genesis_deployed — sector room + personal. - genesis_progress — periodic (every 5%) personal updates during the 48 h. - ship_destroyed — advanced tier only. - genesis_complete — sector + personal on finalization. - notification — personal milestones.

Invariants

  1. Pre-flight runs entirely under a player row lock — no two simultaneous genesis purchases beat the rate limit.
  2. Pre-flight is all-or-nothing: a failed check rolls back any partial credit deduction.
  3. Planet.formation_complete_at > formation_started_at always.
  4. MAX_PLANETS_PER_SECTOR is never exceeded — even under race; the count happens inside the locked transaction (use SELECT … FOR UPDATE on sector rows or repeat the count after insert).
  5. Advanced tier consumes the Colony Ship in the same transaction as the Planet insert.
  6. A forming planet cannot be attacked or landed on — handled by the combat resolver and planetary service.
  7. Player.credits ≥ 0 after deduction.
  8. A failed deployment does not leave devices, credits, or ships in a half-spent state.

Failure modes

Mode Target handling
Sector at planet cap Pre-flight rejects with 400 Sector at planet limit.
Insufficient credits Pre-flight rejects with 402 Insufficient credits.
Wrong ship for advanced tier Pre-flight rejects with 400 Advanced tier requires Colony Ship.
Player docked or landed Pre-flight rejects with 400.
Sector illegal (faction / proximity rules) Pre-flight rejects with 403.
Rate-limit exceeded Pre-flight rejects with 429 Weekly genesis cap reached.
Player leaves sector during 48 h (design forfeiture) Background tick checks Player.current_sector_id periodically; on sustained absence, marks planet formation_status = "failed" and refunds 50% credits (design).
Sabotage attack mid-formation Combat resolver guards: forming planets are not valid attack targets (return 400 Planet not yet formed).
Server crash during transaction DB rollback restores pre-deploy state.
Background tick misses a completion Lazy status query catches it on next read.
Ownership-share calculation drift in team genesis Sum of contribution_percent enforced = 100 by check constraint.
Concurrent deploy in same sector Row lock on player + sector serializes; second request sees updated planet count and may be rejected.

Source map

Concern Path (target)
Genesis service services/gameserver/src/services/genesis_service.py
Tier config + capacity tables same file (GENESIS_TIERS, GENESIS_CAPACITY_BY_SHIP)
Rate-limit storage Player.settings.genesis_purchases (JSONB)
Planet model services/gameserver/src/models/planet.py
Sector legality services/gameserver/src/services/galaxy_service.py, regional_governance_service.py
Genesis API routes services/gameserver/src/api/routes/genesis.py
Background completion tick services/gameserver/src/services/genesis_service.py:tick_formations (target)
Realtime broadcast services/gameserver/src/services/websocket_service.py