From 6aafa7758359e768ef77000e88700fa8f0e4637a Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Fri, 17 Jul 2026 08:21:27 +0200 Subject: [PATCH] feat(simulation): T-1127 glaciation ice tint + Marine color in zoom-ladder probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit aliveness_probe --render gains a 6th glaciation panel; glaciated districts get an ice tint keyed on GlaciationGrade, and Marine vegetation renders [0,96,172] — distinct from the morphology water tones so district-carrier vs voxel-generator disagreement stays visible in ladders. Co-Authored-By: Claude Fable 5 --- server/src/bin/aliveness_probe.rs | 65 ++++++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 5 deletions(-) diff --git a/server/src/bin/aliveness_probe.rs b/server/src/bin/aliveness_probe.rs index 74d5e1cad..d073364c5 100644 --- a/server/src/bin/aliveness_probe.rs +++ b/server/src/bin/aliveness_probe.rs @@ -37,7 +37,8 @@ use settled_reach_server::atlas::believability::{ use settled_reach_server::atlas::body_world_state::BodyWorldState; use settled_reach_server::atlas::chunk_context::derive_chunk_context; use settled_reach_server::atlas::district_profile::{ - derive_district, BodyParams, ClimateConstants, DistrictProfile, VegetationClass, + derive_district, BodyParams, ClimateConstants, DistrictProfile, GlaciationGrade, + VegetationClass, }; use settled_reach_server::atlas::features::TerrainAnalysis; use settled_reach_server::atlas::scale::{ @@ -335,8 +336,17 @@ const MORPHOLOGY_RGB: [[u8; 3]; 17] = [ [64, 115, 102], // 16 Wetland ]; -/// The five attribute panels, in output order. -const PANEL_NAMES: [&str; 5] = ["morphology", "elev", "temp", "moisture", "veg"]; +/// The attribute panels, in output order. `glaciation` is T-1127's dedicated +/// panel; the morphology panel additionally carries a per-pixel ice tint keyed +/// on the same field (see [`apply_ice_tint`]). +const PANEL_NAMES: [&str; 6] = [ + "morphology", + "elev", + "temp", + "moisture", + "veg", + "glaciation", +]; /// Render the district window around the principal settlement and write one PNG /// per panel to `out_dir`, plus a one-line manifest per image and a determinism @@ -447,7 +457,7 @@ fn render_window_panels( ) -> Vec<(&'static str, Vec)> { let n_i = n as i32; let half = n_i / 2; - let mut bufs: [Vec; 5] = std::array::from_fn(|_| vec![0u8; (n * n) as usize * 3]); + let mut bufs: [Vec; 6] = std::array::from_fn(|_| vec![0u8; (n * n) as usize * 3]); for row in 0..n_i { for col in 0..n_i { // Row 0 = northmost: smaller dy = further north (derive_district maps @@ -455,11 +465,19 @@ fn render_window_panels( let dp = (centre.0 - half + col, centre.1 - half + row); let prof = derive_district(seed, body_id, params, ta, dp, climate); let i = ((row * n_i + col) * 3) as usize; - set_rgb(&mut bufs[0], i, morphology_rgb(prof.morphology_zone)); + // T-1127: the morphology color carries a per-pixel ice tint keyed on + // glaciation_grade (a render modifier — the frozen D-239 §6 zone + // vocabulary is untouched; tint = classifier-tuning territory). + set_rgb( + &mut bufs[0], + i, + apply_ice_tint(morphology_rgb(prof.morphology_zone), prof.glaciation_grade), + ); set_rgb(&mut bufs[1], i, gray_rgb(prof.elev_q)); set_rgb(&mut bufs[2], i, temperature_rgb(prof.temperature_c)); set_rgb(&mut bufs[3], i, moisture_rgb(prof.moisture_q)); set_rgb(&mut bufs[4], i, vegetation_rgb(prof.vegetation_class)); + set_rgb(&mut bufs[5], i, glaciation_rgb(prof.glaciation_grade)); } } for buf in &mut bufs { @@ -566,6 +584,43 @@ fn vegetation_rgb(v: VegetationClass) -> [u8; 3] { VegetationClass::Forest => [30, 110, 40], // closed canopy VegetationClass::RiparianScrub => [70, 170, 120], // waterway band (open) VegetationClass::RiparianThicket => [10, 130, 90], // waterway band (dense) + // T-1126: open water — an ocean blue deliberately DISTINCT from the + // morphology water tones (OpenOcean 26,51,115 / Lake 51,102,166) so a + // veg-panel Marine cell is never mistaken for a morphology overlay. + VegetationClass::Marine => [0, 96, 172], + } +} + +/// T-1127: blend the morphology color toward glacial ice-white by +/// `glaciation_grade` — a RENDER modifier only (the D-239 §6 frozen 17-zone +/// vocabulary is untouched; an actual ice zone would need its own D-amendment). +/// +/// `Light` deliberately does NOT tint: grade 1 is glacial-erosion *signatures* +/// (U-valleys, moraines — landform history on coasts as warm as +5 °C mean), +/// not ice cover; visible ice starts where D-239 §5 gates glacial forms, +/// grade ≥ Moderate. The dedicated glaciation panel still shows Light. +fn apply_ice_tint(base: [u8; 3], grade: GlaciationGrade) -> [u8; 3] { + let t = match grade { + GlaciationGrade::None | GlaciationGrade::Light => return base, + GlaciationGrade::Moderate => 0.30, + GlaciationGrade::Heavy => 0.50, + GlaciationGrade::IceCap => 0.70, + }; + lerp_rgb( + [base[0] as f32, base[1] as f32, base[2] as f32], + [228.0, 240.0, 250.0], // glacial ice white-blue + t, + ) +} + +/// T-1127: dedicated glaciation panel — categorical dark→ice ramp. +fn glaciation_rgb(grade: GlaciationGrade) -> [u8; 3] { + match grade { + GlaciationGrade::None => [30, 30, 30], + GlaciationGrade::Light => [96, 120, 150], + GlaciationGrade::Moderate => [150, 180, 210], + GlaciationGrade::Heavy => [200, 222, 240], + GlaciationGrade::IceCap => [240, 248, 255], } }