From 6bf021d0b39cd4b0f55e72fc11f6147cc5e79eae Mon Sep 17 00:00:00 2001 From: Natalie Date: Fri, 8 May 2026 06:28:35 -0700 Subject: [PATCH] =?UTF-8?q?fix(@projects/@magic-civilization):=20?= =?UTF-8?q?=F0=9F=90=9B=20adjust=20player=20count=20to=205=20players?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- .../crates/mc-ai/src/abstract_state.rs | 2 +- .../crates/mc-ai/src/gpu/cpu_reference.rs | 6 ++--- src/simulator/crates/mc-ai/src/gpu/inner.rs | 2 +- src/simulator/crates/mc-ai/src/rollout.rs | 22 +++++++++---------- src/simulator/crates/mc-city/src/city.rs | 2 +- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/simulator/crates/mc-ai/src/abstract_state.rs b/src/simulator/crates/mc-ai/src/abstract_state.rs index 43155a05..4cce5633 100644 --- a/src/simulator/crates/mc-ai/src/abstract_state.rs +++ b/src/simulator/crates/mc-ai/src/abstract_state.rs @@ -5,7 +5,7 @@ //! (`rollout.wgsl`, Task C3) and the CPU fallback rollout path (Task C4). //! //! # Invariants -//! - Exactly 256 bytes (4 players × 64 bytes). +//! - Exactly 360 bytes (5 players × 72 bytes). //! - Alignment ≤ 16 bytes so it maps cleanly to a WGSL uniform / storage binding. //! - Deterministic field order — the WGSL struct layout mirrors this declaration //! one-to-one. Changing either side requires updating the other in lockstep. diff --git a/src/simulator/crates/mc-ai/src/gpu/cpu_reference.rs b/src/simulator/crates/mc-ai/src/gpu/cpu_reference.rs index 108740b7..210f1694 100644 --- a/src/simulator/crates/mc-ai/src/gpu/cpu_reference.rs +++ b/src/simulator/crates/mc-ai/src/gpu/cpu_reference.rs @@ -130,8 +130,8 @@ mod tests { pod.players[0].gold = 100; pod.players[0].pop_total = 5; pod.players[0].city_count = 1; - pod.players[0].force_rel = [0, 20, 0, 0]; - pod.players[0].relations = [0, -1, 0, 0]; + pod.players[0].force_rel = [0, 20, 0, 0, 0]; + pod.players[0].relations = [0, -1, 0, 0, 0]; pod.players[0].rng_state = 0xAAAA_BBBB_CCCC_DDDD; pod.players[0].turn = 1; pod.players[1].gold = 50; @@ -144,7 +144,7 @@ mod tests { fn iron_vs_bh_priors() -> [PersonalityPriors; MAX_PLAYERS] { let iron = ironhold_priors(); let bh = blackhammer_priors(); - [iron, bh, iron, bh] + [iron, bh, iron, bh, iron] } #[test] diff --git a/src/simulator/crates/mc-ai/src/gpu/inner.rs b/src/simulator/crates/mc-ai/src/gpu/inner.rs index ecfd871c..3ed5b3ab 100644 --- a/src/simulator/crates/mc-ai/src/gpu/inner.rs +++ b/src/simulator/crates/mc-ai/src/gpu/inner.rs @@ -98,7 +98,7 @@ impl From for GpuPlayerPriors { } } -/// Mirrors the `BatchPriors` WGSL struct — 4 `PlayerPriors`, total 96 bytes. +/// Mirrors the `BatchPriors` WGSL struct — 5 `PlayerPriors`, total 120 bytes. /// Uploaded once per batch entry, indexed by entry ID. #[repr(C)] #[derive(Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)] diff --git a/src/simulator/crates/mc-ai/src/rollout.rs b/src/simulator/crates/mc-ai/src/rollout.rs index a829e796..ca56a9cb 100644 --- a/src/simulator/crates/mc-ai/src/rollout.rs +++ b/src/simulator/crates/mc-ai/src/rollout.rs @@ -265,7 +265,7 @@ impl GameRolloutState { } /// Index into `force_rel` with the largest value. Ties broken by lowest index. -fn highest_force_index(force_rel: &[u16; 4]) -> usize { +fn highest_force_index(force_rel: &[u16; 5]) -> usize { let mut best = 0_usize; let mut best_v = force_rel[0]; for (i, &v) in force_rel.iter().enumerate().skip(1) { @@ -386,8 +386,8 @@ mod tests { pod.players[0].gold = 100; pod.players[0].pop_total = 5; pod.players[0].city_count = 1; - pod.players[0].force_rel = [0, 20, 0, 0]; // at odds with slot 1 - pod.players[0].relations = [0, -1, 0, 0]; + pod.players[0].force_rel = [0, 20, 0, 0, 0]; // at odds with slot 1 + pod.players[0].relations = [0, -1, 0, 0, 0]; pod.players[0].rng_state = 0xAAAA_BBBB_CCCC_DDDD; pod.players[0].turn = 1; // Opponent slot 1 also seeded lightly. @@ -435,9 +435,9 @@ mod tests { #[test] fn active_actions_gates_make_peace_on_war() { let mut s = make_state(true); - s.abstract_state.players[0].relations = [0, 0, 0, 0]; // all at peace + s.abstract_state.players[0].relations = [0, 0, 0, 0, 0]; // all at peace assert!(!s.active_actions().contains(&ActionKind::MakePeace)); - s.abstract_state.players[0].relations = [0, -1, 0, 0]; // at war with slot 1 + s.abstract_state.players[0].relations = [0, -1, 0, 0, 0]; // at war with slot 1 assert!(s.active_actions().contains(&ActionKind::MakePeace)); } @@ -500,8 +500,8 @@ mod tests { // force, existing war (relations[1] = -1). let mut s = make_state(true); s.abstract_state.players[0].gold = 500; // enables Settle + Trade - s.abstract_state.players[0].force_rel = [0, 20, 10, 0]; // enables Attack + ContinueWar - s.abstract_state.players[0].relations = [0, -1, 0, 0]; // enables MakePeace + s.abstract_state.players[0].force_rel = [0, 20, 10, 0, 0]; // enables Attack + ContinueWar + s.abstract_state.players[0].relations = [0, -1, 0, 0, 0]; // enables MakePeace let acts = s.active_actions(); @@ -556,8 +556,8 @@ mod tests { // ActionKind::ALL order even when some kinds are filtered out. let mut s = make_state(true); s.abstract_state.players[0].gold = 10; // Settle gated out (< 40); Trade OK (>= 0) - s.abstract_state.players[0].force_rel = [0, 0, 0, 0]; // Attack, ContinueWar gated out - s.abstract_state.players[0].relations = [0, 0, 0, 0]; // MakePeace gated out + s.abstract_state.players[0].force_rel = [0, 0, 0, 0, 0]; // Attack, ContinueWar gated out + s.abstract_state.players[0].relations = [0, 0, 0, 0, 0]; // MakePeace gated out let acts = s.active_actions(); assert_eq!( @@ -627,9 +627,9 @@ mod tests { s.apply_active(ActionKind::Idle); assert_eq!(s.active_player, 3); s.apply_active(ActionKind::Idle); - assert_eq!(s.active_player, 0); // wraps past MAX_PLAYERS=4 + assert_eq!(s.active_player, 4); s.apply_active(ActionKind::Idle); - assert_eq!(s.active_player, 1); + assert_eq!(s.active_player, 0); // wraps past MAX_PLAYERS=5 } #[test] diff --git a/src/simulator/crates/mc-city/src/city.rs b/src/simulator/crates/mc-city/src/city.rs index 979f7cb2..9c119ce2 100644 --- a/src/simulator/crates/mc-city/src/city.rs +++ b/src/simulator/crates/mc-city/src/city.rs @@ -90,7 +90,7 @@ impl CityFocus { /// Per-tile yield data for citizen assignment. The full tile-yield system /// lives in mc-economy; this is the projection that cities need for citizen /// allocation. Populated by the caller (GDScript/GDExtension reads tiles). -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct TileYield { pub coord: (i32, i32), pub food: f64,