refactor(simulation): rename DistrictSkeleton→QuarterSkeleton per D-222 (#950)

D-222 renamed the 512m generation cell from District to Quarter (District
is now a new 2048m tier above it). Align the generation skeleton code to
the canonical vocabulary. Pure naming — no behavior change; all 1296 lib
tests + integration tests pass unchanged.

Renamed (spatial-cell identifiers):
- DistrictSkeleton → QuarterSkeleton, DistrictWorldState → QuarterWorldState
- DistrictId → QuarterId, DistrictContext/DistrictBoundaries → Quarter*
- field district_id → quarter_id, district_type → quarter_type
- BodyWorldState.districts map → .quarters
- generate_skeleton → generate_quarter_skeleton

Deliberately left as-is (these name functional ZONING, not the spatial
tier — orthogonal to D-222): DistrictType, DistrictLayoutMode, the
district_mix module (DistrictMix/compute_district_mix), and the
GenWorkItem::GenerateSkeleton / GenCompletion::SkeletonGenerated variants.

Also aligned the perception "sim tile" → "subtile" vocabulary (D-222:
Subtile = 0.5m) in decisions/perception.md and the generation-cascade code
comments. Historical D-066/D-094/D-201/D-220 decision bodies keep their
existing D-222 amendment notes (not rewritten in place); the public
max_offset_sim_tiles fn name is unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-05 13:06:44 +02:00
co-authored by Claude Opus 4.8
parent f7a21c6b8d
commit c71c26a1a6
10 changed files with 108 additions and 97 deletions
+27 -25
View File
@@ -1,6 +1,6 @@
//! World generator data model — district skeleton and mobile chunk types.
//! World generator data model — quarter skeleton and mobile chunk types.
//!
//! Phase 1 generator output: the `DistrictSkeleton` produced by the world generation
//! Phase 1 generator output: the `QuarterSkeleton` produced by the world generation
//! pipeline. Consumed by Phase 2 (chunk fill) and by the simulation startup path.
//!
//! **D-110 (signed z-levels):** All z-level *position* fields use `i8` (negative values
@@ -24,7 +24,7 @@ use serde::{Deserialize, Serialize};
// ---------------------------------------------------------------------------
/// Unique district identifier (content-addressable via hash of world position + seed).
pub type DistrictId = u64;
pub type QuarterId = u64;
/// Unique multi-block reservation identifier within a district.
pub type ReservationId = u64;
/// Unique social site identifier within a district.
@@ -55,13 +55,13 @@ pub type ChunkLayout = String;
/// Corridor spine connecting district access points. Stub.
pub type CorridorSpine = String;
/// District context — neighboring districts, world position, system. Stub.
pub type DistrictContext = String;
pub type QuarterContext = String;
/// Society profile reference (Miri's cultural ingredients). Stub.
pub type SocietyProfileRef = String;
/// Zone definition — base palette + modifiers + zone name. Stub.
pub type ZoneDefinition = String;
/// District boundary system — edge descriptors with neighbors. Stub.
pub type DistrictBoundaries = String;
pub type QuarterBoundaries = String;
/// Guarantee audit result — tier-appropriate spatial invariant checks. Stub.
pub type GuaranteeAuditResult = String;
/// District access point (entry/exit to neighboring district). Stub.
@@ -939,17 +939,17 @@ pub enum ProductionUbiquity {
MonopolySource,
}
/// District-level world state produced by the plan phase (D-230).
/// Quarter-level world state produced by the plan phase (D-230).
///
/// Output of `GenerateSkeleton` extended to include building-property tags.
/// Stored in `BodyWorldState.districts: BTreeMap<DistrictId, DistrictWorldState>`.
/// Stored in `BodyWorldState.quarters: BTreeMap<QuarterId, QuarterWorldState>`.
/// `BTreeMap` for D-010 determinism.
///
/// D-230: `{ skeleton: DistrictSkeleton, block_tags: BTreeMap<(u8,u8), Vec<BuildingPropertyTag>> }`
/// D-230: `{ skeleton: QuarterSkeleton, block_tags: BTreeMap<(u8,u8), Vec<BuildingPropertyTag>> }`
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq)]
pub struct DistrictWorldState {
pub struct QuarterWorldState {
/// Phase 1 skeleton produced by `GenerateSkeleton` (D-230).
pub skeleton: DistrictSkeleton,
pub skeleton: QuarterSkeleton,
/// Building property tags keyed by block position (row, col) within the 4×4 grid.
/// Each entry is a Vec of one tag per building footprint placed in that block.
/// `BTreeMap` for D-010 determinism (no HashMap non-determinism).
@@ -999,7 +999,7 @@ pub struct CityGenerationContext {
/// Organic layout placement for a single block.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Default)]
pub struct BlockPlacement {
/// Offset from grid-aligned position (±16 sim tiles per axis max).
/// Offset from grid-aligned position (±16 subtiles per axis max).
pub offset: (i16, i16),
/// Rotation in 15° increments (03, max 45°).
pub rotation_steps: u8,
@@ -1008,8 +1008,8 @@ pub struct BlockPlacement {
pub street_width_bps: u16,
}
/// Single block within a district's 4×4 block grid.
/// Each block = 128×128 sim tiles = 2×2 chunks.
/// Single block within a quarter's 4×4 block grid.
/// Each block = 128×128 subtiles = 2×2 chunks.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
pub struct BlockSkeleton {
/// Grid position (03, 03).
@@ -1160,10 +1160,10 @@ pub struct MultiBlockReservation {
}
// ---------------------------------------------------------------------------
// District skeleton
// Quarter skeleton
// ---------------------------------------------------------------------------
/// Phase 1 generator output for one district.
/// Phase 1 generator output for one quarter.
///
/// Produced by the async background generation pipeline.
/// Consumed by Phase 2 (chunk-by-chunk fill, on demand) and by
@@ -1171,8 +1171,8 @@ pub struct MultiBlockReservation {
///
/// ## Z-level naming convention (D-110)
///
/// - `z_levels: u8` — how many floor levels exist in this district (count, always ≥ 1)
/// - `base_z` does not appear on `DistrictSkeleton` itself — the district's
/// - `z_levels: u8` — how many floor levels exist in this quarter (count, always ≥ 1)
/// - `base_z` does not appear on `QuarterSkeleton` itself — the quarter's
/// ground level is always 0. Sub-ground structures use [`MultiBlockReservation`]
/// with a negative `base_z` field.
///
@@ -1181,14 +1181,16 @@ pub struct MultiBlockReservation {
/// All `Vec<_>` fields are stable-ordered at generation time (sorted by a
/// deterministic key). Generation reproduces identical output for the same seed.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
pub struct DistrictSkeleton {
pub struct QuarterSkeleton {
// ── Identity ──────────────────────────────────────────
pub district_id: DistrictId,
pub quarter_id: QuarterId,
/// Deterministic seed (derived from master seed via SeedChain).
pub seed: u64,
pub district_type: DistrictType,
/// The quarter's primary functional zone (still a `DistrictType` — the
/// zoning vocabulary is orthogonal to the spatial tier, D-222).
pub quarter_type: DistrictType,
/// World context (system, world, neighboring districts).
pub context: DistrictContext,
pub context: QuarterContext,
// ── Classification ────────────────────────────────────
pub world_tier: WorldTier,
@@ -1197,7 +1199,7 @@ pub struct DistrictSkeleton {
pub layout_mode: DistrictLayoutMode,
// ── Spatial Structure ─────────────────────────────────
/// The 4×4 block grid (each block = 128×128 sim tiles = 2×2 chunks).
/// The 4×4 block grid (each block = 128×128 subtiles = 2×2 chunks).
pub blocks: [[BlockSkeleton; 4]; 4],
/// Multi-block reservations (skyscrapers, parks, terminals, plazas).
pub reservations: Vec<MultiBlockReservation>,
@@ -1215,7 +1217,7 @@ pub struct DistrictSkeleton {
pub zone_palette: Vec<ZoneDefinition>,
// ── Boundary System ───────────────────────────────────
pub boundaries: DistrictBoundaries,
pub boundaries: QuarterBoundaries,
// ── Validation ────────────────────────────────────────
/// Guarantee audit result. `None` for Empty districts.
@@ -1367,9 +1369,9 @@ mod tests {
assert_eq!(r.z_levels, 30u8, "z_levels count must remain u8");
}
/// D-110: z_levels (count) remains u8 on DistrictSkeleton.
/// D-110: z_levels (count) remains u8 on QuarterSkeleton.
#[test]
fn district_skeleton_z_levels_is_unsigned() {
fn quarter_skeleton_z_levels_is_unsigned() {
// Verify z_levels is u8 (cannot hold negative value). Static assertion:
// if this compiled with z_levels = 255u8, the type is correct.
fn assert_u8(_: u8) {}