From 958de5420e2fcdf0cf2457095e70ade3daaa7812 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Thu, 23 Jul 2026 14:14:23 +0200 Subject: [PATCH] =?UTF-8?q?style(simulation):=20gate=20bounce=20=E2=80=94?= =?UTF-8?q?=20box=20GenCompletion::BodyAnalyzed=20state;=20clippy/fmt=20sw?= =?UTF-8?q?eeps?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BodyWorldState grew past clippy's large-enum-variant threshold when it began retaining Layer1Output (T-1170 Ruling 4b) — boxed, with the two insert sites deref'd; manual_contains x2 (drainage tests), cloned_ref_to_slice_refs x3 (river_course tests), fmt wraps. gen_queue 18/18; clippy -D warnings clean; fmt --check clean. Tickets: T-1170 Co-Authored-By: Claude Fable 5 --- server/src/atlas/district_profile.rs | 122 ++++++++++++++++++++++++--- server/src/atlas/drainage.rs | 11 +-- server/src/atlas/gen_queue.rs | 7 +- server/src/atlas/layer_proxy.rs | 78 +++++++++++++---- server/src/atlas/plugin.rs | 2 +- server/src/atlas/river_course.rs | 71 ++++++++++++---- 6 files changed, 232 insertions(+), 59 deletions(-) diff --git a/server/src/atlas/district_profile.rs b/server/src/atlas/district_profile.rs index 67ccda802..6e5333ecc 100644 --- a/server/src/atlas/district_profile.rs +++ b/server/src/atlas/district_profile.rs @@ -2158,8 +2158,15 @@ mod tests { basin_dirs.insert(pos_east, BasinDirection::East); basin_dirs.insert(pos_south, BasinDirection::South); - let districts = - derive_all_districts(test_seed(), ¶ms, &ta, 8, "test_body", Some(&basin_dirs), None); + let districts = derive_all_districts( + test_seed(), + ¶ms, + &ta, + 8, + "test_body", + Some(&basin_dirs), + None, + ); assert_eq!(districts[&pos_east].basin_direction, BasinDirection::East); assert_eq!(districts[&pos_south].basin_direction, BasinDirection::South); @@ -2423,7 +2430,17 @@ mod tests { for i in 0..20 { let wx = (100 + i * 37) as f64 * dm; let wy = (100 + i * 53) as f64 * dm; - let uncut = derive_at_metres(test_seed(), "test_body", &p, &ta, wx, wy, &climate, 0.0, &[]); + let uncut = derive_at_metres( + test_seed(), + "test_body", + &p, + &ta, + wx, + wy, + &climate, + 0.0, + &[], + ); let cut = derive_at_metres( test_seed(), "test_body", @@ -2466,8 +2483,28 @@ mod tests { for i in 0..12 { let wx = (300 + i * 41) as f64 * dm * 0.1; let wy = (300 + i * 29) as f64 * dm * 0.1; - let a = derive_at_metres(test_seed(), "test_body", &p, &ta, wx, wy, &climate, 1_024.0, &[]); - let b = derive_at_metres(test_seed(), "test_body", &p, &ta, wx, wy, &climate, 1_024.0, &[]); + let a = derive_at_metres( + test_seed(), + "test_body", + &p, + &ta, + wx, + wy, + &climate, + 1_024.0, + &[], + ); + let b = derive_at_metres( + test_seed(), + "test_body", + &p, + &ta, + wx, + wy, + &climate, + 1_024.0, + &[], + ); assert_district_profiles_eq(&a, &b); } } @@ -2499,8 +2536,28 @@ mod tests { for i in 0..20 { let wx = (150 + i * 47) as f64 * dm; let wy = (150 + i * 31) as f64 * dm; - let a = derive_at_metres(test_seed(), "test_body", &p, &ta, wx, wy, &climate, 4_096.0, &[]); - let b = derive_at_metres(test_seed(), "test_body", &p, &ta, wx, wy, &climate, 4_096.0, &[]); + let a = derive_at_metres( + test_seed(), + "test_body", + &p, + &ta, + wx, + wy, + &climate, + 4_096.0, + &[], + ); + let b = derive_at_metres( + test_seed(), + "test_body", + &p, + &ta, + wx, + wy, + &climate, + 4_096.0, + &[], + ); assert_district_profiles_eq(&a, &b); } } @@ -2553,10 +2610,28 @@ mod tests { for i in 0..20 { let wx = (150 + i * 47) as f64 * dm; let wy = (150 + i * 31) as f64 * dm; - let district = - derive_at_metres(test_seed(), "test_body", &p, &ta, wx, wy, &climate, 4_096.0, &[]); - let quarter = - derive_at_metres(test_seed(), "test_body", &p, &ta, wx, wy, &climate, 1_024.0, &[]); + let district = derive_at_metres( + test_seed(), + "test_body", + &p, + &ta, + wx, + wy, + &climate, + 4_096.0, + &[], + ); + let quarter = derive_at_metres( + test_seed(), + "test_body", + &p, + &ta, + wx, + wy, + &climate, + 1_024.0, + &[], + ); if district.elev_q != quarter.elev_q || district.slope_q != quarter.slope_q || district.moisture_q != quarter.moisture_q @@ -2669,8 +2744,17 @@ mod tests { for dx in -2..2 { let wx = base_wx + dx as f64 * qm; let wy = base_wy + dy as f64 * qm; - let prof = - derive_at_metres(test_seed(), "test_body", &p, &ta, wx, wy, &climate, 1_024.0, &[]); + let prof = derive_at_metres( + test_seed(), + "test_body", + &p, + &ta, + wx, + wy, + &climate, + 1_024.0, + &[], + ); if prof.vegetation_class != VegetationClass::Marine { *tally.entry(prof.vegetation_class as u8).or_insert(0) += 1; } @@ -2783,7 +2867,17 @@ mod tests { let wx = 40.0 * dm; let wy = 20.0 * dm; let orbital = derive_orbital_at_metres(test_seed(), "test_body", &p, &ta, wx, wy, &climate); - let full = derive_at_metres(test_seed(), "test_body", &p, &ta, wx, wy, &climate, 0.0, &[]); + let full = derive_at_metres( + test_seed(), + "test_body", + &p, + &ta, + wx, + wy, + &climate, + 0.0, + &[], + ); // The invented scatter is a bounded perturbation on top of the raw // envelope (detail_scatter's amplitude is capped well under 100 elev_q diff --git a/server/src/atlas/drainage.rs b/server/src/atlas/drainage.rs index 5393578ca..7eb26bbf8 100644 --- a/server/src/atlas/drainage.rs +++ b/server/src/atlas/drainage.rs @@ -1129,8 +1129,7 @@ mod tests { let rn = &result.river_network; assert!(!rn.mouths.is_empty(), "GJ1c should have real sea mouths"); - let mouth_set: std::collections::BTreeSet<(u16, u16)> = - rn.mouths.iter().copied().collect(); + let mouth_set: std::collections::BTreeSet<(u16, u16)> = rn.mouths.iter().copied().collect(); for (i, &pos) in rn.river_cells.iter().enumerate() { let is_mouth_sentinel = rn.river_downstream[i] == RIVER_DOWNSTREAM_MOUTH; let is_in_mouths_list = mouth_set.contains(&pos); @@ -1195,9 +1194,7 @@ mod tests { empty river_cells silently no-ops every assertion below" ); assert!( - rn.river_downstream - .iter() - .any(|&v| v == RIVER_DOWNSTREAM_EDGE_DRAIN), + rn.river_downstream.contains(&RIVER_DOWNSTREAM_EDGE_DRAIN), "expected at least one EDGE_DRAIN-sentinel river cell (the flat-plateau case) \ on this fixture — downstream values were {:?}", rn.river_downstream @@ -1208,9 +1205,7 @@ mod tests { rn.mouths ); assert!( - !rn.river_downstream - .iter() - .any(|&v| v == RIVER_DOWNSTREAM_MOUTH), + !rn.river_downstream.contains(&RIVER_DOWNSTREAM_MOUTH), "an all-land world must never emit a MOUTH sentinel" ); } diff --git a/server/src/atlas/gen_queue.rs b/server/src/atlas/gen_queue.rs index cc2b9b423..53b23f3ad 100644 --- a/server/src/atlas/gen_queue.rs +++ b/server/src/atlas/gen_queue.rs @@ -272,7 +272,10 @@ pub enum GenCompletion { BodyAnalyzed { body_id: String, /// The computed world state, ready for `BodyWorldStateCache::insert`. - state: BodyWorldState, + /// Boxed: `BodyWorldState` grew past clippy's large-enum-variant + /// threshold when it began retaining `Layer1Output` (T-1170 Ruling 4b) + /// — the box keeps the enum small while the state moves by pointer. + state: Box, }, SkeletonGenerated { city_id: u64, @@ -726,7 +729,7 @@ fn run_work_item( ); GenCompletion::BodyAnalyzed { body_id: body_id.clone(), - state: snapshot.into_body_world_state(), + state: Box::new(snapshot.into_body_world_state()), } } Err(e) => GenCompletion::Failed { diff --git a/server/src/atlas/layer_proxy.rs b/server/src/atlas/layer_proxy.rs index 8377ccd9f..bbaa64f63 100644 --- a/server/src/atlas/layer_proxy.rs +++ b/server/src/atlas/layer_proxy.rs @@ -15,9 +15,7 @@ use bevy_ecs::prelude::Resource; use serde::{Deserialize, Serialize}; use crate::atlas::body_params_reader::BodyParamsReader; -use crate::atlas::body_world_state::{ - BodyWorldState, BodyWorldStateCache, RiverNetwork, SimTick, -}; +use crate::atlas::body_world_state::{BodyWorldState, BodyWorldStateCache, RiverNetwork, SimTick}; use crate::atlas::cascade::CascadeLayer; use crate::atlas::city_context_reader::CityContextReader; use crate::atlas::district_profile::{BodyParams, DistrictPos}; @@ -1206,7 +1204,8 @@ fn invent_courses_near_window( ta.h, params.body_radius_km, ); - let chord_m = ((anchor_a.0 - anchor_b.0).powi(2) + (anchor_a.1 - anchor_b.1).powi(2)).sqrt(); + let chord_m = + ((anchor_a.0 - anchor_b.0).powi(2) + (anchor_a.1 - anchor_b.1).powi(2)).sqrt(); let inflate_m = chord_m * COURSE_BBOX_INFLATION_FRACTION; let (bx0, bx1) = ( anchor_a.0.min(anchor_b.0) - inflate_m, @@ -1321,8 +1320,15 @@ fn crop_course_to_window( EdgeTerminusKind::EdgeDrain => CourseTerminus::EdgeDrain, EdgeTerminusKind::Interior => CourseTerminus::ContinuesBeyondWindow, EdgeTerminusKind::Mouth => { - match resolve_mouth_terminus(course, seed, body_id, params, ta, climate, min_wavelength_m) - { + match resolve_mouth_terminus( + course, + seed, + body_id, + params, + ta, + climate, + min_wavelength_m, + ) { Some(mouth_point) => { // Replace the cropped course's tail with the resolved // mouth point (bisected against the last land @@ -1521,8 +1527,15 @@ pub fn build_district_window_layer( // delta close to the Discipline item 2 ~5% budget. let step_m = granularity.spacing_m(); let window_rect = window_world_rect(center_world_m, half, side, step_m); - let invented_courses = - invent_courses_near_window(seed, params, ta, river_network, window_rect, granularity, min_wavelength_m); + let invented_courses = invent_courses_near_window( + seed, + params, + ta, + river_network, + window_rect, + granularity, + min_wavelength_m, + ); // One Rayon task per row: derive_window_cell(row, ..) for every col, then // scatter that row's results into the flat arrays. Row order in the @@ -1624,8 +1637,15 @@ fn build_district_window_layer_serial( let mut glaciation = vec![0u8; cells]; let step_m = granularity.spacing_m(); let window_rect = window_world_rect(center_world_m, half, side, step_m); - let invented_courses = - invent_courses_near_window(seed, params, ta, river_network, window_rect, granularity, min_wavelength_m); + let invented_courses = invent_courses_near_window( + seed, + params, + ta, + river_network, + window_rect, + granularity, + min_wavelength_m, + ); for row in 0..side { let row_cells: Vec = (0..side) .map(|col| { @@ -2783,13 +2803,37 @@ mod tests { // Two DIFFERENT window rects, both containing `mid` well inside // their bounds (so both windows' crop ranges include the shared // stretch, not just a single boundary point). - let window_a = (mid.0 - 20_000.0, mid.1 - 20_000.0, mid.0 + 5_000.0, mid.1 + 5_000.0); - let window_b = (mid.0 - 5_000.0, mid.1 - 5_000.0, mid.0 + 20_000.0, mid.1 + 20_000.0); + let window_a = ( + mid.0 - 20_000.0, + mid.1 - 20_000.0, + mid.0 + 5_000.0, + mid.1 + 5_000.0, + ); + let window_b = ( + mid.0 - 5_000.0, + mid.1 - 5_000.0, + mid.0 + 20_000.0, + mid.1 + 20_000.0, + ); - let invented_a = - invent_courses_near_window(seed, ¶ms, &ta, rn, window_a, WindowGranularity::District, 0.0); - let invented_b = - invent_courses_near_window(seed, ¶ms, &ta, rn, window_b, WindowGranularity::District, 0.0); + let invented_a = invent_courses_near_window( + seed, + ¶ms, + &ta, + rn, + window_a, + WindowGranularity::District, + 0.0, + ); + let invented_b = invent_courses_near_window( + seed, + ¶ms, + &ta, + rn, + window_b, + WindowGranularity::District, + 0.0, + ); let course_a = invented_a .iter() @@ -5300,7 +5344,7 @@ mod tests { // Serve the completed state back through the proxy: the cache-hit // branch must build and include the region grid. - cache.insert(body_state); + cache.insert(*body_state); let ready = handle_atlas_request( &req("GJ1c"), &mut cache, diff --git a/server/src/atlas/plugin.rs b/server/src/atlas/plugin.rs index 60a285a99..a16412904 100644 --- a/server/src/atlas/plugin.rs +++ b/server/src/atlas/plugin.rs @@ -359,7 +359,7 @@ fn drain_generation_completions( ); } } - cache.insert(state); + cache.insert(*state); } GenCompletion::Failed { item, reason } => { tracing::warn!(?item, %reason, "background generation work item failed"); diff --git a/server/src/atlas/river_course.rs b/server/src/atlas/river_course.rs index a56305d21..a2336a9e4 100644 --- a/server/src/atlas/river_course.rs +++ b/server/src/atlas/river_course.rs @@ -397,10 +397,7 @@ fn stage_a_control_path( let mut prev_offset = 0.0f64; for i in 1..STAGE_A_STATIONS - 1 { let t = i as f64 / (STAGE_A_STATIONS - 1) as f64; - let base = ( - anchor_a.0 + dx * t, - anchor_a.1 + dy * t, - ); + let base = (anchor_a.0 + dx * t, anchor_a.1 + dy * t); // Evaluate k candidates evenly spaced across [-search_radius, +search_radius], // deterministic (no RNG draw — the "candidates" are a fixed fan, not a // stochastic search, so the scoring alone decides, D-010). @@ -535,7 +532,12 @@ fn warp_fbm(sx: u64, sy: u64, arc_m: f64, chord_m: f64, min_wavelength_m: f64) - // stations key on GLOBAL arc-length, never window-relative or 2D // world position, so overlapping windows agree exactly on the shared // stretch regardless of where the window happens to be centred). - let n = value_noise(sx.wrapping_add((i as u64).wrapping_mul(0x1000)), arc_m, 0.0, wl); + let n = value_noise( + sx.wrapping_add((i as u64).wrapping_mul(0x1000)), + arc_m, + 0.0, + wl, + ); sum += n * amp; norm += amp; amp *= 0.5; @@ -569,9 +571,15 @@ fn sample_polyline_at_arc_length(points: &[CoursePoint], arc_m: f64) -> (CourseP } else { remaining / seg_len }; - let pos = (w[0].0 + (w[1].0 - w[0].0) * t, w[0].1 + (w[1].1 - w[0].1) * t); + let pos = ( + w[0].0 + (w[1].0 - w[0].0) * t, + w[0].1 + (w[1].1 - w[0].1) * t, + ); let tangent_len = seg_len.max(1e-9); - let tangent = ((w[1].0 - w[0].0) / tangent_len, (w[1].1 - w[0].1) / tangent_len); + let tangent = ( + (w[1].0 - w[0].0) / tangent_len, + (w[1].1 - w[0].1) / tangent_len, + ); return (pos, tangent); } remaining -= seg_len; @@ -843,7 +851,10 @@ mod tests { let a = invent_course(seed, edge, &ta, ¶ms, 2_048.0, 0.0); let b = invent_course(seed, edge, &ta, ¶ms, 2_048.0, 0.0); - assert_eq!(a.points, b.points, "course invention must be deterministic (D-010/D-227)"); + assert_eq!( + a.points, b.points, + "course invention must be deterministic (D-010/D-227)" + ); } #[test] @@ -881,7 +892,10 @@ mod tests { let seed = SeedChain::root(7).derive(SeedDomain::Body, 1); let station_spacing_m = 2_048.0; - for edge in edges.iter().filter(|e| e.terminus == EdgeTerminusKind::Interior) { + for edge in edges + .iter() + .filter(|e| e.terminus == EdgeTerminusKind::Interior) + { let course = invent_course(seed, edge, &ta, ¶ms, station_spacing_m, 0.0); let anchor_a = cell_world_m(edge.upstream, &ta, ¶ms); let anchor_b = cell_world_m(edge.downstream, &ta, ¶ms); @@ -933,7 +947,9 @@ mod tests { // fields' underlying warp_fbm-style noise streams (same seed, same // world positions) and confirm the Pearson correlation across many // samples is near zero, not just "not identical." - use crate::atlas::coast_invention::{body_coast_envelope, coast_character_at, coast_warp_px}; + use crate::atlas::coast_invention::{ + body_coast_envelope, coast_character_at, coast_warp_px, + }; use crate::atlas::district_profile::{GlaciationGrade, TectonicClass}; let params = test_params(); @@ -1013,7 +1029,10 @@ mod tests { let seed = SeedChain::root(3).derive(SeedDomain::Body, 1); let a = invent_course(seed, interior[0], &ta, ¶ms, 2_048.0, 0.0); let b = invent_course(seed, interior[1], &ta, ¶ms, 2_048.0, 0.0); - assert_ne!(a.points, b.points, "distinct edges must invent distinct courses"); + assert_ne!( + a.points, b.points, + "distinct edges must invent distinct courses" + ); } #[test] @@ -1071,11 +1090,20 @@ mod tests { bbox, }; // On the course itself. - assert!(near_perennial_water((50.0, 0.0), &[course.clone()])); + assert!(near_perennial_water( + (50.0, 0.0), + std::slice::from_ref(&course) + )); // Within the 3 m trunk band. - assert!(near_perennial_water((50.0, 2.9), &[course.clone()])); + assert!(near_perennial_water( + (50.0, 2.9), + std::slice::from_ref(&course) + )); // Just outside the band. - assert!(!near_perennial_water((50.0, 3.1), &[course.clone()])); + assert!(!near_perennial_water( + (50.0, 3.1), + std::slice::from_ref(&course) + )); // Far away entirely. assert!(!near_perennial_water((50.0, 500.0), &[course])); } @@ -1095,8 +1123,14 @@ mod tests { }; // 2.0 m: within tributary band (2.0), outside stream band (1.0). let probe = (50.0, 1.5); - assert!(near_perennial_water(probe, &[base(1)]), "tributary band should cover 1.5 m"); - assert!(!near_perennial_water(probe, &[base(0)]), "stream band should NOT cover 1.5 m"); + assert!( + near_perennial_water(probe, &[base(1)]), + "tributary band should cover 1.5 m" + ); + assert!( + !near_perennial_water(probe, &[base(0)]), + "stream band should NOT cover 1.5 m" + ); } #[test] @@ -1115,7 +1149,10 @@ mod tests { bbox, }; let district_spacing_m = 2_048.0; - assert!(!near_perennial_water((5_000.0, district_spacing_m), &[course])); + assert!(!near_perennial_water( + (5_000.0, district_spacing_m), + &[course] + )); } #[test]