docs(architecture): amend D-212 + implementation notes for #956
- D-212: add the AutonomistHeld variant (Compact of Westphalia) and record the dominant_faction → TerritorialStatus mapping used in place of the numeric faction-influence thresholds (which aren't in the data). Grounded in wiki/factions/. IndigenousHeld/Derelict noted as deferred. - D-214: note the political_archetype derivation + per-settlement storage. - D-215: note the ArrangementPattern enum + derivation land here; block-adjacency enforcement stays with the Quarter-skeleton generator (#957). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1124,9 +1124,12 @@ Technical foundation decisions that constrain implementation: engine, client-ser
|
||||
- `placed_at_generation: bool` flag on `Province` distinguishes classification at build time (true) from runtime re-classification during simulation (false). Build-time status is the starting state; simulation can change it, and the flag ensures the original classification is recoverable for reset/new-game scenarios.
|
||||
- Faction influence values are read from `systems.db` (economics tables) at build time using the same D-199 economic read pattern.
|
||||
- **Rationale:** Territory status is a high-level descriptor visible to the player on the Atlas overlay (D-191 §7, political zones overlay). It must be derivable from the generation inputs without runtime simulation state. The priority-ordered algorithm ensures clear, predictable classification — no ambiguous provinces. The `placed_at_generation` flag enables the game to show "how this province was at settlement time" vs. "how it is now."
|
||||
- **Ticket:** #921
|
||||
- **Amended 2026-06-05 (#956 — implementation):** two changes from the original spec.
|
||||
1. **New variant `AutonomistHeld`** added between `FrontierUnclaimed` and `IndigenousHeld`. The original four control buckets (Commission/Corp/Contested/Frontier) predate the richer faction canon (`wiki/factions/`): the **Compact of Westphalia** is a self-governing autonomist bloc that rejects Concord Assembly authority — it governs its systems firmly, so it is neither `CommissionControlled` (it is the Assembly's *rival*), nor `FrontierUnclaimed` (it is *not* ungoverned), nor locally `ContestedZone` (the Compact is locally dominant). `AutonomistHeld` is its bucket, and gives the Compact its own colour on the political-zones overlay.
|
||||
2. **Derivation source.** The numeric per-faction `faction_influence` thresholds the original record specifies are **not present in the data** — only a single authored `dominant_faction` per system exists (D-237's 8-value vocabulary). So the implementation maps `dominant_faction → TerritorialStatus` instead (`attractor_matching::territorial_status_from_faction`), grounded in faction canon: `concord_assembly`/`veil_institute` → `CommissionControlled` (the Assembly is the Reach's central government; the Veil Institute is Assembly-funded and -aligned); `syndic_dominant` → `CorpTerritory`; `compact`/`compact_sympathetic` → `AutonomistHeld`; `disputed`/`mixed` → `ContestedZone`; `independent`/NULL/unknown → `FrontierUnclaimed`. `IndigenousHeld` and `Derelict` remain unreachable from `dominant_faction` alone (they need the cultural-corridor autonomy flag / population density) — deferred. `dominant_faction` is system-level, so status is uniform across a body's provinces for now; it is still stored per-basin on `DrainageBasin.territorial_status` (forward-compatible for per-province faction data). `placed_at_generation` is not yet modelled (no runtime re-classification exists yet).
|
||||
- **Ticket:** #921, #956 (implementation + amendment)
|
||||
- **Raised by:** Generation cascade workshop (#897)
|
||||
- **Cross-reference:** D-191 (atlas overlay — political zones), D-199 (economic read set), D-205 (Province — this status is a field on it)
|
||||
- **Cross-reference:** D-191 (atlas overlay — political zones), D-199 (economic read set), D-205 (Province — this status is a field on it), [D-237](#d-237) (authored `dominant_faction` source), D-214 (PoliticalArchetype — consumes this)
|
||||
|
||||
### D-213: FoundingOrientation Enum and Spatial Grid Rotation
|
||||
- **Date:** 2026-05-01
|
||||
@@ -1168,7 +1171,8 @@ Technical foundation decisions that constrain implementation: engine, client-ser
|
||||
- **`AttractorAssignment` disambiguation:** `OrganicGrowth` (a `DistrictType` value and also an `EraCause` value) is always unambiguous in context. On `DistrictType`, it means the district grew without a planning mandate. As `EraCause`, it means the era tag was acquired through organic settlement expansion rather than a discrete historical event. Both usages are permitted; the type system distinguishes them.
|
||||
- **Rationale:** Power structure should be legible in a city's spatial form without the player reading a wiki entry. Commission cities look different from Corporate cities look different from Pioneer cities — not just in palette, but in street geometry, district type distribution, and building scale. Encoding this as a named enum ensures the distinction is consistent across all generation code.
|
||||
- **Amended 2026-05-31 ([D-237](#d-237) — authored specialization layer):** for named systems `dominant_faction` (a D-214 derivation input via `TerritorialStatus`/D-199) is now an **authored** value (8-value vocabulary: `concord_assembly | compact | compact_sympathetic | syndic_dominant | veil_institute | independent | disputed | mixed`) rather than one the heuristic guesses from hop-distance/currency; the existing derivation remains the fallback for unauthored systems. The archetype mapping itself is unchanged — it now reads a more trustworthy faction for the ~40–60 named systems where the heuristic was demonstrably wrong (e.g. Groombridge resolves `syndic_dominant` → Corporate, not the hop-2 default that would yield Commission). `lattice_commission` is deliberately **not** a faction value — the Commission is a regulator, not a governing faction (ACB and Bastion are `concord_assembly`).
|
||||
- **Ticket:** #914
|
||||
- **Implemented 2026-06-05 (#956):** `attractor_matching::political_archetype(territorial_status, economic_role)` lands the derivation, stored per settlement on `CityPlacement.political_archetype`. `TerritorialStatus` precedence is enforced (a Commission-controlled manufacturing hub → `Commission`, not `Industrial`); statuses that don't dictate an archetype (`ContestedZone`/`IndigenousHeld`/`Derelict`) fall through to `economic_role`, and the new `AutonomistHeld` (D-212 amendment) → `Pioneer` (self-organized, no central planner). The "spatial effect on district mix" (D-194 weight multipliers) is consumed later by the Quarter-skeleton generator (#957).
|
||||
- **Ticket:** #914, #956 (archetype derivation + storage)
|
||||
- **Raised by:** Generation cascade workshop (#897)
|
||||
- **Cross-reference:** D-194 (district mix — archetype modifiers), D-212 (TerritorialStatus — primary input), D-213 (FoundingOrientation — archetype may override), D-215 (spatial arrangement patterns), [D-237](#d-237) (authored `dominant_faction` source)
|
||||
|
||||
@@ -1183,7 +1187,8 @@ Technical foundation decisions that constrain implementation: engine, client-ser
|
||||
- The arrangement pattern constrains block adjacency during Phase 1 skeleton generation. Specifically: the first 2–3 districts placed in a settlement follow the pattern. Later districts are constrained only by the road network, not by the pattern.
|
||||
- Arrangement patterns must **vary in angular orientation** per seed (not just position) — the same archetype's radial core must not always face the same direction across seeds.
|
||||
- **Rationale:** The 14 D-ready items from the generator-architecture workshop established that spatial arrangement should encode power structure. These five patterns are the minimal set to cover the 6 archetypes (Pioneer and Industrial share ribbon development; hub-and-spoke is a cross-archetype pattern for transit-primary cities). Pattern variation in angular orientation prevents players from pattern-matching settlement layout after the first playthrough.
|
||||
- **Ticket:** #914 (types), #899 (implementation — Phase 1 skeleton generator)
|
||||
- **Implemented 2026-06-05 (#956):** the `ArrangementPattern` enum (the five patterns) and its derivation (`attractor_matching::arrangement_pattern`, from `PoliticalArchetype` + transit_hub override) land here, and the chosen pattern is **stored** per settlement on `CityPlacement.arrangement_pattern`. The block-adjacency **enforcement** (constraining the first 2–3 quarters' layout) is the Quarter-skeleton generator's job and is deferred to #957; the per-seed angular variation rides on `FoundingOrientation` (D-213, seed-derived `Free` bearing).
|
||||
- **Ticket:** #914 (types), #956 (enum + derivation + storage), #899/#957 (skeleton-gen enforcement)
|
||||
- **Raised by:** Generation cascade workshop (#897)
|
||||
- **Cross-reference:** D-094 (spatial hierarchy — district sizes), D-194 (district mix — archetype modifiers), D-214 (PoliticalArchetype — pattern assignment)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user