feat(simulation): Layer-1 water bearing + D-234 waterfront rule (#957)
Close the last D-234 piece — terrain water-direction extraction wired through to founding orientation and the quarter waterfront rule: - Layer 1: TerrainAnalysis::water_bearing — 8-octant integer bearing toward the nearest water from the water_dist gradient (D-010, no atan2). Stored on GeographicAttractor.water_bearing (360 = none). - #956 founding orientation: coastal/river settlements now get a real water-facing bearing (the anchoring attractor's), replacing the 0 stub. - #957 waterfront rule (D-234b): the water-facing quarter edge (from the settlement's Coastal founding orientation) drops its block setback to 0 so buildings present flush to the quay (dock-orthogonal). Typed Edge + coastal_edge + per-block gating. Golden + atlas_response fixture rebaked (additive water_bearing field only). 8 new tests. All integer-deterministic (D-010). Pending: the waterfront rule reads context.founding_orientation, which city_context_reader still stubs to Cardinal — real per-settlement orientation reaches quarter generation once the Layer-3 placement -> Layer-4 GenerateSkeleton dispatch is wired (the remaining cross-layer integration). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
|
||||
use tracing::{error, warn};
|
||||
|
||||
use crate::atlas::features::NO_WATER_BEARING;
|
||||
use crate::seed::{splitmix64, SeedChain};
|
||||
use crate::simulation::generator::{
|
||||
AttractorType, CompatibilityMatrix, GeographicAttractor, SettlementClass, SubBiomeVariant,
|
||||
@@ -265,6 +266,7 @@ fn synthetic_attractor(placed: &[CityPlacement], grid_w: u32, grid_h: u32) -> Ge
|
||||
strength: 50,
|
||||
sub_biome: SubBiomeVariant::TemperateGrassland,
|
||||
terrain_modification_cost: 100,
|
||||
water_bearing: NO_WATER_BEARING, // inland synthetic — no water direction
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,6 +284,7 @@ fn synthetic_attractor(placed: &[CityPlacement], grid_w: u32, grid_h: u32) -> Ge
|
||||
/// grids vary per seed (D-213) while staying deterministic (D-010).
|
||||
fn city_character(
|
||||
attractor_type: AttractorType,
|
||||
water_bearing: u16,
|
||||
economic_role: &str,
|
||||
territorial_status: &TerritorialStatus,
|
||||
city_id: u64,
|
||||
@@ -290,9 +293,15 @@ fn city_character(
|
||||
let archetype = political_archetype(territorial_status, economic_role);
|
||||
let pattern = arrangement_pattern(&archetype, economic_role);
|
||||
let free_bearing = (splitmix64(seed.seed() ^ city_id) % 360) as u16;
|
||||
// river_bearing / coastal_facing are 0 until Layer 1 exposes terrain bearings
|
||||
// (D-209 follow-on); free_bearing seeds the pioneer/open-terrain case.
|
||||
let orientation = founding_orientation(&attractor_type, territorial_status, 0, 0, free_bearing);
|
||||
// Layer-1 water bearing (#957) drives both the coastal facing and the river
|
||||
// bearing (the anchoring attractor's direction-to-water); 360 = none → 0.
|
||||
let wb = if water_bearing >= 360 {
|
||||
0
|
||||
} else {
|
||||
water_bearing
|
||||
};
|
||||
let orientation =
|
||||
founding_orientation(&attractor_type, territorial_status, wb, wb, free_bearing);
|
||||
(archetype, pattern, orientation)
|
||||
}
|
||||
|
||||
@@ -354,6 +363,7 @@ pub fn match_cities(
|
||||
flag_mismatch(&cities[ci].name, score);
|
||||
let (archetype, pattern, orientation) = city_character(
|
||||
attractors[ai].attractor_type,
|
||||
attractors[ai].water_bearing,
|
||||
&cities[ci].economic_role,
|
||||
territorial_status,
|
||||
cities[ci].city_id,
|
||||
@@ -420,6 +430,7 @@ pub fn match_cities(
|
||||
flag_mismatch(&cities[ci].name, score);
|
||||
let (archetype, pattern, orientation) = city_character(
|
||||
attractors[ai].attractor_type,
|
||||
attractors[ai].water_bearing,
|
||||
&cities[ci].economic_role,
|
||||
territorial_status,
|
||||
cities[ci].city_id,
|
||||
@@ -453,6 +464,7 @@ pub fn match_cities(
|
||||
flag_mismatch(&city.name, score);
|
||||
let (archetype, pattern, orientation) = city_character(
|
||||
AttractorType::PlainCenter,
|
||||
synthetic.water_bearing,
|
||||
&city.economic_role,
|
||||
territorial_status,
|
||||
city.city_id,
|
||||
@@ -659,6 +671,7 @@ mod tests {
|
||||
strength,
|
||||
sub_biome: SubBiomeVariant::TemperateGrassland,
|
||||
terrain_modification_cost: 100,
|
||||
water_bearing: NO_WATER_BEARING,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user