refactor(p2-65): 🏗️ Phase 4 C2 — delete mc-turn GameState shim + re-export (bullet 6 → 0)

Complete the consumer migration off mc-turn's state-shape pass-through:
- mc-turn/src/lib.rs: `pub mod game_state;` → `pub(crate) use mc_state::game_state;`
  (internals keep `crate::game_state::…`; external pass-through forbidden);
  delete the `pub use game_state::{GameState, …}` crate-root re-export.
- Delete the mc-turn/src/game_state.rs re-export shim file.
- Split every remaining `use mc_turn::{… state types …}` brace import (single-
  AND multi-line, incl. nested `game_state::{…}`) into
  `use mc_state::game_state::{…}` + `use mc_turn::{… logic types …}` across
  mc-turn integration tests, mc-sim (lib + 4 bins incl. solo_dominion),
  mc-player-api tests, and tests/integration. Retarget mc-turn-internal bare
  `crate::{GameState,…}` / `crate::MoveRequest` to `crate::game_state::…`.
- Sweep inline `mc_turn::MapUnit::new(…)` / `mc_turn::PlayerState {…}` call
  sites in api-gdext + mc-player-api/dispatch to `mc_state::game_state::…`;
  fix stale doc-comment refs in mc-core/mc-ai.
- Add `mc-state` path dep to tests/integration.

Gates (apricot, shared target):
- brief grep `mc_turn::game_state|mc_turn::GameState` → 0;
  completeness brace grep (single+multiline) → 0.
- cargo test --workspace --no-run exit 0.
- serde_roundtrip 6/6; full_turn_golden 3/3 (save-format byte-identical).
- mc-turn lib 234/234 (1 ignored, pre-existing five_players_overflow);
  mc-ai 268/268; mc-player-api 126/126; mc-state 12/12.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
autocommit 2026-06-04 19:47:55 -07:00
parent cea53e1ee4
commit efbfa6ae3f
35 changed files with 73 additions and 88 deletions

View file

@ -1813,6 +1813,7 @@ dependencies = [
"mc-core", "mc-core",
"mc-culture", "mc-culture",
"mc-happiness", "mc-happiness",
"mc-state",
"mc-turn", "mc-turn",
] ]

View file

@ -3592,11 +3592,11 @@ impl GdGameState {
// (hp/attack/defense — these are warrior-flavored fixtures, not // (hp/attack/defense — these are warrior-flavored fixtures, not
// catalog-driven yet) are applied after construction; promoting // catalog-driven yet) are applied after construction; promoting
// those to the catalog is tracked separately. // those to the catalog is tracked separately.
let mut units: Vec<mc_turn::MapUnit> = (0..3) let mut units: Vec<mc_state::game_state::MapUnit> = (0..3)
.map(|i| { .map(|i| {
let unit_u32 = self.inner.next_unit_id; let unit_u32 = self.inner.next_unit_id;
self.inner.next_unit_id = self.inner.next_unit_id.saturating_add(1); self.inner.next_unit_id = self.inner.next_unit_id.saturating_add(1);
let mut u = mc_turn::MapUnit::new( let mut u = mc_state::game_state::MapUnit::new(
"dwarf_warrior", "dwarf_warrior",
city_col + i, city_col + i,
city_row, city_row,
@ -3620,7 +3620,7 @@ impl GdGameState {
// default-constructed and stuck at `base_moves = 0`). // default-constructed and stuck at `base_moves = 0`).
let founder_id = self.inner.next_unit_id; let founder_id = self.inner.next_unit_id;
self.inner.next_unit_id = self.inner.next_unit_id.saturating_add(1); self.inner.next_unit_id = self.inner.next_unit_id.saturating_add(1);
let mut founder = mc_turn::MapUnit::new( let mut founder = mc_state::game_state::MapUnit::new(
"dwarf_founder", "dwarf_founder",
city_col, city_col,
city_row, city_row,
@ -3633,7 +3633,7 @@ impl GdGameState {
founder.auto_join = false; founder.auto_join = false;
units.push(founder); units.push(founder);
self.inner.players.push(mc_turn::PlayerState { self.inner.players.push(mc_state::game_state::PlayerState {
player_index: pi, player_index: pi,
gold: 60, gold: 60,
cities: vec![mc_city::CityState::starter()], cities: vec![mc_city::CityState::starter()],
@ -4096,7 +4096,7 @@ impl GdGameState {
} }
} }
self.inner.players.push(mc_turn::PlayerState { self.inner.players.push(mc_state::game_state::PlayerState {
player_index: pi, player_index: pi,
gold: 0, gold: 0,
cities: Vec::new(), cities: Vec::new(),
@ -4170,7 +4170,7 @@ impl GdGameState {
); );
continue; continue;
}; };
ingested.push(mc_turn::MapUnit { ingested.push(mc_state::game_state::MapUnit {
col: col as i32, col: col as i32,
row: row as i32, row: row as i32,
hp: dict.get("hp").and_then(|v| v.try_to::<i64>().ok()).unwrap_or(60) as i32, hp: dict.get("hp").and_then(|v| v.try_to::<i64>().ok()).unwrap_or(60) as i32,
@ -4417,7 +4417,7 @@ impl GdGameState {
target_col: i64, target_col: i64,
target_row: i64, target_row: i64,
) { ) {
use mc_turn::PillageRequest; use mc_state::game_state::PillageRequest;
self.inner.pending_pillage_requests.push(PillageRequest { self.inner.pending_pillage_requests.push(PillageRequest {
player_index: player_index as u8, player_index: player_index as u8,
unit_index: unit_index as usize, unit_index: unit_index as usize,
@ -4483,7 +4483,7 @@ impl GdGameState {
target_row: i64, target_row: i64,
indirect_fire: bool, indirect_fire: bool,
) { ) {
use mc_turn::BombardRequest; use mc_state::game_state::BombardRequest;
self.inner.pending_bombard_requests.push(BombardRequest { self.inner.pending_bombard_requests.push(BombardRequest {
attacker_player: attacker_player as u8, attacker_player: attacker_player as u8,
attacker_unit: attacker_unit as usize, attacker_unit: attacker_unit as usize,
@ -4504,7 +4504,7 @@ impl GdGameState {
target_col: i64, target_col: i64,
target_row: i64, target_row: i64,
) { ) {
use mc_turn::VolleyRequest; use mc_state::game_state::VolleyRequest;
self.inner.pending_volley_requests.push(VolleyRequest { self.inner.pending_volley_requests.push(VolleyRequest {
attacker_player: attacker_player as u8, attacker_player: attacker_player as u8,
attacker_unit: attacker_unit as usize, attacker_unit: attacker_unit as usize,
@ -4524,7 +4524,7 @@ impl GdGameState {
target_col: i64, target_col: i64,
target_row: i64, target_row: i64,
) { ) {
use mc_turn::ChargeRequest; use mc_state::game_state::ChargeRequest;
self.inner.pending_charge_requests.push(ChargeRequest { self.inner.pending_charge_requests.push(ChargeRequest {
attacker_player: attacker_player as u8, attacker_player: attacker_player as u8,
attacker_unit: attacker_unit as usize, attacker_unit: attacker_unit as usize,

View file

@ -8,7 +8,7 @@
//! //!
//! # Where it lives (Rail 1 — Rust source of truth) //! # Where it lives (Rail 1 — Rust source of truth)
//! //!
//! A [`TacticalMemory`] is carried on `mc_turn::PlayerState` (one per player //! A [`TacticalMemory`] is carried on `mc_state::game_state::PlayerState` (one per player
//! slot). `mc_player_api::dispatch::drive_ai_slot` borrows it `&mut` and //! slot). `mc_player_api::dispatch::drive_ai_slot` borrows it `&mut` and
//! threads it into [`super::decide_tactical_actions`] → //! threads it into [`super::decide_tactical_actions`] →
//! [`super::movement::decide_movement`], which mutates it in place. There is //! [`super::movement::decide_movement`], which mutates it in place. There is
@ -35,7 +35,7 @@
//! invisible at the game-decision scale. //! invisible at the game-decision scale.
// p2-65 Phase 0c — `TacticalMemory` is pure data carried on // p2-65 Phase 0c — `TacticalMemory` is pure data carried on
// `mc_turn::PlayerState`, so it relocated to `mc-core` (which the future // `mc_state::game_state::PlayerState`, so it relocated to `mc-core` (which the future
// `mc-state` crate can depend on without pulling `mc-ai`). Re-exported here so // `mc-state` crate can depend on without pulling `mc-ai`). Re-exported here so
// every `mc_ai::tactical::TacticalMemory` reference keeps compiling unchanged; // every `mc_ai::tactical::TacticalMemory` reference keeps compiling unchanged;
// the impl + unit tests now live in `mc_core::tactical_types`. // the impl + unit tests now live in `mc_core::tactical_types`.

View file

@ -182,7 +182,7 @@ fn default_promotion_weight() -> f32 {
/// } /// }
/// ``` /// ```
// p2-65 Phase 0c — `BuildingPriors` relocated to `mc-core` (pure data carried on // p2-65 Phase 0c — `BuildingPriors` relocated to `mc-core` (pure data carried on
// `mc_turn::PlayerState`); re-exported so `crate::tactical::state::BuildingPriors` // `mc_state::game_state::PlayerState`); re-exported so `crate::tactical::state::BuildingPriors`
// keeps resolving. // keeps resolving.
pub use mc_core::tactical_types::BuildingPriors; pub use mc_core::tactical_types::BuildingPriors;

View file

@ -2,7 +2,7 @@
//! //!
//! Per Rail 3 (GDScript is presentation only) and the p2-72a Wall-2 decision, //! Per Rail 3 (GDScript is presentation only) and the p2-72a Wall-2 decision,
//! UI-only player fields — display name, race id, gender preset, banner colour, //! UI-only player fields — display name, race id, gender preset, banner colour,
//! human-vs-AI flag — must not pollute `mc_turn::PlayerState` (simulation state). //! human-vs-AI flag — must not pollute `mc_state::game_state::PlayerState` (simulation state).
//! Instead, they live in this side-table struct that the save envelope carries //! Instead, they live in this side-table struct that the save envelope carries
//! alongside `GameState`. //! alongside `GameState`.
//! //!

View file

@ -21,7 +21,7 @@ use crate::BuildingId;
/// Per-player cross-turn tactical intent (p1-29h). The persistence channel that /// Per-player cross-turn tactical intent (p1-29h). The persistence channel that
/// makes the AI's war *decisive* (capture → elimination) instead of indecisive /// makes the AI's war *decisive* (capture → elimination) instead of indecisive
/// (capture → disperse → opponent refounds). Carried on /// (capture → disperse → opponent refounds). Carried on
/// `mc_turn::PlayerState::tactical_memory` (`#[serde(skip)]` there); the /// `mc_state::game_state::PlayerState::tactical_memory` (`#[serde(skip)]` there); the
/// commitment hysteresis + army-wide target-lock that `mc-ai`'s /// commitment hysteresis + army-wide target-lock that `mc-ai`'s
/// `decide_movement` mutates each turn. /// `decide_movement` mutates each turn.
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]

View file

@ -1448,7 +1448,7 @@ fn apply_move(
state state
.pending_move_requests .pending_move_requests
.push(mc_turn::MoveRequest { .push(mc_state::game_state::MoveRequest {
player_idx, player_idx,
unit_idx, unit_idx,
target_col: to[0], target_col: to[0],

View file

@ -27,7 +27,7 @@ use std::collections::BTreeMap;
use mc_player_api::action::PlayerAction; use mc_player_api::action::PlayerAction;
use mc_player_api::apply_action; use mc_player_api::apply_action;
use mc_turn::{GameState, MapUnit, PlayerState}; use mc_state::game_state::{GameState, MapUnit, PlayerState};
use mc_ai::evaluator::ScoringWeights; use mc_ai::evaluator::ScoringWeights;
use mc_trade::relation::{Relation, RelationState}; use mc_trade::relation::{Relation, RelationState};

View file

@ -20,7 +20,7 @@
use mc_player_api::action::PlayerAction; use mc_player_api::action::PlayerAction;
use mc_player_api::apply_action; use mc_player_api::apply_action;
use mc_player_api::wire::Event; use mc_player_api::wire::Event;
use mc_turn::{GameState, MapUnit, PlayerState}; use mc_state::game_state::{GameState, MapUnit, PlayerState};
#[test] #[test]
fn queued_attack_emits_unit_destroyed_event() { fn queued_attack_emits_unit_destroyed_event() {

View file

@ -25,7 +25,8 @@ use mc_ecology::EcologyEngine;
use mc_flora::FloraEngine; use mc_flora::FloraEngine;
#[cfg(feature = "gpu")] #[cfg(feature = "gpu")]
use mc_compute::AcceleratedClimate; use mc_compute::AcceleratedClimate;
use mc_turn::{CityEcology, GameState, MapUnit, PlayerState, TurnProcessor, VictoryConfig, VictoryType}; use mc_state::game_state::{CityEcology, GameState, MapUnit, PlayerState};
use mc_turn::{TurnProcessor, VictoryConfig, VictoryType};
use serde::Deserialize; use serde::Deserialize;
use std::collections::HashMap; use std::collections::HashMap;
use std::path::Path; use std::path::Path;

View file

@ -23,7 +23,8 @@ use mc_ecology::EcologyEngine;
use mc_flora::FloraEngine; use mc_flora::FloraEngine;
#[cfg(feature = "gpu")] #[cfg(feature = "gpu")]
use mc_compute::AcceleratedClimate; use mc_compute::AcceleratedClimate;
use mc_turn::{CityEcology, FaunaCombatEvent, GameState, MapUnit, PlayerState, TurnProcessor}; use mc_state::game_state::{CityEcology, GameState, MapUnit, PlayerState};
use mc_turn::{FaunaCombatEvent, TurnProcessor};
use std::collections::HashMap; use std::collections::HashMap;
const EVOLUTION_TICKS: u32 = 50_000; const EVOLUTION_TICKS: u32 = 50_000;

View file

@ -11,7 +11,8 @@ use mc_ecology::EcologyEngine;
use mc_flora::FloraEngine; use mc_flora::FloraEngine;
#[cfg(feature = "gpu")] #[cfg(feature = "gpu")]
use mc_compute::AcceleratedClimate; use mc_compute::AcceleratedClimate;
use mc_turn::{CityEcology, GameState, MapUnit, PlayerState, TurnProcessor}; use mc_state::game_state::{CityEcology, GameState, MapUnit, PlayerState};
use mc_turn::{TurnProcessor};
use std::collections::HashMap; use std::collections::HashMap;
const MAP_SIZE: i32 = 48; const MAP_SIZE: i32 = 48;

View file

@ -19,7 +19,8 @@ use mc_core::grid::GridState;
use mc_ecology::evolution::{run_evolution, EventConfig, WorldAgeConfig}; use mc_ecology::evolution::{run_evolution, EventConfig, WorldAgeConfig};
use mc_ecology::EcologyEngine; use mc_ecology::EcologyEngine;
use mc_flora::FloraEngine; use mc_flora::FloraEngine;
use mc_turn::{CityEcology, GameState, MapUnit, PlayerState, TurnProcessor, VictoryConfig, VictoryType}; use mc_state::game_state::{CityEcology, GameState, MapUnit, PlayerState};
use mc_turn::{TurnProcessor, VictoryConfig, VictoryType};
use serde::Deserialize; use serde::Deserialize;
use std::collections::HashMap; use std::collections::HashMap;
use std::path::Path; use std::path::Path;

View file

@ -2,7 +2,8 @@ pub mod event_dispatch;
use mc_balance::{outcome::GameOutcome, runner::SimRunner, strategy::StrategyConfig}; use mc_balance::{outcome::GameOutcome, runner::SimRunner, strategy::StrategyConfig};
use mc_city::CityState; use mc_city::CityState;
use mc_turn::{GameState, PlayerState, TurnProcessor}; use mc_state::game_state::{GameState, PlayerState};
use mc_turn::{TurnProcessor};
/// Real game runner backed by mc-turn. Implements the SimRunner trait /// Real game runner backed by mc-turn. Implements the SimRunner trait
/// so balance-tool and optimizer can run actual simulated games. /// so balance-tool and optimizer can run actual simulated games.

View file

@ -1,17 +0,0 @@
//! Re-export shim (p2-65 Phase 3b).
//!
//! The canonical full-simulation state struct `GameState` and its pending-queue
//! value types now live in [`mc_state::game_state`]. This module re-exports the
//! whole thing so every `crate::game_state::…` / `mc_turn::game_state::…` import
//! path inside `mc-turn` (and the `mc_turn::lib.rs` re-export of `GameState`,
//! `PlayerState`, `MapUnit`, the action-request structs, …) keeps resolving
//! unchanged for one migration cycle.
//!
//! The turn-step *logic* that mutates `GameState` stays in `mc-turn`
//! (`processor.rs`, `action_handlers/`, victory/capture/ransom resolvers). The
//! `PendingCaptureEvents::drain_into` event-translation method — which embeds
//! `mc_replay::TurnEvent` + `mc_turn::combat_event::TurnResult` (both mc-turn
//! shapes, not movable to the data crate without a cycle) — is re-homed as the
//! `crate::capture_drain::DrainCaptureEvents` extension trait.
pub use mc_state::game_state::*;

View file

@ -29,7 +29,11 @@ pub mod chronicle;
pub mod end_conditions; pub mod end_conditions;
pub mod formation_move; pub mod formation_move;
pub mod patrol; pub mod patrol;
pub mod game_state; // p2-65 Phase 4: GameState + pending-queue value types live in `mc-state`.
// Crate-private re-export so mc-turn internals keep using `crate::game_state::…`;
// `pub(crate)` deliberately forbids any external pass-through of these shapes
// through mc-turn (consumers import them from `mc_state` directly).
pub(crate) use mc_state::game_state;
pub mod combat_event; pub mod combat_event;
pub mod processor; pub mod processor;
pub mod prologue; pub mod prologue;
@ -60,7 +64,6 @@ pub use quality::{apply_quality, band_name, resolve_deltas, UnitQualityChain};
pub use lair_siege::{ pub use lair_siege::{
tick_one_lair, LairSiegeConfig, LairSiegeEvent, SiegeTuningData, TickResult, tick_one_lair, LairSiegeConfig, LairSiegeEvent, SiegeTuningData, TickResult,
}; };
pub use game_state::{AttackRequest, BombardRequest, BuildingRallyPoint, ChargeRequest, CityEcology, EscortRequest, GameState, MapUnit, MoveRequest, PillageRequest, PlayerState, TechState, VolleyRequest};
pub use mc_core::improvement::{RawImprovementJson, TileImprovement, TileImprovementSpec}; pub use mc_core::improvement::{RawImprovementJson, TileImprovement, TileImprovementSpec};
pub use capture::{resolve_posture, CapturePosture, PromptUnresolved}; pub use capture::{resolve_posture, CapturePosture, PromptUnresolved};
pub use ransom::{RansomOffer, RansomQueue, RANSOM_OFFER_DURATION_TURNS}; pub use ransom::{RansomOffer, RansomQueue, RANSOM_OFFER_DURATION_TURNS};

View file

@ -4633,7 +4633,7 @@ pub enum MoveOutcome {
}, },
} }
fn process_one_move(state: &mut GameState, req: &crate::MoveRequest) -> MoveOutcome { fn process_one_move(state: &mut GameState, req: &crate::game_state::MoveRequest) -> MoveOutcome {
use mc_pathfinding::{find_path, UnitDomain}; use mc_pathfinding::{find_path, UnitDomain};
// Bounds + lookup. // Bounds + lookup.
@ -4814,7 +4814,7 @@ fn process_one_move(state: &mut GameState, req: &crate::MoveRequest) -> MoveOutc
mod move_request_tests { mod move_request_tests {
use super::*; use super::*;
use crate::game_state::MoveRequest; use crate::game_state::MoveRequest;
use crate::{GameState, MapUnit, PlayerState}; use crate::game_state::{GameState, MapUnit, PlayerState};
use mc_core::grid::GridState; use mc_core::grid::GridState;
fn build_state_with_unit( fn build_state_with_unit(
@ -8096,7 +8096,7 @@ mod tests {
// Move the escort (unit_idx 1) one tile to (6, 4). No grid -> teleport, // Move the escort (unit_idx 1) one tile to (6, 4). No grid -> teleport,
// cost = 1. // cost = 1.
state.pending_move_requests.push(crate::MoveRequest { state.pending_move_requests.push(crate::game_state::MoveRequest {
player_idx: 0, unit_idx: 1, target_col: 6, target_row: 4, player_idx: 0, unit_idx: 1, target_col: 6, target_row: 4,
}); });
let outcomes = process_move_requests(&mut state); let outcomes = process_move_requests(&mut state);
@ -8137,7 +8137,7 @@ mod tests {
..Default::default() ..Default::default()
}; };
state.escort_links.insert(1, 2); state.escort_links.insert(1, 2);
state.pending_move_requests.push(crate::MoveRequest { state.pending_move_requests.push(crate::game_state::MoveRequest {
player_idx: 0, unit_idx: 1, target_col: 6, target_row: 4, player_idx: 0, unit_idx: 1, target_col: 6, target_row: 4,
}); });
let outcomes = process_move_requests(&mut state); let outcomes = process_move_requests(&mut state);

View file

@ -13,7 +13,8 @@ use mc_core::{
ids::SpeciesId, ids::SpeciesId,
}; };
use mc_replay::TurnEvent; use mc_replay::TurnEvent;
use mc_turn::{GameState, MapUnit, PlayerState, TurnProcessor}; use mc_state::game_state::{GameState, MapUnit, PlayerState};
use mc_turn::{TurnProcessor};
/// Load the real encounter_rates.json from the workspace. /// Load the real encounter_rates.json from the workspace.
fn load_rates() -> EncounterRates { fn load_rates() -> EncounterRates {

View file

@ -19,9 +19,8 @@
use mc_core::units::ActionPoints; use mc_core::units::ActionPoints;
use mc_replay::TurnEvent; use mc_replay::TurnEvent;
use mc_turn::{ use mc_state::game_state::{AttackRequest, GameState, MapUnit, PlayerState};
capture::CapturePosture, AttackRequest, GameState, MapUnit, PlayerState, TurnProcessor, use mc_turn::{TurnProcessor, capture::CapturePosture};
};
use mc_units::{CombatStats, UnitStats as CatalogUnitStats, UnitsCatalog}; use mc_units::{CombatStats, UnitStats as CatalogUnitStats, UnitsCatalog};
const CARAVAN_ID: u32 = 900; const CARAVAN_ID: u32 = 900;

View file

@ -40,15 +40,11 @@
use mc_ai::evaluator::ScoringWeights; use mc_ai::evaluator::ScoringWeights;
use mc_city::CityState; use mc_city::CityState;
use mc_replay::TurnEvent; use mc_replay::TurnEvent;
use mc_turn::{ use mc_state::game_state::{GameState, MapUnit, PendingCaptureEvents, PlayerState};
capture_drain::DrainCaptureEvents, use mc_turn::{TurnProcessor, capture_drain::DrainCaptureEvents, combat_event::{
combat_event::{
CivilianDestroyedEvent, TurnResult, UnitCapturedEvent, CivilianDestroyedEvent, TurnResult, UnitCapturedEvent,
UnitRansomAcceptedEvent, UnitRansomExpiredEvent, UnitRansomOfferedEvent, UnitRansomAcceptedEvent, UnitRansomExpiredEvent, UnitRansomOfferedEvent,
}, }};
game_state::{GameState, MapUnit, PendingCaptureEvents, PlayerState},
TurnProcessor,
};
use std::collections::BTreeMap; use std::collections::BTreeMap;
fn minimal_player(index: u8, anchor: (i32, i32)) -> PlayerState { fn minimal_player(index: u8, anchor: (i32, i32)) -> PlayerState {

View file

@ -24,9 +24,8 @@
use mc_core::units::ActionPoints; use mc_core::units::ActionPoints;
use mc_replay::TurnEvent; use mc_replay::TurnEvent;
use mc_turn::{ use mc_state::game_state::{AttackRequest, GameState, MapUnit, PlayerState};
capture::CapturePosture, AttackRequest, GameState, MapUnit, PlayerState, TurnProcessor, use mc_turn::{TurnProcessor, capture::CapturePosture};
};
use mc_units::{CombatStats, UnitStats as CatalogUnitStats, UnitsCatalog}; use mc_units::{CombatStats, UnitStats as CatalogUnitStats, UnitsCatalog};
const ENGINEER_ID: u32 = 800; const ENGINEER_ID: u32 = 800;

View file

@ -40,9 +40,8 @@
//! correct outcome. //! correct outcome.
use mc_replay::TurnEvent; use mc_replay::TurnEvent;
use mc_turn::{ use mc_state::game_state::{AttackRequest, GameState, MapUnit, PlayerState};
capture::CapturePosture, AttackRequest, GameState, MapUnit, PlayerState, TurnProcessor, use mc_turn::{TurnProcessor, capture::CapturePosture};
};
use mc_units::{CombatStats, UnitStats as CatalogUnitStats, UnitsCatalog}; use mc_units::{CombatStats, UnitStats as CatalogUnitStats, UnitsCatalog};
fn build_capturable_catalog() -> UnitsCatalog { fn build_capturable_catalog() -> UnitsCatalog {

View file

@ -22,9 +22,8 @@ use mc_replay::{
ClanId, GameHistory, GameId, MapDescriptor, PackId, PackVersion, TurnEvent, ClanId, GameHistory, GameId, MapDescriptor, PackId, PackVersion, TurnEvent,
TurnEventCollector, TurnEventCollector,
}; };
use mc_turn::{ use mc_state::game_state::{AttackRequest, GameState, MapUnit, PlayerState};
AttackRequest, GameState, MapUnit, PlayerState, TurnProcessor, use mc_turn::{TurnProcessor};
};
use std::collections::BTreeMap; use std::collections::BTreeMap;
fn balanced_player(index: u8, anchor_x: i32) -> PlayerState { fn balanced_player(index: u8, anchor_x: i32) -> PlayerState {

View file

@ -6,7 +6,8 @@
use mc_ai::evaluator::ScoringWeights; use mc_ai::evaluator::ScoringWeights;
use mc_city::CityState; use mc_city::CityState;
use mc_turn::{GameState, LairCombatConfig, PlayerState, TurnProcessor}; use mc_state::game_state::{GameState, PlayerState};
use mc_turn::{LairCombatConfig, TurnProcessor};
use std::collections::BTreeMap; use std::collections::BTreeMap;
fn balanced_player(index: u8) -> PlayerState { fn balanced_player(index: u8) -> PlayerState {

View file

@ -8,10 +8,8 @@
use mc_ai::evaluator::ScoringWeights; use mc_ai::evaluator::ScoringWeights;
use mc_city::CityState; use mc_city::CityState;
use mc_replay::{ClanId, TurnEvent}; use mc_replay::{ClanId, TurnEvent};
use mc_turn::{ use mc_state::game_state::{GameState, PlayerState};
end_conditions::{evaluate_conditions, GameOver, GameOverReason}, use mc_turn::{LairCombatConfig, TurnProcessor, VictoryConfig, VictoryType, end_conditions::{evaluate_conditions, GameOver, GameOverReason}};
GameState, LairCombatConfig, PlayerState, TurnProcessor, VictoryConfig, VictoryType,
};
use std::collections::{BTreeMap, BTreeSet}; use std::collections::{BTreeMap, BTreeSet};
// ── Helpers ─────────────────────────────────────────────────────────────────── // ── Helpers ───────────────────────────────────────────────────────────────────

View file

@ -16,7 +16,8 @@
use mc_ai::evaluator::ScoringWeights; use mc_ai::evaluator::ScoringWeights;
use mc_city::CityState; use mc_city::CityState;
use mc_core::lair::{SiegePressure, SiegeState}; use mc_core::lair::{SiegePressure, SiegeState};
use mc_turn::{GameState, MapUnit, PlayerState, TurnProcessor}; use mc_state::game_state::{GameState, MapUnit, PlayerState};
use mc_turn::{TurnProcessor};
use std::collections::BTreeMap; use std::collections::BTreeMap;
/// A one-player fixture with a single unit at `unit_pos`. Production is left /// A one-player fixture with a single unit at `unit_pos`. Production is left

View file

@ -18,9 +18,8 @@
use mc_ai::evaluator::ScoringWeights; use mc_ai::evaluator::ScoringWeights;
use mc_city::CityState; use mc_city::CityState;
use mc_replay::{ClanId, TurnEvent}; use mc_replay::{ClanId, TurnEvent};
use mc_turn::{ use mc_state::game_state::{GameState, MapUnit, PlayerState};
GameState, MapUnit, PlayerState, TurnProcessor, VictoryConfig, use mc_turn::{TurnProcessor, VictoryConfig};
};
use std::collections::BTreeMap; use std::collections::BTreeMap;
fn player_with_city_at(index: u8, pos: (i32, i32)) -> PlayerState { fn player_with_city_at(index: u8, pos: (i32, i32)) -> PlayerState {

View file

@ -29,7 +29,8 @@
use mc_ai::evaluator::ScoringWeights; use mc_ai::evaluator::ScoringWeights;
use mc_city::{CityState, Queueable, QualityTier}; use mc_city::{CityState, Queueable, QualityTier};
use mc_turn::{GameState, MapUnit, PlayerState, TurnProcessor}; use mc_state::game_state::{GameState, MapUnit, PlayerState};
use mc_turn::{TurnProcessor};
use mc_units::{CombatStats, UnitStats as CatalogUnitStats}; use mc_units::{CombatStats, UnitStats as CatalogUnitStats};
use std::collections::BTreeMap; use std::collections::BTreeMap;

View file

@ -21,7 +21,8 @@
//! unit_id = 200, .. }` is in `result.events_emitted`. //! unit_id = 200, .. }` is in `result.events_emitted`.
use mc_replay::{ClanId, TurnEvent}; use mc_replay::{ClanId, TurnEvent};
use mc_turn::{AttackRequest, GameState, MapUnit, PlayerState, TurnProcessor}; use mc_state::game_state::{AttackRequest, GameState, MapUnit, PlayerState};
use mc_turn::{TurnProcessor};
#[test] #[test]
fn queued_pvp_kill_emits_unit_killed_event() { fn queued_pvp_kill_emits_unit_killed_event() {

View file

@ -31,10 +31,8 @@ static ENV_GUARD: Mutex<()> = Mutex::new(());
use mc_ai::evaluator::ScoringWeights; use mc_ai::evaluator::ScoringWeights;
use mc_city::CityState; use mc_city::CityState;
use mc_replay::TurnEvent; use mc_replay::TurnEvent;
use mc_turn::{ use mc_state::game_state::{GameState, MapUnit, PlayerState};
game_state::{GameState, MapUnit, PlayerState}, use mc_turn::{TurnProcessor};
TurnProcessor,
};
fn data_dir() -> PathBuf { fn data_dir() -> PathBuf {
let manifest = PathBuf::from(env!("CARGO_MANIFEST_DIR")); let manifest = PathBuf::from(env!("CARGO_MANIFEST_DIR"));

View file

@ -22,7 +22,7 @@ use mc_trade::relation::{Relation, RelationState};
use mc_trade::{ use mc_trade::{
CourierRoute, DiplomaticAgreement, OpenBordersAgreement, SharedMapAgreement, TradeLedger, CourierRoute, DiplomaticAgreement, OpenBordersAgreement, SharedMapAgreement, TradeLedger,
}; };
use mc_turn::{GameState, MapUnit, PlayerState, TechState}; use mc_state::game_state::{GameState, MapUnit, PlayerState, TechState};
use std::collections::{BTreeMap, BTreeSet}; use std::collections::{BTreeMap, BTreeSet};
// ── Fixture builders ──────────────────────────────────────────────────────── // ── Fixture builders ────────────────────────────────────────────────────────

View file

@ -22,7 +22,8 @@
use mc_ai::evaluator::ScoringWeights; use mc_ai::evaluator::ScoringWeights;
use mc_city::CityState; use mc_city::CityState;
use mc_replay::TurnEvent; use mc_replay::TurnEvent;
use mc_turn::{GameState, PlayerState, TurnProcessor}; use mc_state::game_state::{GameState, PlayerState};
use mc_turn::{TurnProcessor};
use std::collections::BTreeMap; use std::collections::BTreeMap;
/// Two-player fixture rigged so bench `try_spawn_unit` fires every turn /// Two-player fixture rigged so bench `try_spawn_unit` fires every turn

View file

@ -16,10 +16,8 @@
use mc_ai::evaluator::ScoringWeights; use mc_ai::evaluator::ScoringWeights;
use mc_city::CityState; use mc_city::CityState;
use mc_replay::ClanId; use mc_replay::ClanId;
use mc_turn::{ use mc_state::game_state::{GameState, PlayerState, TechState};
end_conditions::{evaluate_conditions, load_conditions, GameOverReason}, use mc_turn::{VictoryConfig, VictoryType, end_conditions::{evaluate_conditions, load_conditions, GameOverReason}};
GameState, PlayerState, TechState, VictoryConfig, VictoryType,
};
use std::collections::BTreeMap; use std::collections::BTreeMap;
// Path relative to this crate's manifest (CARGO_MANIFEST_DIR resolves to // Path relative to this crate's manifest (CARGO_MANIFEST_DIR resolves to

View file

@ -13,6 +13,7 @@ mc-city = { path = "../../crates/mc-city" }
mc-happiness = { path = "../../crates/mc-happiness" } mc-happiness = { path = "../../crates/mc-happiness" }
mc-combat = { path = "../../crates/mc-combat" } mc-combat = { path = "../../crates/mc-combat" }
mc-culture = { path = "../../crates/mc-culture" } mc-culture = { path = "../../crates/mc-culture" }
mc-state = { path = "../../crates/mc-state" }
mc-turn = { path = "../../crates/mc-turn" } mc-turn = { path = "../../crates/mc-turn" }
[lints] [lints]

View file

@ -6,7 +6,8 @@
//! - resolve_single_pvp_attack enqueues via the same code route as process_pvp_combat //! - resolve_single_pvp_attack enqueues via the same code route as process_pvp_combat
use mc_city::CityState; use mc_city::CityState;
use mc_turn::{AttackRequest, GameState, MapUnit, PlayerState, TurnProcessor}; use mc_state::game_state::{AttackRequest, GameState, MapUnit, PlayerState};
use mc_turn::{TurnProcessor};
use std::collections::BTreeMap; use std::collections::BTreeMap;
fn make_warrior(col: i32, row: i32) -> MapUnit { fn make_warrior(col: i32, row: i32) -> MapUnit {