diff --git a/src/simulator/crates/mc-player-api/src/projection.rs b/src/simulator/crates/mc-player-api/src/projection.rs index 6fe1ea55..2024cf87 100644 --- a/src/simulator/crates/mc-player-api/src/projection.rs +++ b/src/simulator/crates/mc-player-api/src/projection.rs @@ -162,6 +162,10 @@ fn project_resources(player: &mc_state::game_state::PlayerState) -> ResourceView // p3-26 B1: surface the happiness pool now computed by the turn's // happiness_phase (was hardcoded 0 before the phase existed). happiness_pool: player.happiness, + // Rail-1: surface the Golden Age state the HUD badge reads + // (top_bar.gd:162/169) so it comes from view_json, not the entity. + golden_age_active: player.golden_age_active, + golden_age_turns: player.golden_age_turns.max(0) as u32, stockpile, } } diff --git a/src/simulator/crates/mc-player-api/src/view.rs b/src/simulator/crates/mc-player-api/src/view.rs index f28fc97d..90629cf0 100644 --- a/src/simulator/crates/mc-player-api/src/view.rs +++ b/src/simulator/crates/mc-player-api/src/view.rs @@ -36,10 +36,21 @@ pub struct ResourceView { pub culture_per_turn: i32, /// Global happiness pool (positive = surplus). pub happiness_pool: i32, + /// Whether the empire is in a Golden Age (drives the HUD badge). + #[serde(default, skip_serializing_if = "core::ops::Not::not")] + pub golden_age_active: bool, + /// Golden-age turns remaining (`0` when not active). + #[serde(default, skip_serializing_if = "crate::view::is_zero_u32")] + pub golden_age_turns: u32, /// Strategic-resource stockpile (resource_id → amount). pub stockpile: std::collections::BTreeMap, } +/// serde helper: skip `u32` fields that are zero (wire economy). +pub(crate) fn is_zero_u32(v: &u32) -> bool { + *v == 0 +} + /// Research / tech tab state. #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] pub struct ResearchView { @@ -477,6 +488,20 @@ mod tests { assert!(!json.contains("posture"), "resting posture must be omitted: {json}"); } + #[test] + fn resource_view_golden_age_round_trips_and_omits_when_inactive() { + let mut r = ResourceView::default(); + assert!(!serde_json::to_string(&r).unwrap().contains("golden_age"), + "inactive golden age omitted from wire"); + r.golden_age_active = true; + r.golden_age_turns = 8; + let json = serde_json::to_string(&r).unwrap(); + assert!(json.contains("\"golden_age_active\":true"), "json={json}"); + assert!(json.contains("\"golden_age_turns\":8"), "json={json}"); + let back: ResourceView = serde_json::from_str(&json).unwrap(); + assert_eq!(r, back); + } + #[test] fn unit_posture_serialized_only_when_active() { let mut u = UnitView {