From 3d3c37e69c69602df84b8c52202c0ccd6a5bb991 Mon Sep 17 00:00:00 2001 From: Natalie Date: Mon, 8 Jun 2026 01:34:15 -0700 Subject: [PATCH] =?UTF-8?q?fix(@projects/@magic-civilization):=20?= =?UTF-8?q?=F0=9F=90=9B=20revert=20dominion=5Fbench=20ai=20integration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- .project/designs/p2-80-bullet2-port-sizing.md | 26 +++++++++++++++++++ .../crates/mc-player-api/src/dispatch.rs | 7 +---- src/simulator/crates/mc-sim/Cargo.toml | 1 - .../crates/mc-sim/src/bin/dominion_bench.rs | 23 +--------------- 4 files changed, 28 insertions(+), 29 deletions(-) diff --git a/.project/designs/p2-80-bullet2-port-sizing.md b/.project/designs/p2-80-bullet2-port-sizing.md index f9c5593f..9e660b88 100644 --- a/.project/designs/p2-80-bullet2-port-sizing.md +++ b/.project/designs/p2-80-bullet2-port-sizing.md @@ -159,3 +159,29 @@ not `mc-turn`'s inline stub. **retiring `mc-turn`'s inline `nearest_lair` movement** (dead-stub removal, no-debt). Then expansion-pacing reconciliation if 47 cities still reads high vs the GDScript autoplay on a matched map. + +--- + +## Step 1 follow-up (2026-06-08) — `dominion_bench` is the wrong probe; reverted + +Attempted to make `dominion_bench` drive the real AI (`drive_ai_slot` → +`run_ai_turn`) so the multi-clan bench would show combat. **It did not work and +was reverted** (commits exposing `drive_ai_slot`, adding the `mc-player-api` +dep, and the bench drive-loop are undone — clean, no dead code left). + +**Finding:** with `drive_ai_slot` wired in, the bench result was **byte-identical** +(214 cities, turn 51, 0 PvP) — even after deriving real per-personality +`ScoringWeights::from_personality`. `drive_ai_slot` has **zero net effect** on +`dominion_bench`'s hand-built `GameState`: its `run_ai_turn` actions don't apply +(the minimal bench state lacks the structure the real AI/action-application +expects). Making `dominion_bench` representative would require rebuilding its +state to full-harness fidelity — surgery, not a wire-up. + +**Resolution — no new probe needed:** `full_game_transcript` / +`long_game_transcript` (mc-player-api tests) **already are** the working +real-AI multi-clan bench — they build a realistic `GameState`, drive +`run_ai_turn` via the production `apply_end_turn` → `drive_ai_slot` path, and +produce live-grade games (**2531 kills**, conquest, 47-city winner over 250 +turns). Use those as the convergence harness for the cutover; leave +`dominion_bench` as the fast inline-AI economic/expansion bench it was designed +to be. The real-AI viability question (step 1) is **already answered** there. diff --git a/src/simulator/crates/mc-player-api/src/dispatch.rs b/src/simulator/crates/mc-player-api/src/dispatch.rs index e621da92..99b72de6 100644 --- a/src/simulator/crates/mc-player-api/src/dispatch.rs +++ b/src/simulator/crates/mc-player-api/src/dispatch.rs @@ -976,12 +976,7 @@ fn translate_processor_events(events: &[mc_replay::TurnEvent]) -> Vec { /// counted but DO NOT abort the rest of the turn — a single /// unknown unit or illegal move must not collapse the entire AI /// side (matches the GDScript dispatch behaviour). -/// Drive one AI slot for a turn: project vision, run the slot's controller -/// (`run_ai_turn` by default), and apply the chosen actions. Public so headless -/// multi-clan benches (`dominion_bench`) can drive the *real* AI through the -/// same path the interactive game uses (`apply_end_turn`), instead of relying -/// on `mc-turn`'s inline fallback movement. Returns the action count. -pub fn drive_ai_slot(state: &mut GameState, ai_slot: u8) -> u32 { +fn drive_ai_slot(state: &mut GameState, ai_slot: u8) -> u32 { let pi: usize = ai_slot as usize; if pi >= state.players.len() { return 0; diff --git a/src/simulator/crates/mc-sim/Cargo.toml b/src/simulator/crates/mc-sim/Cargo.toml index 3524c67f..21f4d750 100644 --- a/src/simulator/crates/mc-sim/Cargo.toml +++ b/src/simulator/crates/mc-sim/Cargo.toml @@ -23,7 +23,6 @@ mc-city = { path = "../mc-city" } mc-culture = { path = "../mc-culture" } mc-economy = { path = "../mc-economy" } mc-ai = { path = "../mc-ai" } -mc-player-api = { path = "../mc-player-api" } serde.workspace = true serde_json.workspace = true rayon = "1" diff --git a/src/simulator/crates/mc-sim/src/bin/dominion_bench.rs b/src/simulator/crates/mc-sim/src/bin/dominion_bench.rs index 14a33063..ef38321e 100644 --- a/src/simulator/crates/mc-sim/src/bin/dominion_bench.rs +++ b/src/simulator/crates/mc-sim/src/bin/dominion_bench.rs @@ -355,20 +355,7 @@ fn run_scenario_with_profiles(num_players: usize, all_profiles: &[ProfileJson]) ..Default::default() }], unit_upkeep: vec![], strategic_axes: make_axes(profile), - // Real per-personality scoring weights (military/expansion/etc.), - // the same source the live game uses (`ScoringWeights::from_personality`). - // Without these the AI scores every action ~0 and `drive_ai_slot` - // produces no moves — the inert `default()` was why the bench showed - // zero PvP. Falls back to default if the personality file is absent. - scoring_weights: ScoringWeights::from_personality( - &profile.id, - &Path::new(env!("CARGO_MANIFEST_DIR")) - .ancestors() - .nth(2) - .expect("workspace root") - .join("public/resources/ai/personalities"), - ) - .unwrap_or_default(), + scoring_weights: ScoringWeights::default(), expansion_points: 0, city_buildings: vec![vec![]], city_improvements: Default::default(), @@ -426,14 +413,6 @@ fn run_scenario_with_profiles(num_players: usize, all_profiles: &[ProfileJson]) let mut victory_turn: Option = None; for turn_num in 1..=TOTAL_TURNS { - // Drive every slot's REAL AI (`run_ai_turn` via the controller registry) - // before the turn resolves — the same `drive_ai_slot` the interactive - // game runs inside `apply_end_turn`. Without this the bench relied on - // `mc-turn`'s inline `nearest_lair` fallback (PvE only → zero PvP). All - // slots are AI here (no human), so we drive all of them. - for slot in 0..state.players.len() as u8 { - mc_player_api::dispatch::drive_ai_slot(&mut state, slot); - } let result = processor.step(&mut state); // Track unit production per player.