From 763da9bbf5e8e71a9d9c46df5ff373db2a4c574a Mon Sep 17 00:00:00 2001 From: chazmm Date: Tue, 8 Sep 2026 17:48:10 +0100 Subject: [PATCH] Initialize original scoring HUD after presentation camera exists --- crates/skate-game/src/graphics_menu.rs | 6 +++++- crates/skate-game/src/scoring_hud.rs | 15 ++++++++++----- docs/native-scoring-hud.md | 9 ++++++++- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/crates/skate-game/src/graphics_menu.rs b/crates/skate-game/src/graphics_menu.rs index ab9356cc..fa7b05e4 100644 --- a/crates/skate-game/src/graphics_menu.rs +++ b/crates/skate-game/src/graphics_menu.rs @@ -110,11 +110,15 @@ struct StatusLabel; #[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)] pub(crate) struct MenuInput; +/// The presentation camera must exist before overlays select their UI target. +#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)] +pub(crate) struct PresentationSetup; + pub(crate) struct GraphicsMenuPlugin; impl Plugin for GraphicsMenuPlugin { fn build(&self, app: &mut App) { app.insert_resource(FramePacer(Instant::now())) - .add_systems(PostStartup, setup) + .add_systems(PostStartup, setup.in_set(PresentationSetup)) .add_systems(PreUpdate, interact.in_set(MenuInput).after(bevy::input::InputSystems)) .add_systems(Update, (apply, labels).chain()) .add_systems(Last, pace); diff --git a/crates/skate-game/src/scoring_hud.rs b/crates/skate-game/src/scoring_hud.rs index 5d009094..53ef100f 100644 --- a/crates/skate-game/src/scoring_hud.rs +++ b/crates/skate-game/src/scoring_hud.rs @@ -53,7 +53,10 @@ impl Plugin for ScoringHudPlugin { fn build(&self, app: &mut App) { embedded_asset!(app, "hud_render.wgsl"); app.add_plugins(Material2dPlugin::::default()) - .add_systems(PostStartup, setup) + .add_systems( + PostStartup, + setup.after(crate::graphics_menu::PresentationSetup), + ) .add_systems( FixedUpdate, advance @@ -73,6 +76,12 @@ fn setup( cameras: Query>, mut images: ResMut>, ) { + // The startup dependency also applies the presentation system's deferred + // camera spawn before this query. Without it, setup silently lost the HUD. + let Ok(output) = cameras.single() else { + error!("Original HUD requires the presentation camera"); + return; + }; let root = std::env::var_os("SKATE_SCORING_HUD_ROOT") .map(PathBuf::from) .unwrap_or_else(|| config.asset_root.join("private/hud")); @@ -143,10 +152,6 @@ fn setup( RenderLayers::layer(31), Msaa::Off, )); - let Ok(output) = cameras.single() else { - error!("Original HUD requires the presentation camera"); - return; - }; commands.spawn(( ImageNode::new(target), UiTargetCamera(output), diff --git a/docs/native-scoring-hud.md b/docs/native-scoring-hud.md index 33e76d70..724a7aa3 100644 --- a/docs/native-scoring-hud.md +++ b/docs/native-scoring-hud.md @@ -98,7 +98,14 @@ The copied build and launcher are in ignored `logs/scoring/build`. The launcher uses this worktree's HUD cache and the existing owned asset installation and starts paused. It checks required paths before running and retains failures on screen. The executable SHA256 is -`775264c02f456665052355d466b99cb2e3ead1e359af3123c9a53afd68e1e182`. +`deb1045925e1dd0e7143825d0320172eb2c26cf77e1c0f336d3475887557435d`. + +The missing-HUD startup defect is fixed: HUD setup now depends on presentation +setup, so Bevy applies the deferred camera spawn before the HUD queries it. +Previously the two PostStartup systems were unordered and a missing camera +caused HUD initialization to return permanently. The rebuilt launcher also +saves runtime output to `logs/scoring/build/scoring-test.log`. This fix is +release-compiled; interactive rendering has not been launched for verification. ## Native parity gaps