Multi-Regional Restructuring¶
Status: 🚧 Partial — Region model, governance API, Nexus generation, and auth service are built; webhook-to-container-provisioning gap means no actual Docker region spins up on subscription … (Re-verified 2026-08-21 vs origin/feat
46bce720— tip delta Admin Soft-ORDER #789/#788 honesty only; Soft-HOLD residuals unchanged.)
SectorWars 2102 runs as a Central Nexus hub (5000 sectors organized into 20 thematic clusters) plus per-region territories — Standard tier ~1000 sectors with ±20% variability — that players own via PayPal subscription. The galaxy evolves only by attaching new regions to the Nexus; in-place expansion is not a launch mechanic (see ADR-0006).
1. Architecture¶
Central Nexus¶
5000 sectors organized into 20 thematic clusters (Commerce, Diplomatic, Industrial, Residential, Transit, Security, Cultural, Research, Free-Trade, Gateway Plaza, plus 10 more — full taxonomy + sector ranges in ../SYSTEMS/central-nexus-clusters.md).
Galactic governance sits on a council, with the Nexus acting as the universal trade hub for all regional territories. The Nexus's Capital Sector lives inside the Gateway Plaza cluster — that's where cross-region travelers arrive (the "petal connection point").
Regional territories¶
- Sized by subscription tier; Standard tier targets ~1000 sectors with ±20% variability (range 800–1200). Higher tiers (Premium / Mega — 📐 Design-only) widen the upper bound.
- Sectors are numbered locally inside each region; the canonical identifier is the compound
(Region, Cluster, sector_number)— sector numbers are not globally unique. - Each region has a Capital Sector (welcome hub) randomly placed within its Federation Zone, so cross-region visitors must explore to find each region's hub. See
../SYSTEMS/galaxy-generation.md#step-8-capital-sector. - Subscription tiers via PayPal: $25/mo regional ownership, $5/mo galactic citizenship.
- Configurable governance: Democracy, Autocracy, Council Republic.
- Configurable economy: tax rate (5-25%), starting credits (100-10,000), trade bonuses (1.0-3.0x), economic specialization.
- Cultural identity (language pack, aesthetic theme, traditions, motto).
Container topology¶
Topology lives in the root docker-compose.yml (Sectorwars2102), selected with Compose profiles — there is no separate docker-compose.multi-regional.yml file. Canonical service picture also in ../ARCHITECTURE/multi-regional.md and ../ARCHITECTURE/deployment.md.
docker compose --profile multi-regional up
# or: docker compose --profile production up
Central Nexus / multi-regional profile services (names match Compose service keys):
nginx-gateway— public HTTP/HTTPS entry (not a separatenexus-gatewayimage name).central-nexus-server— Nexus gameserver role (SERVICE_TYPE=central-nexus).central-nexus-db— Postgres for the Nexus.redis-nexus— Redis for Nexus / cross-region traffic.redis-cache— shared cache (also used by the default/dev profile).regional-server-template— recipe under the regional-template profile; not started by a normal multi-regionalup—region-managerclones it per provisioned region.region-manager— orchestrator (provision / scale / terminate).player-client,admin-ui— frontends.- Monitoring (
prometheus,grafana) when themonitoringprofile is also enabled.
Networks follow the Compose file (sectorwars-network, nexus-network, etc.) — do not invent a parallel nexus_network / regional_network CIDR story here; operator hosting docs own host-specific addressing.
Service ports¶
| Service | Container port | Notes |
|---|---|---|
nginx-gateway |
80 / 443 | Public HTTP / HTTPS entry |
central-nexus-server |
8080 | Gameserver API for the Nexus |
central-nexus-db |
5433 (host map typical) | Postgres for the Nexus |
redis-nexus |
6379 | Redis for the Nexus |
region-manager |
8081 | Orchestrator (region provision / scale / terminate) |
player-client |
3000 | Static frontend for players |
admin-ui |
3001 | Static frontend for admins |
prometheus |
9090 | Metrics scrape (monitoring profile) |
grafana |
3002 | Dashboards (monitoring profile) |
Per-region resource allocation¶
| Resource | Min | Default | Max |
|---|---|---|---|
| CPU (vCPU) | 1 | 2 | 8 |
| Memory (GB) | 2 | 4 | 16 |
| Storage (GB) | 10 | 20 | 100 |
| Concurrent players | 10 | 100 | 1000 |
Auto-scale triggers: scale up at >80% CPU or >85% memory sustained; scale down at <20% CPU and <30% memory sustained.
2. Code surface¶
Database schema — regions, regional_memberships, regional_policies, regional_elections, regional_votes, regional_treaties, inter_regional_travels, plus an enhanced sectors table with region_id, cluster_id, security_level, development_level, traffic_level.
Models — Region, RegionalMembership, InterRegionalTravel in gameserver.
Services — regional_governance_service.py, nexus_generation_service.py (regional_auth_service.py deleted 1619912d; GC travel uses Player.is_galactic_citizen / ship_upgrade_service.is_galactic_citizen, not a RegionalRole module).
API:
- /api/v1/regions/* — owned region info, stats, economy/governance config, policy proposals, elections, treaties, culture, members.
- /api/v1/nexus/* — status, stats, districts, generate/regenerate nexus, regenerate district.
Multi-region-owner disambiguation (/my-region/*) — ✅ Shipped, live-verified (907c0c7c; ADR-0093 item 4). /api/v1/my-region/* takes an explicit region_id query param:
- A caller who owns exactly one region can omit region_id — it resolves to their sole region unaffected.
- A caller who owns 2+ regions and omits region_id gets 400 ERR_AMBIGUOUS_REGION_OWNER, with the response body listing their owned regions so the client can prompt a pick.
- A caller who supplies a region_id they don't own, or that doesn't exist, gets a flat 403 — the two cases are indistinguishable in the response, so the endpoint never leaks whether a given region ID exists.
Admin UI — pages/CentralNexusManager.tsx and pages/RegionalGovernorDashboard.tsx (7-tab interface for Overview, Governance, Economy, Policies, Elections, Diplomacy, Culture).
Player client — regional-selection UI, cross-regional travel view, and player-facing governance panel.
3. Subscription / provisioning flow¶
Player → PayPal: subscribe ($25/mo)
PayPal → Platform: webhook
Platform → region-manager: provision request
region-manager → Docker: create containers from template
Docker → region-manager: containers ready
region-manager → Central Nexus: register region
Provisioning steps: 1. Validate subscription status. 2. Create isolated database. 3. Generate region configuration. 4. Deploy container stack from template. 5. Register with Central Nexus. 6. Configure inter-regional routing.
Termination: 1. 30-day evacuation notice to players. 2. Backup + export. 3. Container cleanup. 4. DB removal. 5. Network cleanup.
4. Performance targets¶
| Metric | Launch target | Notes |
|---|---|---|
| Central Nexus generation | 15-20 min for 5000 sectors | One-shot at galaxy bootstrap |
| Regional stats query | <2 s | |
| Policy CRUD | <1 s | |
| Dashboard load | <3 s | |
| Complex regional aggregations | <500 ms | |
| Concurrent active player-owned regions | 50 (soft target) | Per ADR-0051 SK25. Operator dashboards alert at 75% (37–38 regions). No hard cap per ADR-0050 SK23. |
| Players per region | 500+ concurrent | |
| Nexus capacity | 10,000+ concurrent |
API SLO: p95 <1 s response. Pool utilization <80%, CPU <70%, memory <80%.
Scaling path¶
Per ADR-0051 SK25, post-launch scaling proceeds in three layers:
- Vertical — bigger DB instance, more RAM, more compute. First lever; lowest operational risk.
- Horizontal — region sharding across multiple gameserver clusters. The existing multi-regional architecture per ADR-0001 is already region-isolated, so horizontal scale-out is a known-shape migration.
- Archival — idle regions auto-tombstone after 6 months of zero player activity (zero logins from any resident, zero traversals through the region's Nexus warp). Tombstoned regions unload from active memory but stay on disk for fast resurrection if a player returns. Frees capacity for new active regions without deleting paying-subscriber state.
5. Operations¶
Setup¶
# Prefer Compose profiles on the root file (no docker-compose.multi-regional.yml).
# setup-multi-regional.sh may still exist as a helper — script truth is a separate
# gameserver WO; this doc describes the working Compose entrypoint.
cp .env.example .env # or operator-supplied env with PayPal / DB / JWT secrets
docker compose --profile multi-regional up -d
CLI¶
./scripts/region-cli.py list
./scripts/region-cli.py show <region>
./scripts/region-cli.py scale <region> --cpu 4 --memory 8 --disk 40
./scripts/region-cli.py config sample-region.yml
Health / metrics¶
curl http://localhost/api/v1/status/health
curl http://localhost/api/v1/region-manager/metrics
docker-compose logs -f central-nexus-server
docker-compose logs -f region-<name>-server
Grafana dashboards at http://localhost:3002.
Backup¶
- Central Nexus: daily full + hourly incremental.
- Regional: daily per region.
- Configuration: git.
- Retention: 30 days online, 1 year archived.
6. Cost model¶
- Base platform: ~$200/mo (64 vCPU server).
- Per region: $5-15/mo cost vs $25/mo + $5/mo citizen revenue.
- Break-even: ~15 active regions.
7. Key files¶
Backend
- services/gameserver/src/models/region.py (Region, RegionalMembership, InterRegionalTravel)
- services/gameserver/src/services/regional_governance_service.py
- services/gameserver/src/services/nexus_generation_service.py
- services/gameserver/src/models/player.py (is_galactic_citizen, can_travel_between_regions)
- services/gameserver/src/services/ship_upgrade_service.py (is_galactic_citizen helper)
- services/gameserver/src/api/routes/nexus.py
- services/gameserver/src/api/routes/regional_governance.py
Admin UI
- services/admin-ui/src/components/pages/CentralNexusManager.tsx
- services/admin-ui/src/components/pages/RegionalGovernorDashboard.tsx
Infra
- docker-compose.yml (profiles: multi-regional, production, monitoring, …)
- scripts/setup-multi-regional.sh (helper — may lag; prefer docker compose --profile multi-regional)
- scripts/region-cli.py