Skip to content

Central Nexus Districts

Purpose

The Central Nexus is a single 5,000-sector region (Region.region_type = CENTRAL_NEXUS) that serves as the universal hub connecting all player-owned regions. Internally, the Nexus is partitioned into 10 thematic districts that drive sector spawn density, security/development/traffic gradients, and economic specialization.

Districts are a generation-time grouping layer distinct from Zone: the Nexus has exactly one Zone (EXPANSE, policing_level = 3, danger_level = 6), while districts are an additional cross-cut used by the generator and by Nexus-aware UI/admin tooling.

Inputs

The district generator reads:

  • total_sectors = 5000 — fixed Nexus size.
  • DISTRICT_CONFIGURATION — the 10-row table below (sector counts, security/development/traffic ranges, characteristics).
  • Generation seed — propagated from the parent Nexus generation pipeline.
  • Region row created by the Nexus generator (region_type = CENTRAL_NEXUS).
  • Zone row created by the Nexus generator (name = "The Expanse").

Process

District materialization runs as a phase inside the Nexus generation pipeline (see ./galaxy-generation.md):

                ┌──────────────────────────┐
                │ Nexus Region + Zone made │
                └──────────────┬───────────┘
                               ▼
                ┌──────────────────────────┐
                │ Partition 5000 sectors   │
                │ into 10 districts by     │
                │ contiguous sector range  │
                └──────────────┬───────────┘
                               ▼
                ┌──────────────────────────┐
                │ For each district:       │
                │  - allocate clusters     │
                │  - bias cluster type by  │
                │    district characters   │
                │  - generate sectors with │
                │    security / dev / traf │
                │    drawn uniformly from  │
                │    district ranges       │
                └──────────────┬───────────┘
                               ▼
                ┌──────────────────────────┐
                │ Tag each sector and      │
                │ cluster with district id │
                │ (Sector.district)        │
                └──────────────────────────┘

Step-by-step:

  1. Range partition. The 5,000 Nexus sectors are partitioned into 10 contiguous ranges based on the per-district sectors count, in the legacy DistrictConfiguration declaration order. Ranges are computed at generator boot from the configuration table — they are not hard-coded. The generator validates the running sum equals 5,000 before any DB write.
  2. Cluster allocation. Cluster generation runs within each district. Cluster economic_focus and controlling_faction are biased by the district's characteristics list (e.g. industrial_zone favours INDUSTRIAL/MANUFACTURING clusters; research_campus favours SCIENCE; free_trade_zone raises the weight on BLACK_MARKET/SMUGGLING cluster types). The bias function takes the characteristics list and returns a weighted pool of ClusterType values; the cluster's final type is sampled from that pool.
  3. Sector roll. For each sector in a district, security_level, development_level, and traffic_level are drawn uniformly at random from the district's [min, max] ranges (inclusive on both ends). The seed is mixed with the sector number so the same seed reproduces the same per-sector draws.
  4. District tagging. Each generated Sector row is written with its district slug; the Cluster is likewise tagged so admin queries (WHERE region_id = nexus AND district = 'free_trade_zone') are O(index-lookup) via idx_sectors_nexus_district.
  5. Zone assignment. Every sector — regardless of district — is assigned to the Nexus's single EXPANSE zone. Districts are an orthogonal grouping; they do not override zone policing/danger. A district's high security_level does not change its zone's policing_level; the security level is per-sector and additive on top of zone-level policing.
  6. SpaceDock placement. Sector 1 is created first as the SpaceDock anchor and tagged transit_hub directly. The remaining 4,999 sectors are then partitioned: transit_hub's configured count of 400 absorbs the SpaceDock slot, so 399 additional sectors are drawn from the partition for that district. Range arithmetic for all other districts is unaffected.

District table

The legacy DistrictConfiguration declares ten districts by sector count, not by an explicit numeric range. The generator derives contiguous ranges from those counts in declaration order. Counts sum to exactly 5,000.

District Sectors Sector range Security Development Traffic Characteristics
commerce_central 500 1 – 500 7 – 9 8 – 10 8 – 10 premium_markets, trade_hubs, financial_centers
diplomatic_quarter 300 501 – 800 8 – 10 7 – 9 4 – 7 embassies, negotiation_chambers, cultural_centers
industrial_zone 600 801 – 1400 4 – 7 6 – 9 6 – 9 manufacturing, shipyards, industrial_complexes
residential_district 800 1401 – 2200 5 – 8 5 – 8 3 – 6 housing, services, entertainment
transit_hub 400 2201 – 2600 6 – 8 7 – 10 8 – 10 warp_gates, transportation, logistics
high_security_zone 200 2601 – 2800 9 – 10 8 – 10 1 – 3 restricted_access, high_value, premium_services
cultural_center 350 2801 – 3150 6 – 8 6 – 9 5 – 8 events, festivals, cultural_exchange
research_campus 450 3151 – 3600 7 – 9 8 – 10 3 – 6 technology, innovation, research_facilities
free_trade_zone 600 3601 – 4200 3 – 6 5 – 8 7 – 10 unrestricted_trade, black_market, smuggling
gateway_plaza 800 4201 – 5000 6 – 8 6 – 8 8 – 10 welcome_center, orientation, first_contact

Notes:

  • Sector numbers are Nexus-internal; in deployments where Nexus sectors are namespaced behind a Terran-space prefix the generator applies the offset uniformly (the within-district order and count are unchanged).
  • Districts are listed in legacy declaration order, not in sector-range order. The numeric ranges above are the canonical mapping derived from that order.
  • sector 1 (the SpaceDock-bearing sector) falls inside commerce_central by raw range, but is reassigned to transit_hub (see Invariants).

District semantics

Each district's characteristics list is an unordered set of free-form tags that informs three downstream behaviours:

Cluster-type bias

The cluster generator looks up each characteristic in a CHARACTERISTIC_TO_CLUSTER_WEIGHT map and accumulates weights into a sampling pool. Sample mappings:

Characteristic Boosted ClusterType
manufacturing, shipyards, industrial_complexes INDUSTRIAL, MANUFACTURING
technology, innovation, research_facilities SCIENCE, TECH
premium_markets, trade_hubs, financial_centers COMMERCIAL, FINANCIAL
unrestricted_trade, black_market, smuggling BLACK_MARKET, SMUGGLING
embassies, negotiation_chambers DIPLOMATIC
events, festivals, cultural_exchange CULTURAL
restricted_access, high_value, premium_services MILITARY, RESTRICTED
warp_gates, transportation, logistics TRANSIT
welcome_center, orientation, first_contact GATEWAY, STANDARD
housing, services, entertainment RESIDENTIAL, STANDARD

If no characteristic matches any entry, the generator falls back to ClusterType.STANDARD.

Faction control

Each district's leading characteristic projects a controlling_faction onto its clusters:

District Default controlling_faction
commerce_central MERCHANT_GUILD
diplomatic_quarter FEDERATION
industrial_zone INDUSTRIAL_CONSORTIUM
residential_district CIVILIAN_AUTHORITY
transit_hub TRANSPORT_AUTHORITY
high_security_zone FEDERATION_MILITARY
cultural_center CULTURAL_FEDERATION
research_campus SCIENCE_COUNCIL
free_trade_zone INDEPENDENT
gateway_plaza FEDERATION

These defaults are overridable per cluster by admin tooling; the generator only seeds them.

Spawn-distribution shape

The securityRange / developmentRange / trafficRange triples are the only stochastic inputs the per-sector roll consumes. They are uniform distributions, not biased toward midpoint. Two consequences:

  • A district like high_security_zone (security 9–10) cannot legally produce a low-security sector. Combat AI and patrol-spawn logic that key off Nexus sectors can therefore assume the floor.
  • A district like free_trade_zone (security 3–6) intentionally never produces high-security sectors, so smuggler/black-market spawn rules can rely on the ceiling.

The generator does not currently weight draws by sector position within a district (e.g. denser at the centre); position-weighted draws are a future extension.

Outputs / state changes

For each Nexus generation run:

  • Region — one row, name = "central-nexus", region_type = CENTRAL_NEXUS.
  • Zone — one row, name = "The Expanse", policing_level = 3, danger_level = 6, region_id = nexus.id.
  • Cluster — multiple rows per district. Each row carries region_id, district slug, cluster_type, economic_focus, and controlling_faction derived from the district's characteristics.
  • Sector — 5,000 rows. Each carries:
  • region_id = nexus.id
  • zone_id = expanse.id
  • district — the slug from the table above
  • cluster_id — its parent cluster
  • security_level ∈ district securityRange
  • development_level ∈ district developmentRange
  • traffic_level ∈ district trafficRange

No game-time events are emitted; this is a generation-phase write only. Subsequent edits (admin reassignment of a sector's district, for example) go through the normal Sector write path and trigger no special hook.

Invariants

  1. Sum-to-5000. sum(district.sectors for district in DISTRICT_CONFIGURATION) == 5000. Enforced at generator boot.
  2. No overlap. District sector ranges are contiguous and disjoint; every Nexus sector belongs to exactly one district.
  3. Total coverage. No Nexus sector has district = NULL.
  4. Single zone. Every Nexus sector has zone_id = (the single Expanse zone). Districts never replace zones.
  5. SpaceDock anchor. Sector 1 is reserved for the Nexus SpaceDock and is assigned to transit_hub regardless of where its raw sector number falls in the range table — the generator places SpaceDock first, then partitions the remaining 4,999 sectors into the configured counts (with transit_hub losing one slot to absorb sector 1).
  6. Deterministic with seed. Given identical seed and identical DISTRICT_CONFIGURATION, the generator produces an identical district-to-sector mapping.
  7. Range monotonicity. Within a district, generated security_level, development_level, and traffic_level are bounded by the district's [min, max] inclusive on both ends.

Failure modes

Mode Target handling
District counts don't sum to 5,000 Generator aborts at boot with ConfigurationError("district sectors sum != 5000"). No DB writes.
District securityRange[0] > securityRange[1] (or dev/traffic) Generator aborts at boot with ConfigurationError("invalid range for <district>").
Duplicate district slug in configuration Generator aborts at boot with ConfigurationError("duplicate district slug").
Cluster type bias produces zero-weight pool Fall back to ClusterType.STANDARD for that cluster; emit a warning log carrying the offending district slug.
Random draw lands outside expected range (impossible barring code bug) Generator clamps to range and logs an error so the test suite catches the regression.
Nexus already exists when generation runs Generator returns {"status": "exists"}; districts are not rewritten or re-tagged.
Sector 1 already exists in another district on re-run Idempotent re-run skips re-partition; the mismatch is recorded in the admin audit log for manual review.
District count drifts from 10 (config edit adds/removes a district) Generator runs against the new shape so long as counts still sum to 5,000; admin tooling reads the live configuration rather than assuming "10".

Admin operations

Admin tooling targets the district layer directly:

  • GET /api/v1/admin/nexus/districts — returns the live DISTRICT_CONFIGURATION (slug, count, ranges, characteristics) for every district, plus per-district counts of generated clusters and sectors.
  • GET /api/v1/admin/nexus/districts/{slug} — district detail, including the cluster list and aggregate security/development/traffic histograms.
  • POST /api/v1/admin/nexus/districts/{slug}/regenerate — re-rolls the district's sector attributes in place (keeps sector ids; rerolls security/development/traffic from current ranges). Bounded by an admin-confirm step because it overwrites live state.
  • PATCH /api/v1/admin/nexus/sectors/{sector_id} — admin override for a single sector's district, security_level, development_level, or traffic_level. Writes an audit-log entry tagged nexus.district_override.

District configuration itself is not runtime-editable through the API; changes go through code in nexus_districts.py and require a Nexus regeneration to take effect on existing rows.

Source map

Concern Path (target)
District configuration table services/gameserver/src/core/nexus_districts.py
Nexus generation service services/gameserver/src/services/nexus_generation_service.py
Nexus admin routes services/gameserver/src/api/routes/nexus.py
Sector.district column services/gameserver/src/models/sector.py
Cluster.district column services/gameserver/src/models/cluster.py
Cluster type bias logic services/gameserver/src/services/nexus_generation_service.py:_bias_cluster_type
Per-sector attribute roll services/gameserver/src/services/nexus_generation_service.py:_roll_sector_attributes
Index for district queries migration idx_sectors_nexus_district on sectors(region_id, district)
Audit-log channel for district overrides services/gameserver/src/services/audit_service.py (event tag nexus.district_override)