Four-round workshop (Gestalt, Tyre, Paula, Burnelli-Sheldon, Miri) mapping the full generation pipeline from planetary heightmap to walkable tile. 25 D-records produced. Ticket dependency chain for Tier 0-4 implementation identified. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
602 lines
28 KiB
Markdown
602 lines
28 KiB
Markdown
---
|
||
title: "Round 3 — Burnelli-Sheldon: Economics as Generator Input"
|
||
description: "Mapping systems.db economic fields to spatial generator parameters across all scales"
|
||
type: workshop
|
||
status: active
|
||
workshop: generation-cascade
|
||
agent: burnelli-sheldon
|
||
round: 3
|
||
created: 2026-04-30
|
||
---
|
||
|
||
# Round 3 — Burnelli-Sheldon: Economics as Generator Input
|
||
|
||
The economics layer is built. The question is what the spatial pipeline should read
|
||
from it. My job here is to be the bridge: not to redesign the economics model, but to
|
||
map its concrete, queryable fields to concrete, actionable generator parameters.
|
||
|
||
I'll work scale by scale, then address differentiation, corporate footprint, dynamic
|
||
settlements, and what the simulation needs back.
|
||
|
||
---
|
||
|
||
## Preliminary: What Economic Data Actually Exists
|
||
|
||
Before prescribing anything, I surveyed what is actually in systems.db. The picture
|
||
is richer than the schema alone suggests.
|
||
|
||
**Per inhabited body (bodies table, 275 inhabited rows):**
|
||
- `economic_role`: 10 distinct values — `manufacturing`, `agricultural`, `extraction`,
|
||
`transit`, `research`, `commercial`, `service_mixed`, `mining`, `frontier`, `energy`
|
||
- `settlement_pattern`: 15+ values — `urban_concentrated`, `dispersed`, `dispersed_rural`,
|
||
`domed`, `underground_concentrated`, `cave`, `village_network`, `town_network`, etc.
|
||
- `industrial_corridor`: `MVG`, `Gate_Corp`, `DSMC`, `Prometheus`, `Agricultural_Syndic`
|
||
(null for many bodies — absence is meaningful)
|
||
- `population` (range: ~800 to 8.5B), `planet_class`, `atmosphere`, `surface_gravity`
|
||
|
||
**Per system (system_economy, system_factions, system_culture):**
|
||
- `economic_tier` (1–5), `economic_base_primary/secondary`, `distribution_index` (stratified/moderate)
|
||
- `currency_zone`: TRACTUS_PRIMARY | MARK_PRIMARY | MIXED
|
||
- `gate_energy_connected`: boolean
|
||
- `governance_type`, `dominant_faction`, `primary/secondary_fault_line`
|
||
- `cultural_register`, `ambient_anxiety`, `active_situation`
|
||
|
||
**Corporations (275 rows, `corp_presence` cross-reference):**
|
||
- `scope`: reach-wide, sector, system, local (many nulls — needs cleanup)
|
||
- `behavioral_archetype`: Monopolist | Distributor | Producer | Specialist | Cooperative | Intermediary
|
||
- `supply_chain_role`, `shadow_economy_access`
|
||
- `headquarters_system`, `headquarters_body`
|
||
|
||
**Corp presence per location:** The `corp_presence` table records which corps operate at
|
||
each body/station with `primary_operation` (commodity). Locations range from 1 corp
|
||
(frontier outpost) to 13 corps (GJ380c/Lendel — the Groombridge Settlement House hub).
|
||
This distribution is the single most useful signal for district composition.
|
||
|
||
**Commodities (36 types) and production chains (21 chains):** `production_ubiquity`
|
||
(monopolistic → ubiquitous) and `location_bound` (currently all 0, but the field is
|
||
load-bearing for future extractive operations).
|
||
|
||
**Brand products:** `brand_category`, `scarcity_class`, `base_premium_multiplier`,
|
||
`brand_tier` (halo/volume). These are spatial differentiators — halo brands require
|
||
physical presence; volume brands are ubiquitous.
|
||
|
||
**What is NOT yet queryable:** `behavioral_archetype` is mostly null. `scope` field on
|
||
corporations is a mixed bag (some are text prose, not enum values). The generator will
|
||
need to gracefully handle nulls on both.
|
||
|
||
---
|
||
|
||
## 1. Economic Data by Scale
|
||
|
||
### Regional Scale (planet → city hinterlands)
|
||
|
||
Regional subdivision is essentially hinterland characterization — what lies between
|
||
cities on a body. Economic signals at this scale:
|
||
|
||
**Primary input:** `bodies.economic_role` → hinterland type
|
||
|
||
| economic_role | Hinterland character | What fills the space |
|
||
|---|---|---|
|
||
| agricultural | Farmland belts, processing nodes | Field tiles, irrigation channels, silos |
|
||
| extraction / mining | Resource zones, access corridors | Open pits, pipeline corridors, camp clusters |
|
||
| manufacturing | Industrial fringe, supply chains | Warehousing strips, rail freight yards |
|
||
| transit | Corridor infrastructure | Road/rail density, relay stations |
|
||
| research | Campus periphery, exclusion zones | Restricted zones, observatory sites |
|
||
| commercial | Suburban sprawl, trade routes | Mixed low-density blocks, markets |
|
||
| service_mixed | Residential spread | Generic residential, civic amenities |
|
||
|
||
**Secondary input:** `atlas_roads`, `atlas_railroads` — road and rail count/density on
|
||
the body determines whether hinterland is connected or isolated. A body with 5+ rail
|
||
lines has industrial corridors linking cities; one with no rail has regional isolation.
|
||
|
||
**Tertiary input:** `system_economy.economic_tier` — tier 1–2 bodies have sparse
|
||
hinterland infrastructure regardless of `economic_role`. A tier-1 extraction world
|
||
looks like isolated mining camps; a tier-4 extraction world (Witwatersrand, GJ3522c)
|
||
has the industrial capacity to fill the hinterland.
|
||
|
||
**Recommendation:** The regional hinterland generator needs two parameters per body:
|
||
1. `HinterlandType` — derived from `economic_role`
|
||
2. `InfrastructureDensity` (0.0–1.0) — derived from `(economic_tier + rail_count + road_count) / normalization`
|
||
|
||
### City Scale (city → district decomposition)
|
||
|
||
The D-C4 decomposition formula (district count from population) is correct. The
|
||
economic question is: once you have N districts, what types are they?
|
||
|
||
**The mapping I propose is three-column: economic_role × settlement_pattern × distribution_index:**
|
||
|
||
#### economic_role → DistrictType distribution
|
||
|
||
I'll express this as a probability weight vector across the 9 confirmed DistrictType
|
||
values from Round 1/2 notes (Residential, Commercial, Industrial, Administrative,
|
||
LogisticsHub, Entertainment, MixedUse, Transit, Specialized):
|
||
|
||
| economic_role | Res | Com | Ind | Adm | Log | Ent | Mix | Trn | Spe |
|
||
|---|---|---|---|---|---|---|---|---|---|
|
||
| manufacturing | 25 | 5 | 35 | 5 | 20 | 2 | 5 | 3 | 0 |
|
||
| agricultural | 30 | 15 | 5 | 10 | 25 | 3 | 10 | 2 | 0 |
|
||
| extraction | 20 | 5 | 30 | 5 | 30 | 0 | 5 | 5 | 0 |
|
||
| transit | 10 | 20 | 5 | 5 | 25 | 10 | 15 | 10 | 0 |
|
||
| research | 20 | 5 | 5 | 15 | 5 | 5 | 10 | 0 | 35 |
|
||
| commercial | 15 | 35 | 5 | 5 | 10 | 15 | 15 | 0 | 0 |
|
||
| service_mixed | 25 | 20 | 5 | 10 | 5 | 15 | 20 | 0 | 0 |
|
||
| mining | 20 | 5 | 25 | 0 | 35 | 0 | 10 | 5 | 0 |
|
||
| frontier | 35 | 10 | 10 | 5 | 20 | 5 | 15 | 0 | 0 |
|
||
| energy | 10 | 0 | 20 | 5 | 30 | 0 | 5 | 5 | 25 |
|
||
|
||
These are not final tuning targets — they are the prior that seed generation should use
|
||
before corp-presence and governance modifiers are applied (see §3 below).
|
||
|
||
#### settlement_pattern modifier
|
||
|
||
`settlement_pattern` is a strong secondary signal. It doesn't change DistrictType
|
||
distribution — it changes *how districts are arranged*:
|
||
|
||
- `urban_concentrated`: compact grid, high-density blocks, minimal green space
|
||
- `dispersed` / `dispersed_rural`: districts smaller and more separated, low-density
|
||
building tiles, road-separated rather than contiguous
|
||
- `domed`: maximum 1 district (hardcoded — entire settlement is one pressurized dome);
|
||
DistrictType is always Specialized
|
||
- `underground_concentrated` / `cave`: vertical stacking matters; single large district
|
||
with strong perimeter treatment (Checkpoint or Walled)
|
||
- `village_network` / `town_network`: each "city" entry in atlas represents a network
|
||
of small settlements rather than one city — decompose into many Residential + small
|
||
Commercial; no Industrial districts unless industrial_corridor is set
|
||
|
||
#### distribution_index → prosperity gradient
|
||
|
||
`system_economy.distribution_index` gives the city-level prosperity shape:
|
||
- `stratified`: prosperity_index spans full range. A stratified manufacturing capital
|
||
has elite executive districts (0.8+) adjacent to worker housing (0.2). This creates
|
||
visible class geography.
|
||
- `moderate`: prosperity_index clusters around 0.4–0.6. The city is more economically
|
||
homogeneous — no dramatic wealth contrasts.
|
||
|
||
Concrete formula: if `distribution_index = stratified`, assign prosperity_index as
|
||
`0.1 + (district_rank / N) * 0.8` where district_rank is sorted by DistrictType
|
||
prestige (Administrative > Specialized > Commercial > Entertainment > Residential >
|
||
MixedUse > Industrial > LogisticsHub > Transit). If `moderate`, all districts draw
|
||
from N(0.5, 0.1) clipped to [0.2, 0.8].
|
||
|
||
### District Composition
|
||
|
||
Once district types are assigned, the generator needs to fill each district. Economic
|
||
data drives two things here: **tile density** and **building character**.
|
||
|
||
**Tile density from economic_role + DistrictType:**
|
||
|
||
A Commercial district on a manufacturing world differs from the same DistrictType on a
|
||
transit hub. The former is a small company store; the latter is a major trading floor.
|
||
Use this rule: `base_density = district_type_density[DistrictType] × role_multiplier[economic_role]`
|
||
|
||
Role multipliers (examples): transit on Commercial = ×1.8; manufacturing on Commercial
|
||
= ×0.5; research on Specialized = ×1.5; agricultural on LogisticsHub = ×1.4.
|
||
|
||
**Commodity signal → building archetype:**
|
||
|
||
The `corp_presence.primary_operation` field tells us what commodity each corp at this
|
||
location primarily deals in. Cross-referencing with `commodities.bulk_class`:
|
||
|
||
| bulk_class | Physical form → building archetype |
|
||
|---|---|
|
||
| bulk | Open yards, conveyor structures, grain silos |
|
||
| liquid | Tank farms, pipe corridors |
|
||
| precision | Clean-room buildings, elevated access points |
|
||
| perishable | Cold storage blocks, loading docks with shade cover |
|
||
| non_physical | Office towers, transmission arrays, no loading dock |
|
||
| standard | Generic warehouse / distribution |
|
||
|
||
This mapping is queryable: `SELECT cp.primary_operation, c.bulk_class FROM corp_presence cp JOIN commodities c ON cp.primary_operation = c.commodity_id WHERE cp.location_id = ?`
|
||
|
||
### Infrastructure: Roads, Rail, Ports
|
||
|
||
**Road quality:** `economic_tier + settlement_pattern → road_quality`
|
||
|
||
| tier | urban_concentrated | dispersed | domed |
|
||
|---|---|---|---|
|
||
| 1 | narrow_unpaved | tracks | internal_only |
|
||
| 2 | narrow_paved | gravel_road | internal_only |
|
||
| 3 | medium_paved | narrow_paved | internal_only |
|
||
| 4 | boulevard | medium_paved | internal_only |
|
||
| 5 | boulevard | boulevard | N/A |
|
||
|
||
**Rail placement:** Query `atlas_railroads` — if a body has railroad entries, the
|
||
generator should anchor rail yards in LogisticsHub districts and place station tiles in
|
||
Transit districts. No authoring needed; the atlas already marks rail presence.
|
||
|
||
**Port/spaceport location:** Transit and LogisticsHub districts should be placed at the
|
||
city edge closest to the body's orbital station (if `stations.orbits_body_id` matches).
|
||
If no station exists, spaceport tiles go at the district with highest `logistics`
|
||
weight. Port capacity is a direct read from `stations.docking_class`.
|
||
|
||
---
|
||
|
||
## 2. Economic Differentiation: Concrete Examples
|
||
|
||
Theory is cheap. Let me walk through three real bodies in systems.db to show how
|
||
economic fields produce spatially distinct results.
|
||
|
||
### Case A: Tributarium (GJ251c/city_0) — Manufacturing Capital
|
||
|
||
```
|
||
body.economic_role = manufacturing
|
||
body.settlement_pattern = urban_concentrated
|
||
body.industrial_corridor = Gate_Corp
|
||
body.population = 5B
|
||
system.distribution_index = stratified (GJ 251 — inferred from tier 5)
|
||
system.economic_tier = (reached via GJ251 system_economy)
|
||
corp_presence at GJ251c = gate-corporation (HQ system), kalten-assembly, precision-works...
|
||
```
|
||
|
||
**Generator output:**
|
||
- District composition: ~35% Industrial, ~20% LogisticsHub, ~25% Residential, ~5% Administrative
|
||
- Prosperity: sharply stratified — Gate Corp executive district at 0.9, worker housing at 0.15
|
||
- Gate Corp `behavioral_archetype = Monopolist` → one dominant industrial district type; consistent building footprint
|
||
- `industrial_corridor = Gate_Corp` → gate component manufacturing tiles dominate Industrial districts
|
||
- `gate_components` commodity: `bulk_class = precision` → clean-room buildings, not open yards
|
||
- Road network: tier 5 → boulevards; but industrial zones have dedicated freight lanes
|
||
|
||
### Case B: Bluebank (GJ3522c/city_0) — Extraction Capital
|
||
|
||
```
|
||
body.economic_role = extraction
|
||
body.settlement_pattern = urban_concentrated
|
||
body.industrial_corridor = DSMC
|
||
body.population = 1.5B
|
||
system.distribution_index = stratified
|
||
corp_presence = dsmc (DSMC HQ system)
|
||
```
|
||
|
||
**Generator output:**
|
||
- District composition: ~30% Industrial, ~30% LogisticsHub, ~20% Residential, ~5% Administrative, ~5% Transit
|
||
- `metallic_ore` + `rare_minerals` → bulk_class = bulk → open pit adjacency, conveyor structures, slag heap tiles
|
||
- DSMC = reach-wide Monopolist → single employer city; company housing blocks (uniform, low prosperity)
|
||
- No Entertainment districts. Very low prosperity (worker housing at 0.15–0.25)
|
||
- LogisticsHub → ship loading yards (bulk cargo configuration), railway terminus
|
||
|
||
**Contrast with Tributarium:** Both are industrial. Tributarium has precision manufacturing
|
||
(implants, gate components) → clean-room aesthetic, corporate towers. Bluebank has
|
||
raw extraction (ore, rare minerals) → open yard aesthetic, functional brutalism.
|
||
The aesthetic difference is entirely derivable from `production_ubiquity` and `bulk_class`.
|
||
|
||
### Case C: Strata (GJ280Ad/city_0) — Service Mixed Capital
|
||
|
||
```
|
||
body.economic_role = service_mixed
|
||
body.settlement_pattern = urban_concentrated
|
||
body.industrial_corridor = NULL
|
||
body.population = 1.8B
|
||
system.distribution_index = stratified
|
||
corp_presence = rare-vein-survey (HQ), adams-ford-publishing (HQ)
|
||
```
|
||
|
||
**Generator output:**
|
||
- District composition: ~25% Residential, ~20% Commercial, ~10% Administrative, ~15% Entertainment, ~20% MixedUse
|
||
- No industrial corridor → no dominant building archetype; district types are heterogeneous
|
||
- Two reach-wide HQ corps → two landmark buildings (publisher HQ, survey company HQ)
|
||
- `non_physical` services (financial, legal, entertainment) → office towers, no loading docks
|
||
- `distribution_index = stratified` + `service_mixed` → gentrified commercial district (prosperity 0.75) adjacent to mid-tier residential (prosperity 0.45)
|
||
|
||
**Contrast with Bluebank:** Strata has negligible Industrial districts. Its LogisticsHub
|
||
equivalents handle information rather than cargo — server banks, archive towers.
|
||
The physical infrastructure (roads, buildings) looks wealthy but not industrial.
|
||
|
||
---
|
||
|
||
## 3. The Corporation Footprint
|
||
|
||
Corporations are the most underutilized signal in the current bridge-gap. The
|
||
`corp_presence` table is already populated and queryable. Here is how it maps to space.
|
||
|
||
### Corporate Presence Tier
|
||
|
||
Derive a `CorpPresenceTier` per city from the corp_presence query:
|
||
|
||
```sql
|
||
SELECT COUNT(DISTINCT cp.corp_id) as corp_count,
|
||
COUNT(DISTINCT CASE WHEN co.scope = 'reach-wide' THEN cp.corp_id END) as halo_count,
|
||
SUM(CASE WHEN co.headquarters_system = b.system_id THEN 1 ELSE 0 END) as hq_count
|
||
FROM corp_presence cp
|
||
JOIN corporations co ON cp.corp_id = co.corp_id
|
||
JOIN bodies b ON cp.location_id = b.body_id
|
||
WHERE cp.location_id = ?
|
||
```
|
||
|
||
| corp_count | halo_count | tier | District effect |
|
||
|---|---|---|---|
|
||
| 1–2 | 0 | Company Town | Single employer → uniform district character |
|
||
| 3–5 | 0–1 | Local Economy | Mixed district types, small commercial |
|
||
| 6–10 | 1–2 | Regional Hub | Commercial district expands, entertainment emerges |
|
||
| 11+ | 3+ | System Nexus | Full district variety, landmark buildings |
|
||
|
||
GJ380c (Lendel) has 13 corps including 2 reach-wide HQs → System Nexus.
|
||
GJ1111b has 5 corps, 0 HQs → Local Economy.
|
||
This difference is real and pre-populated.
|
||
|
||
### HQ Presence → Corporate District
|
||
|
||
When `corporations.headquarters_system = atlas_city.body.system_id` AND
|
||
`headquarters_body = atlas_city.body_id` (or close enough), that city gets a corporate
|
||
district. Rules:
|
||
|
||
- One corporate district per reach-wide HQ corp at this city
|
||
- The corporate district's DistrictType is Administrative (if Monopolist) or Commercial (if Distributor/Specialist)
|
||
- `base_premium_multiplier` from brand_products by this corp → scales the landmark building height (halo ×18 brands get the skyline)
|
||
|
||
### Behavioral Archetype → District Shape
|
||
|
||
Where `behavioral_archetype` is populated:
|
||
|
||
| archetype | District character |
|
||
|---|---|
|
||
| Monopolist | Large uniform blocks, single building type, minimal commercial variety |
|
||
| Distributor | Dense transit + logistics districts; loading infrastructure heavy |
|
||
| Producer | Industrial districts with process-flow layout (input → process → output) |
|
||
| Specialist | One Specialized district with restricted perimeter; premium prosperity |
|
||
| Cooperative | Residential more integrated with commercial; lower wealth disparity |
|
||
| Intermediary | Commercial + financial services; mixed-use preferred |
|
||
|
||
Where `behavioral_archetype = NULL` (most corps currently), fall back to
|
||
`supply_chain_role` if populated, or derive from `primary_operation` commodity tier.
|
||
|
||
### Shadow Economy
|
||
|
||
`corporations.shadow_economy_access = 1` → this location has a shadow market.
|
||
Physical manifestation: one MixedUse district at the city fringe with reduced
|
||
perimeter treatment (Open instead of Gated), elevated tile decay (prosperity 0.15–0.25),
|
||
and elevated building density (informal construction = wasted space is illegal).
|
||
|
||
`system_fiscal.collection_efficiency < 0.7` at the system level → amplify shadow zone
|
||
size by `(1 - collection_efficiency) × 2` as a district probability weight modifier.
|
||
|
||
---
|
||
|
||
## 4. Dynamic Settlements (Off-Atlas)
|
||
|
||
The atlas marks cities. But economic pressure creates settlements the atlas doesn't
|
||
know about. These are procedural — generated from economic conditions, not authored.
|
||
|
||
### Trigger Conditions
|
||
|
||
**Mining camps** (highest frequency):
|
||
- Condition: `bodies.economic_role IN ('extraction', 'mining')` AND body has
|
||
`corp_presence` entries with `primary_operation IN ('metallic_ore', 'rare_minerals',
|
||
'lattice_grade_material')`
|
||
- Generator action: place 1 satellite settlement per 2 qualifying corps, at randomized
|
||
distance from nearest atlas city (15%–40% of map scale)
|
||
- Settlement type: single LogisticsHub district + minimal Residential; no Commercial
|
||
- Size: 1 district, population ~1,000–50,000
|
||
|
||
**Trade route waypoints**:
|
||
- Condition: `atlas_roads.kind IN ('highway', 'commercial')` with point_count > 5
|
||
(long road connecting two distant cities)
|
||
- Generator action: place a waypoint settlement at the geometric midpoint of roads
|
||
longer than a threshold
|
||
- Settlement type: Transit district (fueling stop, overnight), small Commercial
|
||
- Size: 1 district, population ~500–5,000
|
||
|
||
**Agricultural dispersed nodes**:
|
||
- Condition: `bodies.settlement_pattern IN ('dispersed', 'dispersed_rural')` AND
|
||
`bodies.economic_role = 'agricultural'`
|
||
- Generator action: scatter farm clusters at interval proportional to `1/economic_tier`
|
||
(lower tier = fewer, sparser farms)
|
||
- Each farm cluster: 1 Residential district + 1 LogisticsHub, no perimeter treatment
|
||
- Size: sub-district scale
|
||
|
||
**Shadow economy nodes**:
|
||
- Condition: `system_fiscal.collection_efficiency < 0.6` AND system has shadow-viable
|
||
corps in `corp_presence`
|
||
- Generator action: place 1 informal settlement per system, adjacent to a major city
|
||
but not on its district grid
|
||
- Settlement type: MixedUse fringe; elevated decay, low prosperity
|
||
|
||
### What the Generator Needs Per Dynamic Settlement
|
||
|
||
Unlike atlas cities, dynamic settlements do not have authored names or economic roles.
|
||
The generator should derive:
|
||
- `settlement_seed = child_seed(body_seed, trigger_type_hash + location_hash)` — FNV-1a per D-010
|
||
- `economic_role` = inferred from trigger condition (mining camp → extraction, etc.)
|
||
- `prosperity_index` = base 0.15 for camps; 0.25–0.4 for waypoints
|
||
- `district_count` = always 1
|
||
- Name = procedural suffix of nearest atlas city ("Bluebank Camp 3", "Kallast Waypoint")
|
||
|
||
---
|
||
|
||
## 5. What the Economic Simulation Needs Back from the Spatial World
|
||
|
||
This is the other side of the bridge. Once districts exist, the simulation's trade
|
||
cost model gets better data.
|
||
|
||
### Transport Distance
|
||
|
||
The D-C4 formula places districts at city-local coordinates `(col × 512, row × 512)`.
|
||
After generation, the simulation needs:
|
||
|
||
```
|
||
city_transport_cost_modifier(from_city_id, to_city_id) → f32
|
||
```
|
||
|
||
Derived from: `atlas_roads` + `atlas_railroads` point_count between two cities on the
|
||
same body. Cities connected by rail get a 0.4× cost multiplier (per D-178 gate edge
|
||
5–12%); road-only cities get 1.0×; no infrastructure gets 2.5×.
|
||
|
||
This does not require the spatial world to be generated — it's derivable from atlas data
|
||
alone. The generator does not need to feed this back; it's a pre-generation query.
|
||
|
||
### Port Capacity
|
||
|
||
`stations.docking_class` (major/standard/restricted/none) is already in systems.db.
|
||
After generation, the port district's physical size (tile count in Transit districts)
|
||
should be reported back as `effective_port_size: u32`. This feeds the trade flow
|
||
capacity constraint: a Restricted port can't handle bulk cargo regardless of
|
||
economic_role.
|
||
|
||
Concrete mapping:
|
||
- `docking_class = major` → Transit district tile budget = 256 tiles; throughput_coefficient = 1.0
|
||
- `docking_class = standard` → 128 tiles; throughput_coefficient = 0.5
|
||
- `docking_class = restricted` → 32 tiles; throughput_coefficient = 0.2
|
||
- `docking_class = none` → no Transit district; throughput_coefficient = 0.0
|
||
|
||
### Infrastructure Quality
|
||
|
||
`settlement_pattern` + `economic_tier` → road quality (derived above). The simulation
|
||
should read `road_quality: RoadQuality` per body as a trade cost multiplier:
|
||
|
||
| road_quality | intra-city cost multiplier |
|
||
|---|---|
|
||
| narrow_unpaved | 3.0 |
|
||
| gravel_road | 2.0 |
|
||
| narrow_paved | 1.5 |
|
||
| medium_paved | 1.0 |
|
||
| boulevard | 0.7 |
|
||
|
||
This is already derivable from `economic_tier` + `settlement_pattern` without running
|
||
the generator — another pre-generation query, not a feedback dependency.
|
||
|
||
### What Actually Requires Generator Feedback
|
||
|
||
Most simulation needs are pre-generation derivable. The only fields that genuinely
|
||
require post-generation reporting:
|
||
|
||
1. **Effective port tile count** — physical district layout determines actual cargo
|
||
throughput, not just declared docking class
|
||
2. **Corp district allocation** — which DistrictType a given corp actually occupies,
|
||
once the district assignment algorithm runs (needed for corp financial state updates)
|
||
3. **Shadow economy footprint** — whether a shadow zone was generated, and its
|
||
prosperity floor (informs `collection_efficiency` updates)
|
||
|
||
These are three narrow feedback fields, not a broad data exchange. The simulation
|
||
should not depend on generator re-runs for routine tick processing.
|
||
|
||
---
|
||
|
||
## Responses to Round 2 Open Questions
|
||
|
||
### OQ-R2-1: Should `prosperity_index` be in the minimum slice?
|
||
|
||
**Yes.** And here is the economic argument for inclusion rather than deferral:
|
||
|
||
`prosperity_index` is not a decorative field — it is a readability signal derived
|
||
entirely from data we already query: `distribution_index` + `economic_role` +
|
||
`economic_tier`. The computation is trivial (one formula, no authoring). The cost of
|
||
deferral is not "decorative refinement later" — it is "all districts look equally
|
||
prosperous until a retrofit pass." Retrofit changes Phase 2 tile generation. Include
|
||
it in Stage 1 classification as a derived field; it costs 0.5 dev-days.
|
||
|
||
Concrete derivation formula:
|
||
```
|
||
base_prosperity = economic_tier / 5.0
|
||
role_modifier: manufacturing=0.0, extraction=-0.1, research=+0.15, service_mixed=+0.1,
|
||
commercial=+0.05, agricultural=-0.05, transit=-0.05, frontier=-0.2
|
||
if distribution_index = stratified:
|
||
district_prosperity[i] = (base + role_modifier) + (district_prestige_rank(i) - 0.5) * 0.7
|
||
else: # moderate
|
||
district_prosperity[i] = clamp(N(base + role_modifier, 0.1), 0.2, 0.8)
|
||
```
|
||
|
||
### OQ-R2-2: Should `political_archetype` be a formal authored field?
|
||
|
||
**Derive it; do not author it separately.** From an economist's perspective, this is
|
||
the classic "add a variable or derive it from existing ones" tradeoff. The answer is
|
||
always: derive unless you have reason to believe the derivation fails.
|
||
|
||
Derivation rules:
|
||
- `corp_presence` where one `behavioral_archetype = Monopolist` corp accounts for >60%
|
||
of corps → `CompanyTown`
|
||
- `governance_type = assembly` AND `commission_presence` high → `AdminCapital`
|
||
- `economic_role = transit` AND `corp_count > 6` → `FreePort`
|
||
- `primary_fault_line` AND `secondary_fault_line` both populated and active →
|
||
`Contested`
|
||
- Else → `OrganicGrowth`
|
||
|
||
If a named city fails this derivation in a way that's clearly wrong (the lead decides
|
||
this), add a one-field override in `atlas_cities` schema. But the starting position
|
||
should be: trust the data.
|
||
|
||
### OQ-R2-5: Naming register lookup table — before Phase 2?
|
||
|
||
**After walkable.** This is a pure naming question that has zero effect on tile layout.
|
||
The register taxonomy is correct and useful; the lookup table determines what *kind* of
|
||
name a district gets, not what tiles it contains. It can be authored once a district
|
||
exists and is legible. Defer.
|
||
|
||
---
|
||
|
||
## D-Record Candidates
|
||
|
||
### D-C9 (proposed by Burnelli-Sheldon): Economic Fields → Generator Parameter Mapping
|
||
|
||
The spatial generator's primary input from systems.db is the following read-only query
|
||
set, executed once per city at generation time:
|
||
|
||
```sql
|
||
-- All queries execute against server/data/systems.db (read-only)
|
||
|
||
-- City economic context
|
||
SELECT b.economic_role, b.settlement_pattern, b.industrial_corridor,
|
||
b.population, b.planet_class, b.atmosphere
|
||
FROM bodies b
|
||
JOIN atlas_cities ac ON ac.body_id = b.body_id
|
||
WHERE ac.city_id = ?;
|
||
|
||
-- System-level modifiers
|
||
SELECT se.economic_tier, se.distribution_index,
|
||
sf.dominant_faction, sf.governance_type,
|
||
ss.currency_zone, ss.gate_energy_connected
|
||
FROM system_economy se
|
||
JOIN system_factions sf ON se.system_id = sf.system_id
|
||
JOIN star_systems ss ON se.system_id = ss.system_id
|
||
WHERE se.system_id = (SELECT system_id FROM bodies b
|
||
JOIN atlas_cities ac ON b.body_id = ac.body_id
|
||
WHERE ac.city_id = ?);
|
||
|
||
-- Corporate presence at this body
|
||
SELECT co.corp_id, co.behavioral_archetype, co.scope, co.shadow_economy_access,
|
||
cp.primary_operation, c.bulk_class
|
||
FROM corp_presence cp
|
||
JOIN corporations co ON cp.corp_id = co.corp_id
|
||
LEFT JOIN commodities c ON cp.primary_operation = c.commodity_id
|
||
WHERE cp.location_id = (SELECT body_id FROM atlas_cities WHERE city_id = ?);
|
||
```
|
||
|
||
This data is sufficient to derive:
|
||
- `DistrictType` distribution weights per city
|
||
- `prosperity_index` per district
|
||
- `CorpPresenceTier` and corporate district placement
|
||
- `political_archetype` (derived, not authored)
|
||
- `perimeter_treatment` per district
|
||
- Infrastructure quality parameters
|
||
- Dynamic settlement trigger conditions
|
||
|
||
### D-C10 (proposed by Burnelli-Sheldon): economic_role → DistrictType Weight Table
|
||
|
||
The mapping table in §1 above (manufacturing → 35% Industrial, etc.) should be a
|
||
confirmed D-record, not just a design note. It is the foundational prior that all
|
||
district composition derives from. Corp-presence modifiers apply on top of it.
|
||
|
||
The table should live in Rust as a const array, keyed by `EconomicRole` enum. It can
|
||
be tuned later, but a locked canonical default prevents every sprint from relitigating
|
||
the same question.
|
||
|
||
---
|
||
|
||
## Summary: The Minimum Read Set
|
||
|
||
If the generator can only read one thing from systems.db per city, it should read
|
||
`bodies.economic_role`. Every other field is a refinement multiplier.
|
||
|
||
The full minimum read set for a differentiated Phase 1 district skeleton:
|
||
1. `bodies.economic_role` — district type distribution
|
||
2. `bodies.settlement_pattern` — district layout and density mode
|
||
3. `system_economy.economic_tier` — infrastructure quality and wealth floor
|
||
4. `system_economy.distribution_index` — prosperity gradient shape
|
||
5. `corp_presence` count at this body — corporate district intensity
|
||
6. `corporations.headquarters_system` match — HQ landmark flag
|
||
|
||
Everything else (behavioral_archetype, shadow economy, bulk_class, brand premiums,
|
||
currency zone) is Phase 2 enrichment — meaningful, but not required for the minimum
|
||
walkable world.
|
||
|
||
The pipeline will produce economically differentiated worlds on those six fields alone.
|
||
Everything else makes them richer.
|