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>
28 KiB
title, description, type, status, workshop, agent, round, created
| title | description | type | status | workshop | agent | round | created |
|---|---|---|---|---|---|---|---|
| Round 3 — Burnelli-Sheldon: Economics as Generator Input | Mapping systems.db economic fields to spatial generator parameters across all scales | workshop | active | generation-cascade | burnelli-sheldon | 3 | 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,energysettlement_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 | MIXEDgate_energy_connected: booleangovernance_type,dominant_faction,primary/secondary_fault_linecultural_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 | Intermediarysupply_chain_role,shadow_economy_accessheadquarters_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:
HinterlandType— derived fromeconomic_roleInfrastructureDensity(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 spacedispersed/dispersed_rural: districts smaller and more separated, low-density building tiles, road-separated rather than contiguousdomed: maximum 1 district (hardcoded — entire settlement is one pressurized dome); DistrictType is always Specializedunderground_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 districtsgate_componentscommodity: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_physicalservices (financial, legal, entertainment) → office towers, no loading docksdistribution_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:
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_multiplierfrom 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 hascorp_presenceentries withprimary_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')ANDbodies.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.6AND system has shadow-viable corps incorp_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-010economic_role= inferred from trigger condition (mining camp → extraction, etc.)prosperity_index= base 0.15 for camps; 0.25–0.4 for waypointsdistrict_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.0docking_class = standard→ 128 tiles; throughput_coefficient = 0.5docking_class = restricted→ 32 tiles; throughput_coefficient = 0.2docking_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:
- Effective port tile count — physical district layout determines actual cargo throughput, not just declared docking class
- Corp district allocation — which DistrictType a given corp actually occupies, once the district assignment algorithm runs (needed for corp financial state updates)
- Shadow economy footprint — whether a shadow zone was generated, and its
prosperity floor (informs
collection_efficiencyupdates)
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_presencewhere onebehavioral_archetype = Monopolistcorp accounts for >60% of corps →CompanyTowngovernance_type = assemblyANDcommission_presencehigh →AdminCapitaleconomic_role = transitANDcorp_count > 6→FreePortprimary_fault_lineANDsecondary_fault_lineboth 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:
-- 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:
DistrictTypedistribution weights per cityprosperity_indexper districtCorpPresenceTierand corporate district placementpolitical_archetype(derived, not authored)perimeter_treatmentper 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:
bodies.economic_role— district type distributionbodies.settlement_pattern— district layout and density modesystem_economy.economic_tier— infrastructure quality and wealth floorsystem_economy.distribution_index— prosperity gradient shapecorp_presencecount at this body — corporate district intensitycorporations.headquarters_systemmatch — 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.