A* over the L1 terrain-cost field (ocean/lake impassable, river ½, slope ≥35° ×10, else D-210 terrain_modification_cost) on a coarse 64-wide grid, equirectangular wrap
MaintenanceAuthority per edge (new enum) from endpoint archetypes + haul length; waypoints; named-route join (designed-for, pool empty post-D-223); junction detection
10 road_graph unit tests + cascade e2e test; full suite + clippy --all-targets -D warnings green
Decisions
D-242 — corp-HQ settlement model: HQs leave the city name pool; placement is a specialization-keyed CityTenant/Standalone preference; population/settlement_class install-baked. Tickets T-1074/1075/1076.
D-243 — spatial scale ladder (resolves Q-110): nested absolute containment voxel → chunk → block → quarter → district → region (~205 km) with a single elastic region ↔ planet seam; region is the climate/weather/season lockdown scale, edge-fuzzed; D-201 tier-4 Region → Province. Recorded in CLAUDE.md. Tickets T-1077/1078; unblocks T-1046.
Verification
cargo fmt --check, cargo clippy --all-targets -D warnings, full cargo test — all green
Reviewing the T-1038 road-graph hub model surfaced that corp HQs are
cross-referenced into atlas_city_names as reserved rows — one per corp —
producing duplicate co-named "cities" (e.g. 10 'Groombridge' rows on
GJ380c) that the spatial layers place as separate settlements.
D-242 resolves the data model: corp HQs are not cities. The HQ relationship
lives with the corp; placement is a baked, specialization-keyed preference
(CityTenant vs Standalone, since corp_type is degenerate); population and
settlement_class are install-baked with only position seed-derived. This
supersedes the D-223 corp-HQ-cross-ref and deferred-pop/class notes.
Companion tickets under T-750: T-1074 (corp-HQ model / remove the cross-ref /
specialization map / standalone HQ settlements), T-1075 (bake per-settlement
population + settlement_class), T-1076 (road-graph hub refinement — scaled-cap
hubs, co-location collapse, hybrid minor attach, deferred RailHeadFacing pass;
blocked on T-1074 + T-1075). T-1038 annotated with shipped-vs-deferred.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
New deterministic cascade layer (CascadeLayer::RoadGraph) building the
transport topology between Layer-3 settlement placements, stored on
BodyWorldState.road_graph (session-cached, never serialized).
- MST force-connect (strict Kruskal over squared distance) + secondary
links across a 30-60% body-scale band where the MST detours >1.5x.
- A* over the Layer-1 terrain-cost field on a coarse ~64-wide routing grid:
ocean/lake impassable, river corridors 1/2 cost, slope >=35deg (D-210
roughness ~0.7) 10x, else the D-210 terrain_modification_cost. Columns
wrap (equirectangular); integer costs + index tie-break keep A*
deterministic.
- MaintenanceAuthority per edge (new generator.rs enum) from endpoint
political archetypes + haul length; waypoint nodes at long-edge midpoints;
named-route identity join (designed-for, pool empty post-D-223); junction
detection (high_connectivity_junctions, degree>=3).
Wired into the cascade (gen_queue requests CascadeLayer::RoadGraph). Adds
Copy to PoliticalArchetype. 10 road_graph unit tests + a cascade e2e test;
full suite + clippy --all-targets -D warnings green.
Deferred to T-1076 (gated on the D-242 settlement model): the RailHeadFacing
junction pass (needs a D-213 FoundingOrientation amendment + Layer-4 handling)
and the hub-selection refinement (needs baked population/specialization).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Resolves Q-110 (region/chunk physical-scale anchoring), which had three
contradictory metres-per-scale assumptions in the cascade and no record
fixing metres-per-heightmap-pixel.
D-243 establishes a nested absolute-metre containment ladder with a single
elastic seam at planetary scale:
voxel 1m -> chunk 64m -> block 128m -> quarter 512m -> district 2km
-> region ~205km (100x100 districts) -> (elastic) -> planet
A body holds round(2*pi*R/204.8km) regions (the only per-body-floating
quantity); everything below is fixed integer math, so ChunkPos->RegionPos
is body-independent. The region is the largest hard block: the climate/
weather/season lockdown scale (the Q-105 cheap-dynamism source) and the
sane planetary grid. Sub-heightmap detail is invented deterministically
(interpolation + domain warp + detail-scatter, never stored, D-227); climate
is edge-fuzzed so the grid never shows ('climate does not change on a line').
Vocabulary locked and recorded in CLAUDE.md: 'region' = the 205km metric
cell only; the old 1km RegionProfile is dropped onto the 2km district; D-201
tier-4 'Region' renamed Province (the watershed/political overlay), amended
here. Refines D-239 §2 (district temperature now modulates a region baseline).
Implementation tickets: T-1077 (re-scale the code to the ladder + elastic-seam
resampling; blocks T-1046) and T-1078 (region climate stack + edge fuzz).
T-1046 is un-gated on Q-110 and now blocked only by T-1077.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Layer-2 inter-settlement road/rail graph (T-1038) plus the two cascade-scale architecture decisions that came out of reviewing it.
Feature — Layer 2 road/rail graph (T-1038)
Deterministic
road_graphcascade layer (CascadeLayer::RoadGraph, stored onBodyWorldState.road_graph, never serialized):terrain_modification_cost) on a coarse 64-wide grid, equirectangular wrapMaintenanceAuthorityper edge (new enum) from endpoint archetypes + haul length; waypoints; named-route join (designed-for, pool empty post-D-223); junction detectionclippy --all-targets -D warningsgreenDecisions
voxel → chunk → block → quarter → district → region (~205 km)with a single elasticregion ↔ planetseam; region is the climate/weather/season lockdown scale, edge-fuzzed; D-201 tier-4Region → Province. Recorded in CLAUDE.md. Tickets T-1077/1078; unblocks T-1046.Verification
cargo fmt --check,cargo clippy --all-targets -D warnings, fullcargo test— all greenpql decisions validate+sync— 0 broken refs🤖 Generated with Claude Code
Resolves Q-110 (region/chunk physical-scale anchoring), which had three contradictory metres-per-scale assumptions in the cascade and no record fixing metres-per-heightmap-pixel. D-243 establishes a nested absolute-metre containment ladder with a single elastic seam at planetary scale: voxel 1m -> chunk 64m -> block 128m -> quarter 512m -> district 2km -> region ~205km (100x100 districts) -> (elastic) -> planet A body holds round(2*pi*R/204.8km) regions (the only per-body-floating quantity); everything below is fixed integer math, so ChunkPos->RegionPos is body-independent. The region is the largest hard block: the climate/ weather/season lockdown scale (the Q-105 cheap-dynamism source) and the sane planetary grid. Sub-heightmap detail is invented deterministically (interpolation + domain warp + detail-scatter, never stored, D-227); climate is edge-fuzzed so the grid never shows ('climate does not change on a line'). Vocabulary locked and recorded in CLAUDE.md: 'region' = the 205km metric cell only; the old 1km RegionProfile is dropped onto the 2km district; D-201 tier-4 'Region' renamed Province (the watershed/political overlay), amended here. Refines D-239 §2 (district temperature now modulates a region baseline). Implementation tickets: T-1077 (re-scale the code to the ladder + elastic-seam resampling; blocks T-1046) and T-1078 (region climate stack + edge fuzz). T-1046 is un-gated on Q-110 and now blocked only by T-1077. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>Pull request closed