diff --git a/decisions/architecture.md b/decisions/architecture.md index 2aa135550..474eff4de 100644 --- a/decisions/architecture.md +++ b/decisions/architecture.md @@ -171,6 +171,7 @@ Technical foundation decisions that constrain implementation: engine, client-ser - **Sprites: 2x2 sim tile footprint.** Entity sprites render across 2x2 sim tiles so they feel proportional to the 1m visual grid. Tween interpolation ([D-054](#d-054-tile-based-movement-with-same-tile-occupancy)) hides half-visual-tile movement increments. - **Mental model:** "Objects are where they look. I can position myself precisely within open space." The player reads cover and walls at visual scale (always correct). Fine movement granularity is felt, not counted. - **What the simulation does NOT know:** Visual tiles. The retina factor is purely a client rendering convention. The server operates exclusively on 0.5m sim tiles. +- **Amendment (2026-05-22, [D-222](#d-222)):** canonical vocabulary. This 0.5m "sim tile" is now the **Subtile** — the granularity the server simulation, entity positioning, and render detail run on. The **Tile = 1m** (2×2 subtiles) is the unit sizes are quoted in and the one the world-generation cascade, pathfinding, and grids operate on. The dual-scale model and the 0.5m simulation granularity are unchanged; only the naming primacy flips. The Chunk/Block/Quarter/District ladder built on the Tile is canonical in D-222. - **Fog shader ([D-059](perception.md#d-059-fog--shader-based-five-layers-knowledge-graph-driven)):** Unaffected — fog is screen-space, driven by PointLight2D vision cone and LOS mask from sim-resolution shadowcasting. Gradient edge "3-4 tiles" is retuned to 6-8 sim tiles (= 3-4 visual tiles) to preserve the intended softness. - **Cursor/interaction:** No change — cursor already resolves to sim tile from pixel position. Interaction range of ~2 sim tiles = 1m (arm's length). - **Map authoring:** Author at 1m visual scale. Subdivision tool expands each visual tile to 4 sim tiles (2x2). Validation enforces 2x2 minimum on all world geometry layers. @@ -239,6 +240,7 @@ Technical foundation decisions that constrain implementation: engine, client-ser ### D-094: District Spatial Hierarchy — Chunk, Block, District Naming and Sizes - **Date:** 2026-02-25 - **Decision:** The spatial hierarchy for map generation and streaming is defined as follows. **Chunk** = 64×64 sim tiles (32×32 visual tiles, 32m) — the streaming and serialization unit. **Block** = 128×128 sim tiles (64×64 visual tiles, 64m) — the generator planning unit, composed of 4 chunks arranged in a 2×2 grid. Each block contains 4 chunks; chunks within a block can merge into one large edifice, remain separate (small buildings, gardens, cafes), or form L-shaped buildings across chunk boundaries. **District** = 4×4 blocks = 512×512 sim tiles (256×256 visual tiles, 256m) per z-level, containing 16 blocks and 64 chunks. Large civic structures (gate terminals, horizon station installations, stadiums, parks) span multiple blocks. Three z-levels for the Transit District = ~1.35MB (trivial). This decision amends D-012 and overrides the ~150×150 visual estimate in D-014. +- **Amendment (2026-05-22, [D-222](#d-222)):** naming + scale superseded. The unit this record calls a **District** (4×4 blocks) is renamed the **Quarter** (now 512m at Tile = 1m); **District** is promoted to a new 2048m tier (4×4 quarters). Tier *counts* and nesting structure here are unchanged — only the names and the metre values (per the Tile = 1m / Subtile = 0.5m scale of D-220). See D-222 for the canonical ladder and the lore-vs-code rule. - **Rationale:** Chunk size of 32×32 visual (64×64 sim) gives a 32m streaming cell — large enough to hold a meaningful space, small enough for efficient streaming. The 2×2-chunk block provides a generator planning unit with enough granularity for per-chunk variation. The 4×4 block district (256×256 visual) gives a full district footprint generalisable as a template for the Q-036 generator. The chunk-based fill system within blocks allows the generator to place buildings of varying scale without hard-coding building dimensions. - **Raised by:** Tyre (chunk/block spec and memory confirmation), confirmed by team. Lead ratified district = 4×4 blocks. - **Dissent:** Araminta preferred 32×32 visual chunk size (effectively halving the chunk to a 16m cell). Overruled by lead and team majority — 32m chunk is the minimum viable streaming cell for the simulation architecture. @@ -885,14 +887,15 @@ Technical foundation decisions that constrain implementation: engine, client-ser | 3 | Body | ~512×256 pixels (equirectangular heightmap) | Planetary topography, climate zones | | 4 | Region | ~50–500km | Province boundaries (watershed-derived, D-205), biome zones | | 5 | Settlement | ~1–30km radius | City footprint, district layout | - | 6 | District | 512×512 sim tiles (256m) | Phase 1 skeleton, 4×4 block grid (D-094) | - | 7 | Block | 128×128 sim tiles (64m) | Generator planning unit, 2×2 chunks (D-094) | - | 8 | Chunk | 64×64 sim tiles (32m) | Streaming/serialization unit (D-094) | + | 6 | District | 2048×2048 tiles (2048m, 4.19 km²) | 4×4 quarters — large urban division (D-222) | + | 7 | Quarter | 512×512 tiles (512m, 0.262 km²) | 4×4 blocks — settlement footprint cell, Phase 1 skeleton grid (D-222) | + | 8 | Block | 128×128 tiles (128m) | Generator planning unit, 2×2 chunks (D-222) | + | 9 | Chunk | 64×64 tiles (64m) | Streaming/serialization unit (D-222) | - - Tiers 6–8 are locked by D-094 (district spatial hierarchy). This decision formalizes Tiers 1–5 with equivalent lock status. + - Tiers 6–9 (District → Chunk) are the sub-settlement spatial hierarchy, canonical in [D-222](#d-222) — renamed/resized from the original D-094 ladder (the old 512m "District" is now the Quarter; District is now 2048m), at the Tile = 1m / Subtile = 0.5m scale of D-220. This decision formalizes Tiers 1–5 with equivalent lock status. - Tier 3 heightmap resolution (512×256 equirectangular at 1024×512 PNG) is the canonical format. Deviation requires amending D-191. - Tier 4 province boundaries are pre-computed at build-time and stored in `atlas_province_boundaries` (D-205). They are not re-computed at runtime. - - The `SettingType` enum on `DistrictSkeleton` is the interface between Tier 5 (settlement planning) and Tier 6 (district generation). + - The `SettingType` enum on `DistrictSkeleton` is the interface between Tier 5 (settlement planning) and the skeleton cell (the 512m Quarter, Tier 7 — `DistrictSkeleton` is pending rename to match D-222). - **Rationale:** Locking spatial dimensions prevents the generative layers from drifting in incompatible directions. The heightmap pipeline, atlas pipeline, and district generator all assume these dimensions and would need coordinated migration if they changed. Formalization prevents silent per-system variation. - **Ticket:** #912 (WorldTier enum), #913 (SettlementClass) - **Raised by:** Generation cascade workshop (#897) @@ -1254,6 +1257,8 @@ Technical foundation decisions that constrain implementation: engine, client-ser Each tile contains 2×2 subtiles. The generation cascade operates in tiles. The renderer subdivides to subtiles for visual fidelity. All higher tiers (Province, Area, Body) remain as defined in D-201. + - **Amendment (2026-05-22, [D-222](#d-222)):** the 512m unit this table calls **District** is renamed the **Quarter**; **District** is promoted to a new 2048m tier (4×4 quarters). The Tile/Subtile scale above is unchanged. Throughout this record — including the footprint formula (`district_count = footprint / 0.262`) and the density examples — "district" denotes the **0.262 km² Quarter cell**, not the new 2048m District. See D-222 for the canonical ladder and the lore-vs-code rule. + **Density classes:** Density is measured in people per km² of settlement footprint. It is the primary driver of settlement character — not population alone. The same population at different densities produces completely different settlements. @@ -1376,4 +1381,33 @@ Technical foundation decisions that constrain implementation: engine, client-ser --- -*80 decisions (D-001 through D-220, excluding gaps). Last updated: 2026-05-03 (D-220 — Settlement Density Model, design session)* +### D-222: Spatial hierarchy and naming — Subtile to District, lore vs code +- **Date:** 2026-05-22 +- **Decision:** Canonical naming and sizes for the sub-settlement spatial hierarchy. This record is the single source of truth for the ladder; it supersedes the dimensions/naming scattered across D-094 (hierarchy), D-201 (tier table), D-220 (tile scale), and D-066 (dual-scale grid), which are amended to point here. + + **The ladder (each tier nests cleanly in the one above):** + + | Unit | Side | Composition | Real-world analogue | Used for | + |------|------|-------------|---------------------|----------| + | Subtile | 0.5m | — | a footstep | server simulation, entity positioning, render detail | + | Tile | 1m | 2×2 subtiles | a doorway | **the unit all sizes are quoted in**; generation cascade, pathfinding, grids | + | Chunk | 64m | 64×64 tiles | half a block | streaming / serialization unit (technical) | + | Block | 128m | 2×2 chunks | a city block (~100m real) | generator planning unit | + | Quarter | 512m | 4×4 blocks (16) | a superblock (≈ Barcelona *superilla*, 0.262 km²) | the cell a settlement footprint is tiled into | + | District | 2048m | 4×4 quarters (256 blocks) | a real urban district (4.19 km²) | large urban division | + | *(above)* | *fluid* | — | borough / sector / city | **not a fixed tier** — settlements vary too much; groupings above District are settlement-specific | + + Nesting rhythm: Chunk→Block is 2×2 (Chunk is a technical sub-block streaming unit); Block→Quarter→District is a uniform 4×4 (the legible "human" ladder). + + **Lore ≠ code (load-bearing):** the tier names above are **code/generation units** — fixed grid cells. The *same words* used in lore, narrative, and UI ("Sova Transit District", "the market quarter") are **free-form region labels** with no obligation to map to a code tier. A narrative "district" may span several code Quarters, sit inside one, or ignore the grid entirely. **Reviewers and the clerk must not reconcile a lore name to a code tier** — they are different registers that happen to share vocabulary. + + **Rename from prior records:** the 512m cell that D-094 / D-201 / D-220 called a **District** is now the **Quarter**. "District" is promoted to the 2048m tier (4×4 quarters), matching the real-world scale of a named urban district. The tile scale (Tile = 1m, Subtile = 0.5m) and the doubled footprints established by D-220 are unchanged. Code that uses "District" for the 512m skeleton unit (e.g. `DistrictSkeleton`) is now misnamed → see follow-up ticket. + +- **Rationale:** The old hierarchy named only Chunk/Block/District and jumped from a 512m "District" straight to the 1–30km Settlement, leaving the 512m cell wearing the name of a unit two rungs too large — a real district is kilometres and many neighborhoods, not 16 blocks. Grounding against real sizes (city block ~100m; Barcelona superblock 400m / 9 blocks; real district several km) puts Block at 128m (correct), the 512m cell at Quarter/superblock, and a true District at 2048m (4.19 km²). Leaving everything above District fluid matches reality — boroughs/sectors/cities vary too much to force a fixed generation tier, and the Reach's settlements range from frontier homesteads to compressed capitals. Separating the lore register from the code register lets narrative use "district" naturally without dragging the generator's grid into it. +- **Raised by:** Jeroen + Claude, design session 2026-05-22. Grounded against real-world block/superblock/district scales. +- **Cross-reference:** [D-094](#d-094) (spatial hierarchy — renamed/superseded), [D-201](#d-201) (tier table — superseded for the sub-settlement tiers), [D-220](#d-220) (tile scale — Tile/Subtile retained; its "district" footprint cell is the Quarter), [D-066](#d-066-dual-scale-grid--05m-simulation-1m-visual-2x-retina-factor) (dual-scale — Subtile is the 0.5m grid), [D-093](content.md#d-093-sova-transit-district--spatial-layout-and-district-topology) (Sova Transit District — a *lore* district, not bound to the code tier) +- **Dissent:** None + +--- + +*82 decisions (D-001 through D-222, excluding gaps). Last updated: 2026-05-22 (D-222 — Spatial hierarchy and naming)*