feat(simulation): dispatch RegionProfile layer in production (T-1032)
The D-239 carrier layer (T-1023/1024/1026) only ran in tests because every production AnalyzeBody enqueue passed body_params: None. Wire the real path: - New BodyParamsReader (server/src/atlas/body_params_reader.rs): read-only systems.db reader, joins bodies -> star_systems (LEFT JOIN) for the climate/ tectonic inputs. SQL verified against systems-schema.sql. All fields Option, NULLs handled; tectonic_activity absent from schema -> None (derives from planet_class). 5 unit tests. - layer_proxy.rs: on cache miss, read the body's params and pass Some(Box::new(..)). On read error, warn + fall back to None (cascade stops at Settlement, no panic) — graceful degradation. - plugin.rs / main.rs: register BodyParamsReaderResource (CityContextReader pattern) and thread it through serve_atlas_requests. BodyWorldState.regions now populates for real bodies in the D-206 background pass. End-to-end tests cover wired (regions populated) + unwired (empty) paths. cargo test 1504 pass, clippy -D warnings clean, fmt clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,7 @@ use bevy_ecs::prelude::*;
|
||||
use bevy_ecs::schedule::IntoScheduleConfigs;
|
||||
|
||||
use crate::atlas::attractor_matching::CityPlacement;
|
||||
use crate::atlas::body_params_reader::BodyParamsReaderResource;
|
||||
use crate::atlas::body_world_state::{BodyWorldStateCache, CACHE_CAPACITY};
|
||||
use crate::atlas::city_context_reader::{
|
||||
context_from_read_set, CityContextReaderResource, CityEconomicReadSet,
|
||||
@@ -50,6 +51,7 @@ fn serve_atlas_requests(
|
||||
queue: Res<GenerationQueue>,
|
||||
resolver: Option<Res<BodySourceResolverResource>>,
|
||||
city_reader: Option<Res<CityContextReaderResource>>,
|
||||
body_params_reader: Option<Res<BodyParamsReaderResource>>,
|
||||
rng: Option<Res<SimRng>>,
|
||||
time: Option<Res<SimulationTime>>,
|
||||
) {
|
||||
@@ -59,12 +61,20 @@ fn serve_atlas_requests(
|
||||
let world_seed = rng.as_ref().map(|r| r.seed()).unwrap_or(0);
|
||||
let tick = time.as_ref().map(|t| t.tick).unwrap_or(0);
|
||||
let reader = city_reader.as_ref().map(|r| &r.0);
|
||||
let params_reader = body_params_reader.as_ref().map(|r| &r.0);
|
||||
let pending: Vec<_> = requests.0.drain(..).collect();
|
||||
for req in pending {
|
||||
let resp = match resolver.as_ref() {
|
||||
Some(r) => {
|
||||
handle_atlas_request(&req, &mut cache, &queue, &r.0, reader, world_seed, tick)
|
||||
}
|
||||
Some(r) => handle_atlas_request(
|
||||
&req,
|
||||
&mut cache,
|
||||
&queue,
|
||||
&r.0,
|
||||
reader,
|
||||
params_reader,
|
||||
world_seed,
|
||||
tick,
|
||||
),
|
||||
None => AtlasLayerResponse {
|
||||
body_id: req.body_id.clone(),
|
||||
status: AtlasLayerStatus::Error("no body source resolver".to_string()),
|
||||
|
||||
Reference in New Issue
Block a user