Skip to main content

GameLoop

Struct GameLoop 

Source
pub struct GameLoop {
    pub mana_pools: Vec<ManaPool>,
    pub combat: CombatState,
    pub trigger_handler: TriggerHandler,
    pub game_log: GameLog,
    pub token_templates: HashMap<String, Card>,
    pub token_art_variants: HashMap<(String, String), usize>,
    pub token_fallback: HashMap<String, String>,
    pub edition_dates: HashMap<String, String>,
    pub game_rng: Box<dyn GameRng>,
    pub experimental_restore_snapshot: bool,
    pub abort_signal: Option<Arc<AtomicBool>>,
    pub provide_priority_action_space: bool,
    /* private fields */
}
Expand description

Drives a complete game from setup through game over.

Fields§

§mana_pools: Vec<ManaPool>§combat: CombatState§trigger_handler: TriggerHandler§game_log: GameLog§token_templates: HashMap<String, Card>

Token templates keyed by their script filename stem (e.g. “r_1_1_goblin”). Populated at game start by the Tauri layer; used by the Token effect handler.

§token_art_variants: HashMap<(String, String), usize>

Token art variant counts: (token_script, edition_code) → count. Used for game-RNG parity with Java. When Java creates a token, it calls Aggregates.random(collection) on a Set of art variants, which consumes nextInt() once per element. Rust needs to consume the same number of RNG calls to keep the game RNG in sync.

§token_fallback: HashMap<String, String>

Token fallback codes: edition_code → fallback_edition_code.

§edition_dates: HashMap<String, String>

Edition release dates: edition_code → “YYYY-MM-DD”.

§game_rng: Box<dyn GameRng>

Pluggable RNG for game effects (shuffles, coin flips, dice rolls). Default: ThreadRngAdapter (non-deterministic). For parity testing, replace with a JavaRandom-backed implementation.

§experimental_restore_snapshot: bool

Enables Java-parity snapshot rollback support (stash_game_state / restore_game_state).

§abort_signal: Option<Arc<AtomicBool>>

Cooperative shutdown signal. When the host (e.g. Tauri’s GameManager::end_game) flips this flag we short-circuit the outer run() loop and bail out. Prevents the engine from continuing to tick after the user has conceded or returned to the main menu — the previous behavior kept the game running silently and drove a visible log/prompt loop on the frontend.

§provide_priority_action_space: bool

Whether the engine precomputes priority action space before calling PlayerAgent::choose_action. UI agents use the default true; parity disables it and requests action space explicitly only when needed.

Implementations§

Source§

impl GameLoop

Source

pub fn step_combat( &mut self, game: &mut GameState, agents: &mut [Box<dyn PlayerAgent>], )

Source§

impl GameLoop

Source

pub fn step_untap( &mut self, game: &mut GameState, agents: &mut [Box<dyn PlayerAgent>], )

Source

pub fn step_draw( &mut self, game: &mut GameState, agents: &mut [Box<dyn PlayerAgent>], )

Source

pub fn step_with_priority( &mut self, game: &mut GameState, agents: &mut [Box<dyn PlayerAgent>], is_main_phase: bool, )

Source

pub fn step_main_phase( &mut self, game: &mut GameState, agents: &mut [Box<dyn PlayerAgent>], )

Source

pub fn step_cleanup( &mut self, game: &mut GameState, agents: &mut [Box<dyn PlayerAgent>], )

Source§

impl GameLoop

Source

pub fn priority_round( &mut self, game: &mut GameState, agents: &mut [Box<dyn PlayerAgent>], is_main_phase: bool, )

Source§

impl GameLoop

Source

pub fn resolve_stack( &mut self, game: &mut GameState, agents: &mut [Box<dyn PlayerAgent>], )

Source§

impl GameLoop

Source

pub fn new(num_players: usize) -> Self

Source

pub fn set_provide_priority_action_space(&mut self, provide: bool)

Source

pub fn set_abort_signal(&mut self, signal: Arc<AtomicBool>)

Install a cooperative abort signal. When the host flips the flag the outer run() loop exits before the next turn so the game thread can wind down cleanly instead of continuing to drive prompts at a frontend that has already unmounted.

Source

pub fn register_token(&mut self, script_name: impl Into<String>, template: Card)

Register a token template by its script filename stem (e.g. “r_1_1_goblin”). Called at game start by the Tauri layer for every token script in the token DB.

Source

pub fn token_art_variant_count( &self, token_script: &str, edition_code: &str, ) -> usize

Get the number of art variants for a token in a given edition. Follows TokenFallbackCode chains. Returns 1 if not found.

Source

pub fn pool(&self, pid: PlayerId) -> &ManaPool

Source

pub fn pool_mut(&mut self, pid: PlayerId) -> &mut ManaPool

Source

pub fn make_snapshot( &self, game: &GameState, include_stack: bool, ) -> GameSnapshot

Create a game snapshot. Set include_stack false for copy-without-stack flows.

Source

pub fn restore_snapshot( &mut self, game: &mut GameState, snapshot: &GameSnapshot, )

Restore a previously captured snapshot.

Source

pub fn stash_game_state(&mut self, game: &GameState)

Stash the current state if snapshot rollback is enabled.

Source

pub fn restore_game_state(&mut self, game: &mut GameState) -> bool

Restore from the previously stashed state if available and enabled.

Source

pub fn restore_checkpoint( &mut self, game: &mut GameState, checkpoint_id: u64, ) -> bool

Source

pub fn get_tappable_lands( &self, game: &GameState, player: PlayerId, ) -> Vec<CardId>

Get untapped lands on the battlefield for a player.

Source

pub fn get_untappable_lands( &self, _game: &GameState, player: PlayerId, _pool_snapshot: &ManaPool, ) -> Vec<CardId>

Get the top reversible mana source for a player, if any.

Source

pub fn setup( &mut self, game: &mut GameState, agents: &mut [Box<dyn PlayerAgent>], rng: &mut impl Rng, )

Set up the game: roll for first player, shuffle libraries, draw opening hands, run mulligans.

Source

pub fn roll_for_first_player( &mut self, game: &mut GameState, agents: &mut [Box<dyn PlayerAgent>], rng: &mut impl Rng, )

Each player rolls a d20; the highest roller goes first. Ties are broken by rerolling among the tied players (resolved internally — only the final round is surfaced to the UI).

Emits a single FirstPlayerRoll notification so the frontend can animate every player’s die side-by-side. Mutates game.turn.active_player and priority_player to the winner.

Source

pub fn run_opening_hand_actions( &mut self, game: &mut GameState, agents: &mut [Box<dyn PlayerAgent>], )

Run generic “opening hand” actions before the game begins.

Mirrors Java’s GameAction.runOpeningHandActions(): gather every MayEffectFromOpeningHand keyword in hand, ask the controller whether to use it, and resolve the referenced SVar immediately.

Source

pub fn run( &mut self, game: &mut GameState, agents: &mut [Box<dyn PlayerAgent>], rng: &mut impl Rng, max_turns: u32, ) -> Option<PlayerId>

Run the full game until someone wins or loses. Returns the winner’s PlayerId.

Source

pub fn run_turn( &mut self, game: &mut GameState, agents: &mut [Box<dyn PlayerAgent>], _rng: &mut impl Rng, )

Run a single turn.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> ArchivePointee for T

Source§

type ArchivedMetadata = ()

The archived version of the pointer metadata for this type.
Source§

fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata

Converts some archived metadata to the pointer metadata for itself.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<F, W, T, D> Deserialize<With<T, W>, D> for F
where W: DeserializeWith<F, T, D>, D: Fallible + ?Sized, F: ?Sized,

Source§

fn deserialize( &self, deserializer: &mut D, ) -> Result<With<T, W>, <D as Fallible>::Error>

Deserializes using the given deserializer
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> LayoutRaw for T

Source§

fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>

Gets the layout of the type.
Source§

impl<T> Pointee for T

Source§

type Metadata = ()

The type for metadata in pointers and references to Self.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V