Skip to main content

PlayerAgent

Trait PlayerAgent 

Source
pub trait PlayerAgent {
Show 82 methods // Required methods fn mulligan_decision( &mut self, player: PlayerId, hand: &[CardId], mulligan_count: u32, ) -> bool; fn choose_action( &mut self, player: PlayerId, action_space: Option<&PriorityActionSpace>, request_action_space: &mut dyn FnMut() -> PriorityActionSpace, ) -> PlayerAction; fn choose_attackers( &mut self, player: PlayerId, available: &[CardId], possible_defenders: &[DefenderId], ) -> Vec<(CardId, DefenderId)>; fn choose_blockers( &mut self, player: PlayerId, attackers: &[CardId], available_blockers: &[CardId], max_blockers: Option<usize>, ) -> Vec<(CardId, CardId)>; fn choose_targets_for( &mut self, sa: &mut SpellAbility, game: &GameState, mana_pools: &[ManaPool], ) -> bool; fn choose_target_player( &mut self, player: PlayerId, valid: &[PlayerId], sa: Option<&SpellAbility>, ) -> Option<PlayerId>; fn choose_target_card( &mut self, player: PlayerId, valid: &[CardId], sa: Option<&SpellAbility>, ) -> Option<CardId>; fn choose_target_any( &mut self, player: PlayerId, valid_players: &[PlayerId], valid_cards: &[CardId], sa: Option<&SpellAbility>, ) -> TargetChoice; fn choose_land_or_spell(&mut self, player: PlayerId) -> Option<bool>; // Provided methods fn snapshot_state(&mut self, _game: &GameState, _mana_pools: &[ManaPool]) { ... } fn take_restore_request(&mut self) -> Option<u64> { ... } fn reveal_cards( &mut self, _game: &GameState, _player: PlayerId, _cards: &[CardId], _zone: ZoneType, _owner: PlayerId, _message_prefix: Option<&str>, ) { ... } fn get_pass_until(&self) -> Option<PassUntilTarget> { ... } fn clear_pass_until(&mut self) { ... } fn mulligan_decision_send( &mut self, _player: PlayerId, _hand: &[CardId], _mulligan_count: u32, ) { ... } fn mulligan_decision_recv( &mut self, player: PlayerId, hand: &[CardId], mulligan_count: u32, ) -> bool { ... } fn choose_cards_to_bottom( &mut self, _player: PlayerId, hand: &[CardId], count: usize, ) -> Vec<CardId> { ... } fn choose_cards_to_bottom_send( &mut self, _player: PlayerId, _hand: &[CardId], _count: usize, ) { ... } fn choose_cards_to_bottom_recv( &mut self, player: PlayerId, hand: &[CardId], count: usize, ) -> Vec<CardId> { ... } fn exert_attackers( &mut self, _player: PlayerId, _attackers: &[CardId], ) -> Vec<CardId> { ... } fn enlist_attackers( &mut self, _player: PlayerId, _attackers: &[CardId], ) -> Vec<CardId> { ... } fn choose_blocker_for( &mut self, player: PlayerId, attackers: &[CardId], blocker: CardId, ) -> Option<CardId> { ... } fn choose_damage_assignment_order( &mut self, _player: PlayerId, _attacker: CardId, blockers: &[CardId], ) -> Vec<CardId> { ... } fn assign_combat_damage( &mut self, game: &GameState, _player: PlayerId, attacker: CardId, blockers_in_order: &[CardId], defender_id: Option<DefenderId>, damage_to_assign: i32, ) -> Vec<(Option<CardId>, i32)> { ... } fn choose_target_card_from_zone( &mut self, player: PlayerId, _zone: ZoneType, valid: &[CardId], sa: Option<&SpellAbility>, ) -> Option<CardId> { ... } fn choose_sacrifice( &mut self, _player: PlayerId, valid: &[CardId], _source: Option<CardId>, ) -> Option<CardId> { ... } fn choose_scry( &mut self, _game: &GameState, _player: PlayerId, _source: Option<CardId>, cards: &[CardId], ) -> Vec<Vec<CardId>> { ... } fn choose_surveil( &mut self, _game: &GameState, _player: PlayerId, _source: Option<CardId>, cards: &[CardId], ) -> Vec<Vec<CardId>> { ... } fn choose_dig( &mut self, _game: &GameState, _player: PlayerId, valid: &[CardId], max: usize, _optional: bool, ) -> Vec<CardId> { ... } fn choose_reorder_library( &mut self, _game: &GameState, _player: PlayerId, cards: &[CardId], ) -> Vec<CardId> { ... } fn choose_discard( &mut self, _player: PlayerId, hand: &[CardId], num: usize, ) -> Vec<CardId> { ... } fn choose_discard_any_number( &mut self, _player: PlayerId, hand: &[CardId], min: usize, max: usize, ) -> Vec<CardId> { ... } fn choose_random_discard( &mut self, _player: PlayerId, hand: &[CardId], num: usize, ) -> Vec<CardId> { ... } fn choose_target_spell( &mut self, _player: PlayerId, valid: &[u32], _source: Option<CardId>, ) -> Option<u32> { ... } fn choose_mode( &mut self, _player: PlayerId, descriptions: &[String], min: usize, _max: usize, _source_card_id: Option<CardId>, ) -> Vec<usize> { ... } fn choose_spell_abilities_for_effect( &mut self, _player: PlayerId, abilities: &[SpellAbility], num: usize, ) -> Vec<usize> { ... } fn choose_single_entity_for_effect( &mut self, _player: PlayerId, valid: &[GameEntity], _is_optional: bool, ) -> Option<GameEntity> { ... } fn get_ability_to_play( &mut self, _player: PlayerId, abilities: &[SpellAbility], ) -> Option<usize> { ... } fn choose_legend_keep( &mut self, _player: PlayerId, duplicates: &[CardId], ) -> CardId { ... } fn choose_optional_trigger( &mut self, _player: PlayerId, _description: &str, _source: Option<CardId>, _api: Option<ApiType>, ) -> bool { ... } fn confirm_replacement_effect( &mut self, _player: PlayerId, _question: &str, _effect_description: &str, _source: Option<CardId>, ) -> bool { ... } fn confirm_action( &mut self, _player: PlayerId, _mode: Option<&str>, _message: &str, _options: &[String], _source: Option<CardId>, _api: Option<ApiType>, ) -> bool { ... } fn confirm_payment( &mut self, player: PlayerId, cost_kind: &str, message: &str, source: Option<CardId>, api: Option<ApiType>, ) -> bool { ... } fn pay_cost_to_prevent_effect( &mut self, player: PlayerId, cost_kind: &str, message: &str, source: Option<CardId>, api: Option<ApiType>, can_pay: bool, targets: &[GameEntity], effect_text: &str, ) -> bool { ... } fn choose_binary( &mut self, player: PlayerId, question: &str, kind: BinaryChoiceKind, _default_choice: Option<bool>, source: Option<CardId>, api: Option<ApiType>, ) -> bool { ... } fn choose_kicker( &mut self, _player: PlayerId, _kicker_cost: &str, _source: Option<CardId>, ) -> bool { ... } fn help_pay_assist( &mut self, _player: PlayerId, _card_name: &str, _max_generic: u32, ) -> u32 { ... } fn choose_buyback( &mut self, _player: PlayerId, _buyback_cost: &str, _source: Option<CardId>, ) -> bool { ... } fn choose_multikicker( &mut self, _player: PlayerId, _cost: &str, _max_kicks: u32, _source: Option<CardId>, ) -> u32 { ... } fn choose_replicate( &mut self, _player: PlayerId, _cost: &str, _max_replicates: u32, _source: Option<CardId>, ) -> u32 { ... } fn choose_color( &mut self, _player: PlayerId, valid_colors: &[String], ) -> Option<String> { ... } fn choose_colors( &mut self, _player: PlayerId, valid_colors: &[String], min: usize, max: usize, ) -> Vec<String> { ... } fn choose_cards_for_effect( &mut self, _player: PlayerId, valid: &[CardId], _min: usize, max: usize, ) -> Vec<CardId> { ... } fn choose_tap_type_for_cost( &mut self, player: PlayerId, valid: &[CardId], _min_total_power: i32, _card_powers: &[(CardId, i32)], _card_sort_powers: &[(CardId, i32)], _sa: Option<&SpellAbility>, ) -> Vec<CardId> { ... } fn choose_entities_for_effect( &mut self, _player: PlayerId, candidates: &[GameEntity], _min: usize, max: usize, ) -> Vec<GameEntity> { ... } fn choose_single_card_for_zone_change( &mut self, _game: &GameState, player: PlayerId, valid: &[CardId], _select_prompt: &str, _is_optional: bool, ) -> Option<CardId> { ... } fn choose_cards_for_zone_change( &mut self, _game: &GameState, player: PlayerId, valid: &[CardId], min: usize, max: usize, _select_prompt: &str, ) -> Vec<CardId> { ... } fn choose_type( &mut self, _player: PlayerId, _type_category: &str, valid_types: &[String], ) -> Option<String> { ... } fn choose_counter_type( &mut self, _player: PlayerId, options: &[CounterType], _prompt: &str, ) -> Option<CounterType> { ... } fn choose_card_name( &mut self, _player: PlayerId, valid_names: &[String], ) -> Option<String> { ... } fn choose_number( &mut self, _player: PlayerId, _source: Option<CardId>, _title: &str, _description: Option<&str>, min: i32, _max: i32, ) -> Option<i32> { ... } fn choose_number_for_keyword_cost( &mut self, _player: PlayerId, _max: i32, _prompt: &str, _source: Option<CardId>, ) -> i32 { ... } fn choose_number_from_list( &mut self, _player: PlayerId, choices: &[i32], _message: &str, _source_card_id: Option<CardId>, ) -> Option<i32> { ... } fn choose_roll_to_ignore( &mut self, _player: PlayerId, rolls: &[i32], _source: Option<CardId>, ) -> Option<i32> { ... } fn choose_roll_to_swap( &mut self, _player: PlayerId, rolls: &[i32], _source: Option<CardId>, ) -> Option<i32> { ... } fn choose_dice_to_reroll( &mut self, _player: PlayerId, _rolls: &[i32], _source: Option<CardId>, ) -> Vec<i32> { ... } fn choose_roll_to_modify( &mut self, _player: PlayerId, rolls: &[i32], _source: Option<CardId>, ) -> Option<i32> { ... } fn choose_roll_swap_value( &mut self, _player: PlayerId, _current_result: i32, _power: i32, _toughness: i32, _source: Option<CardId>, ) -> Option<RollSwapChoice> { ... } fn flip_coin_call(&mut self, _player: PlayerId) -> bool { ... } fn choose_phyrexian_pay_life( &mut self, _player: PlayerId, _color: &str, _source: Option<CardId>, ) -> bool { ... } fn pay_combat_cost( &mut self, _player: PlayerId, _attacker: CardId, _cost: i32, _description: &str, _mana_ability_options: &[ManaAbilityOption], _tappable_lands: &[CardId], _untappable_lands: &[CardId], _mana_pool_total: i32, ) -> CombatCostAction { ... } fn choose_delve( &mut self, _player: PlayerId, valid: &[CardId], max: usize, _source: Option<CardId>, ) -> Vec<CardId> { ... } fn choose_improvise( &mut self, _player: PlayerId, _untapped_artifacts: &[CardId], _remaining_cost: &ManaCost, _source: Option<CardId>, ) -> Vec<CardId> { ... } fn choose_convoke( &mut self, _player: PlayerId, _untapped_creatures: &[CardId], _remaining_cost: &ManaCost, _source: Option<CardId>, ) -> Vec<CardId> { ... } fn pay_mana_cost( &mut self, _player: PlayerId, _card_id: CardId, _card_name: &str, _mana_cost: &str, _mana_cost_display: &str, _mana_cost_checkpoint: &str, _can_confirm_from_pool: bool, _allow_reserved_source_reuse: bool, _reserved_sacrifices: &[CardId], _mana_ability_options: &[ManaAbilityOption], _tappable_lands: &[CardId], _untappable_lands: &[CardId], _mana_pool: &ManaPool, ) -> ManaCostAction { ... } fn await_display_ack(&mut self) { ... } fn decide_cost_part( &mut self, _player: PlayerId, _source: CardId, _cost_part: &CostPart, _game: &GameState, ) -> Option<PaymentDecision> { ... } fn pays_right_after_decision(&self) -> bool { ... } fn order_cost_parts(&mut self, parts: Vec<CostPart>) -> Vec<CostPart> { ... } fn specify_mana_combo( &mut self, _player: PlayerId, available_colors: &[String], amount: usize, _source: Option<CardId>, _express_choice: Option<u16>, ) -> Vec<String> { ... } fn notify(&mut self, _event: GameNotification) { ... } fn choose_single_replacement_effect( &mut self, _player: PlayerId, _descriptions: &[String], ) -> usize { ... }
}
Expand description

Trait for player decision-making. Decouples the engine from UI/AI. Implementations can be interactive (prompt user), AI, or network-driven.

Required Methods§

Source

fn mulligan_decision( &mut self, player: PlayerId, hand: &[CardId], mulligan_count: u32, ) -> bool

Choose whether to keep the current opening hand or mulligan. mulligan_count is the number of mulligans already taken this game. Returns true to keep, false to mulligan.

Source

fn choose_action( &mut self, player: PlayerId, action_space: Option<&PriorityActionSpace>, request_action_space: &mut dyn FnMut() -> PriorityActionSpace, ) -> PlayerAction

Choose a main-phase action: play a card from hand, tap a land for mana, untap a land, activate an ability, or pass. tappable_lands lists untapped lands available for tapping. untappable_lands lists source IDs whose most recent mana action can be undone. activatable lists (card_id, ability_index) pairs for activated abilities that can be used.

Source

fn choose_attackers( &mut self, player: PlayerId, available: &[CardId], possible_defenders: &[DefenderId], ) -> Vec<(CardId, DefenderId)>

Choose attackers from available creatures, assigning each to a defender. possible_defenders lists valid attack targets (opponent players + their planeswalkers). Returns (attacker, defender) pairs.

Source

fn choose_blockers( &mut self, player: PlayerId, attackers: &[CardId], available_blockers: &[CardId], max_blockers: Option<usize>, ) -> Vec<(CardId, CardId)>

Choose blockers. Returns pairs of (blocker, attacker). max_blockers is the BlockRestrict limit (if any) — agent should stop after this many.

Source

fn choose_targets_for( &mut self, sa: &mut SpellAbility, game: &GameState, mana_pools: &[ManaPool], ) -> bool

Source

fn choose_target_player( &mut self, player: PlayerId, valid: &[PlayerId], sa: Option<&SpellAbility>, ) -> Option<PlayerId>

Choose a target player (e.g. for Lightning Bolt targeting a player). sa is the active spell ability context (source card, API type, etc.) for UI display.

Source

fn choose_target_card( &mut self, player: PlayerId, valid: &[CardId], sa: Option<&SpellAbility>, ) -> Option<CardId>

Choose a target card (e.g. for Lightning Bolt targeting a creature).

Source

fn choose_target_any( &mut self, player: PlayerId, valid_players: &[PlayerId], valid_cards: &[CardId], sa: Option<&SpellAbility>, ) -> TargetChoice

Choose a target that can be a player or a card (e.g. “any target”).

Source

fn choose_land_or_spell(&mut self, player: PlayerId) -> Option<bool>

Choose whether to play a land or cast a spell when both are possible. Returns true for land, false for spell, None to pass.

Provided Methods§

Source

fn snapshot_state(&mut self, _game: &GameState, _mana_pools: &[ManaPool])

Called before each agent decision point with the current game state. Override this to capture snapshots for a UI or network layer.

Source

fn take_restore_request(&mut self) -> Option<u64>

Poll and clear any pending snapshot-restore request from this agent.

Source

fn reveal_cards( &mut self, _game: &GameState, _player: PlayerId, _cards: &[CardId], _zone: ZoneType, _owner: PlayerId, _message_prefix: Option<&str>, )

Source

fn get_pass_until(&self) -> Option<PassUntilTarget>

Returns the (player, phase) slot this player auto-passes until. A stop is genuinely (player, phase): “pass until Player2’s end” is distinct from “pass until my end”. The declaration is HELD across priority windows — the engine does not consume it each pass — and is cleared only when the target is reached or a meaningful event occurs. None = no standing pass-until (prompt normally).

Source

fn clear_pass_until(&mut self)

Clear the pass-until declaration (target reached, cast, attackers declared, …).

Source

fn mulligan_decision_send( &mut self, _player: PlayerId, _hand: &[CardId], _mulligan_count: u32, )

Fire the mulligan prompt without blocking for a response. Default: no-op. UI agents override to decouple prompt dispatch from response collection so multiple players can be prompted in parallel.

Source

fn mulligan_decision_recv( &mut self, player: PlayerId, hand: &[CardId], mulligan_count: u32, ) -> bool

Block waiting for the mulligan response previously sent via mulligan_decision_send. Default falls back to the blocking mulligan_decision so agents that don’t split send/recv still work.

Source

fn choose_cards_to_bottom( &mut self, _player: PlayerId, hand: &[CardId], count: usize, ) -> Vec<CardId>

London Mulligan: after keeping, choose count cards from hand to put on the bottom of the library. Returns exactly count card IDs. Default: picks the first count cards (suitable for simple AI agents).

Source

fn choose_cards_to_bottom_send( &mut self, _player: PlayerId, _hand: &[CardId], _count: usize, )

Fire the put-back prompt without blocking. Default: no-op.

Source

fn choose_cards_to_bottom_recv( &mut self, player: PlayerId, hand: &[CardId], count: usize, ) -> Vec<CardId>

Block waiting for the put-back response. Default falls back to the blocking choose_cards_to_bottom.

Source

fn exert_attackers( &mut self, _player: PlayerId, _attackers: &[CardId], ) -> Vec<CardId>

Choose which attackers to exert. Input is the subset of already-declared attackers that can pay an Exert optional attack cost. Return a subset of attackers. Default: choose none.

Source

fn enlist_attackers( &mut self, _player: PlayerId, _attackers: &[CardId], ) -> Vec<CardId>

Choose which attackers to enlist. Input is the subset of already-declared attackers that can pay an Enlist optional attack cost. Return a subset of attackers. Default: choose none.

Source

fn choose_blocker_for( &mut self, player: PlayerId, attackers: &[CardId], blocker: CardId, ) -> Option<CardId>

Choose one attacker for a specific blocker during sequential declaration.

Return Some(attacker_id) to assign this blocker, or None to leave it unassigned. Default behavior maps through choose_blockers for the single blocker, preserving existing agent behavior when not overridden.

Source

fn choose_damage_assignment_order( &mut self, _player: PlayerId, _attacker: CardId, blockers: &[CardId], ) -> Vec<CardId>

Choose the order in which an attacker assigns damage to its blockers. The attacker must assign lethal damage to each blocker in order before assigning damage to the next one. Returns a permutation of blockers in the desired assignment order. Default: return blockers as-is (no reordering).

Source

fn assign_combat_damage( &mut self, game: &GameState, _player: PlayerId, attacker: CardId, blockers_in_order: &[CardId], defender_id: Option<DefenderId>, damage_to_assign: i32, ) -> Vec<(Option<CardId>, i32)>

Choose exact combat damage assignment for one blocked attacker.

blockers_in_order are in assignment order. defender_id is provided only when damage can legally be assigned to the defender (e.g. trample).

Return pairs of (assignee, damage) where:

  • Some(card_id) assigns to a blocker
  • None assigns to defender
Source

fn choose_target_card_from_zone( &mut self, player: PlayerId, _zone: ZoneType, valid: &[CardId], sa: Option<&SpellAbility>, ) -> Option<CardId>

Choose a target card from a specific zone (e.g. Raise Dead from graveyard).

Source

fn choose_sacrifice( &mut self, _player: PlayerId, valid: &[CardId], _source: Option<CardId>, ) -> Option<CardId>

Choose one permanent to sacrifice/select from the valid options. sa is the active spell ability context for UI display. Default picks the first (used by AI agents).

Source

fn choose_scry( &mut self, _game: &GameState, _player: PlayerId, _source: Option<CardId>, cards: &[CardId], ) -> Vec<Vec<CardId>>

Distribute the looked-at Scry cards across the zones. Returns one ordered pile per zone — [top, bottom] — where the last id in each pile is placed on top of that pile. Default: keep everything on top, nothing to bottom.

Source

fn choose_surveil( &mut self, _game: &GameState, _player: PlayerId, _source: Option<CardId>, cards: &[CardId], ) -> Vec<Vec<CardId>>

Distribute the looked-at Surveil cards: [top, graveyard] ordered piles. Default: keep everything on top, nothing milled.

Source

fn choose_dig( &mut self, _game: &GameState, _player: PlayerId, valid: &[CardId], max: usize, _optional: bool, ) -> Vec<CardId>

Choose up to max cards from valid to move to the destination zone (Dig effect). optional means the player is not required to choose any. Default: take first max cards.

Source

fn choose_reorder_library( &mut self, _game: &GameState, _player: PlayerId, cards: &[CardId], ) -> Vec<CardId>

Choose an ordering for the top N cards being put back on the library (Ponder/Reorder). Returns the cards in desired order: index 0 will be placed deepest, last will be on top. Default: keep original order.

Source

fn choose_discard( &mut self, _player: PlayerId, hand: &[CardId], num: usize, ) -> Vec<CardId>

Choose which cards to discard from hand (for SP$ Discard effects). hand is the full hand, num is how many must be discarded. Default: discard the first num cards.

Source

fn choose_discard_any_number( &mut self, _player: PlayerId, hand: &[CardId], min: usize, max: usize, ) -> Vec<CardId>

Choose any number of cards to discard (for AnyNumber$ True on SP$/DB$ Discard). The agent may pick 0..=hand.len() cards. Default: discard min cards (the minimum forced amount).

Source

fn choose_random_discard( &mut self, _player: PlayerId, hand: &[CardId], num: usize, ) -> Vec<CardId>

Choose cards to discard at random (for Mode$ Random discard, e.g. Hypnotic Specter). The engine calls this instead of choose_discard when the discard is random. Default: discard the first num cards (same as choose_discard). Deterministic agents should override this to use their seeded RNG.

Source

fn choose_target_spell( &mut self, _player: PlayerId, valid: &[u32], _source: Option<CardId>, ) -> Option<u32>

Choose a target spell on the stack (for SP$ Counter effects). valid is a slice of stack entry IDs. Default: target the first (topmost) spell.

Source

fn choose_mode( &mut self, _player: PlayerId, descriptions: &[String], min: usize, _max: usize, _source_card_id: Option<CardId>, ) -> Vec<usize>

Choose N modes for a modal spell (SP$ Charm / Commands).

descriptions — human-readable description of each mode. min — minimum number of modes to choose. max — maximum number of modes to choose.

Returns indices into descriptions of the chosen modes, in order. Default: choose the first min modes (index 0, 1, …).

Source

fn choose_spell_abilities_for_effect( &mut self, _player: PlayerId, abilities: &[SpellAbility], num: usize, ) -> Vec<usize>

Source

fn choose_single_entity_for_effect( &mut self, _player: PlayerId, valid: &[GameEntity], _is_optional: bool, ) -> Option<GameEntity>

Choose exactly one entity (Card or Player) from a candidate list.

Source

fn get_ability_to_play( &mut self, _player: PlayerId, abilities: &[SpellAbility], ) -> Option<usize>

Source

fn choose_legend_keep( &mut self, _player: PlayerId, duplicates: &[CardId], ) -> CardId

Choose which legendary permanent to keep when the legend rule applies. duplicates contains all legendaries with the same name controlled by this player. Returns the CardId of the one to keep; the rest are sacrificed.

Source

fn choose_optional_trigger( &mut self, _player: PlayerId, _description: &str, _source: Option<CardId>, _api: Option<ApiType>, ) -> bool

Choose whether an optional triggered ability fires. description is the trigger text shown to the player. source is the engine card id of the source card (for UI display). api is the spell ability API type. Returns true to allow the trigger, false to decline. Default: always allow (non-interactive agents accept all optional triggers).

Source

fn confirm_replacement_effect( &mut self, _player: PlayerId, _question: &str, _effect_description: &str, _source: Option<CardId>, ) -> bool

Source

fn confirm_action( &mut self, _player: PlayerId, _mode: Option<&str>, _message: &str, _options: &[String], _source: Option<CardId>, _api: Option<ApiType>, ) -> bool

Generic confirmation hook for optional effect prompts that don’t yet have a dedicated typed callback in the Rust agent interface.

Returns true to accept/confirm, false to decline.

Source

fn confirm_payment( &mut self, player: PlayerId, cost_kind: &str, message: &str, source: Option<CardId>, api: Option<ApiType>, ) -> bool

Source

fn pay_cost_to_prevent_effect( &mut self, player: PlayerId, cost_kind: &str, message: &str, source: Option<CardId>, api: Option<ApiType>, can_pay: bool, targets: &[GameEntity], effect_text: &str, ) -> bool

Source

fn choose_binary( &mut self, player: PlayerId, question: &str, kind: BinaryChoiceKind, _default_choice: Option<bool>, source: Option<CardId>, api: Option<ApiType>, ) -> bool

Source

fn choose_kicker( &mut self, _player: PlayerId, _kicker_cost: &str, _source: Option<CardId>, ) -> bool

Choose whether to pay the kicker cost for a spell. kicker_cost is the mana cost string (e.g. “W”, “2 R”). source is the name of the spell being cast (for UI display). Returns true to kick, false to cast without kicker. Default: don’t kick (AI default).

Source

fn help_pay_assist( &mut self, _player: PlayerId, _card_name: &str, _max_generic: u32, ) -> u32

Assist: another player asks if we’ll help pay generic mana. Returns how much generic mana to pay (0 = decline). Default: decline.

Source

fn choose_buyback( &mut self, _player: PlayerId, _buyback_cost: &str, _source: Option<CardId>, ) -> bool

Choose whether to pay the buyback cost for a spell. Returns true to pay buyback, false to cast normally. Default: don’t pay buyback.

Source

fn choose_multikicker( &mut self, _player: PlayerId, _cost: &str, _max_kicks: u32, _source: Option<CardId>, ) -> u32

Choose how many times to pay the multikicker cost. max_kicks is the maximum affordable. Returns the number of times to kick (0 to max_kicks). Default: 0 (don’t multikick).

Source

fn choose_replicate( &mut self, _player: PlayerId, _cost: &str, _max_replicates: u32, _source: Option<CardId>, ) -> u32

Choose how many times to pay the replicate cost. max_replicates is the maximum affordable. Returns the number of replicates. Default: 0.

Source

fn choose_color( &mut self, _player: PlayerId, valid_colors: &[String], ) -> Option<String>

Choose a color (for ChooseColorEffect). valid_colors lists the legal color choices (e.g. [“White”,“Blue”,“Black”,“Red”,“Green”]). Default: pick the first valid color.

Source

fn choose_colors( &mut self, _player: PlayerId, valid_colors: &[String], min: usize, max: usize, ) -> Vec<String>

Choose one or more colors.

Source

fn choose_cards_for_effect( &mut self, _player: PlayerId, valid: &[CardId], _min: usize, max: usize, ) -> Vec<CardId>

Choose cards for an effect (ChooseCardEffect, CloneEffect, etc.). valid lists eligible card IDs, min/max are the selection bounds. Default: pick up to max from the front of valid.

Source

fn choose_tap_type_for_cost( &mut self, player: PlayerId, valid: &[CardId], _min_total_power: i32, _card_powers: &[(CardId, i32)], _card_sort_powers: &[(CardId, i32)], _sa: Option<&SpellAbility>, ) -> Vec<CardId>

Choose cards to tap for a tapXType cost that has a total-power floor such as Crew. card_powers carries the effective tap-power value for each candidate under the active ability; card_sort_powers carries the normal net power value used by Forge’s deterministic cost plumbing when ordering candidates.

Source

fn choose_entities_for_effect( &mut self, _player: PlayerId, candidates: &[GameEntity], _min: usize, max: usize, ) -> Vec<GameEntity>

Choose game entities (players and/or permanents) for an effect like Proliferate.

Source

fn choose_single_card_for_zone_change( &mut self, _game: &GameState, player: PlayerId, valid: &[CardId], _select_prompt: &str, _is_optional: bool, ) -> Option<CardId>

Choose a single card for hidden-origin zone changes (e.g. library search).

Source

fn choose_cards_for_zone_change( &mut self, _game: &GameState, player: PlayerId, valid: &[CardId], min: usize, max: usize, _select_prompt: &str, ) -> Vec<CardId>

Choose multiple cards for hidden-origin zone changes (e.g. tutor multi-select).

Source

fn choose_type( &mut self, _player: PlayerId, _type_category: &str, valid_types: &[String], ) -> Option<String>

Choose a creature/card type (for ChooseType effect). type_category is “Creature”, “Card”, “Land”, etc. valid_types lists the legal type choices. Default: pick the first valid type.

Source

fn choose_counter_type( &mut self, _player: PlayerId, options: &[CounterType], _prompt: &str, ) -> Option<CounterType>

Choose a counter type.

Source

fn choose_card_name( &mut self, _player: PlayerId, valid_names: &[String], ) -> Option<String>

Choose a card name (for NameCard effect). valid_names lists the legal card name choices (for ChooseFromList mode). Default: pick the first valid name.

Source

fn choose_number( &mut self, _player: PlayerId, _source: Option<CardId>, _title: &str, _description: Option<&str>, min: i32, _max: i32, ) -> Option<i32>

Choose a number within [min, max]. title/description present the choice and source is the card driving it (shown in the prompt). Default: pick the minimum.

Source

fn choose_number_for_keyword_cost( &mut self, _player: PlayerId, _max: i32, _prompt: &str, _source: Option<CardId>, ) -> i32

Choose how many times to pay an optional keyword cost. Default: decline optional keyword costs.

Source

fn choose_number_from_list( &mut self, _player: PlayerId, choices: &[i32], _message: &str, _source_card_id: Option<CardId>, ) -> Option<i32>

Choose one number from an explicit list of legal rolled values.

Source

fn choose_roll_to_ignore( &mut self, _player: PlayerId, rolls: &[i32], _source: Option<CardId>, ) -> Option<i32>

Choose one die result from a rolled list to ignore.

Source

fn choose_roll_to_swap( &mut self, _player: PlayerId, rolls: &[i32], _source: Option<CardId>, ) -> Option<i32>

Choose one rolled result to exchange with a card’s power or toughness.

Source

fn choose_dice_to_reroll( &mut self, _player: PlayerId, _rolls: &[i32], _source: Option<CardId>, ) -> Vec<i32>

Choose one or more dice to reroll from the current natural roll list.

Source

fn choose_roll_to_modify( &mut self, _player: PlayerId, rolls: &[i32], _source: Option<CardId>, ) -> Option<i32>

Choose one rolled result to increment or decrement by 1.

Source

fn choose_roll_swap_value( &mut self, _player: PlayerId, _current_result: i32, _power: i32, _toughness: i32, _source: Option<CardId>, ) -> Option<RollSwapChoice>

Choose whether a swap should use power or toughness.

Source

fn flip_coin_call(&mut self, _player: PlayerId) -> bool

Choose heads or tails for a coin flip. Returns true for heads, false for tails. Default: always call heads.

Source

fn choose_phyrexian_pay_life( &mut self, _player: PlayerId, _color: &str, _source: Option<CardId>, ) -> bool

Choose whether to pay life instead of mana for a Phyrexian mana shard. Returns true to pay 2 life, false to pay the color. Default: always pay color (never pay life).

Source

fn pay_combat_cost( &mut self, _player: PlayerId, _attacker: CardId, _cost: i32, _description: &str, _mana_ability_options: &[ManaAbilityOption], _tappable_lands: &[CardId], _untappable_lands: &[CardId], _mana_pool_total: i32, ) -> CombatCostAction

Pay an attack cost for a creature (Propaganda, Ghostly Prison). Called in a loop: tap lands to build mana, then Pay or Decline.

Source

fn choose_delve( &mut self, _player: PlayerId, valid: &[CardId], max: usize, _source: Option<CardId>, ) -> Vec<CardId>

Choose graveyard cards to exile for Delve (reduces generic cost). valid lists graveyard card IDs, max is the maximum that can be exiled. Default: exile max cards (maximize cost reduction). The interactive UI resolves delve inside the mana-payment session, not via this callback.

Source

fn choose_improvise( &mut self, _player: PlayerId, _untapped_artifacts: &[CardId], _remaining_cost: &ManaCost, _source: Option<CardId>, ) -> Vec<CardId>

Choose artifacts to tap for Improvise (each pays {1} generic). untapped_artifacts lists available artifacts to tap. Default: don’t improvise (AI default — auto-tap handles mana).

Source

fn choose_convoke( &mut self, _player: PlayerId, _untapped_creatures: &[CardId], _remaining_cost: &ManaCost, _source: Option<CardId>, ) -> Vec<CardId>

Choose creatures to tap for Convoke (each pays {1} or a matching colored mana). untapped_creatures lists available creatures to tap. Default: don’t convoke (AI default — auto-tap handles mana).

Source

fn pay_mana_cost( &mut self, _player: PlayerId, _card_id: CardId, _card_name: &str, _mana_cost: &str, _mana_cost_display: &str, _mana_cost_checkpoint: &str, _can_confirm_from_pool: bool, _allow_reserved_source_reuse: bool, _reserved_sacrifices: &[CardId], _mana_ability_options: &[ManaAbilityOption], _tappable_lands: &[CardId], _untappable_lands: &[CardId], _mana_pool: &ManaPool, ) -> ManaCostAction

Pay a mana cost within a single payment session. Called in a loop for manual interaction: tap lands to build mana, then Pay { auto: false } or Cancel. Agents can also return Pay { auto: true } to delegate the rest of the session to engine auto-pay. Default: always cancel.

Source

fn await_display_ack(&mut self)

Block until this agent acknowledges a display-only prompt that requires UI dwell time (e.g. dice roll animations). Default implementation is a no-op — only human-driven transports need to wait for an ack.

Used to make multi-agent broadcasts run their UI in parallel: the broadcast loop dispatches the prompt to every agent in one pass (so all clients receive it simultaneously), then a second pass calls await_display_ack on each agent so the engine blocks until the slowest player finishes their animation.

Source

fn decide_cost_part( &mut self, _player: PlayerId, _source: CardId, _cost_part: &CostPart, _game: &GameState, ) -> Option<PaymentDecision>

Decide how to pay a single cost part.

Source

fn pays_right_after_decision(&self) -> bool

Whether this agent pays each cost part immediately after deciding (true) or batches all decisions first, then pays (false).

Source

fn order_cost_parts(&mut self, parts: Vec<CostPart>) -> Vec<CostPart>

Reorder cost parts before payment (for human players to choose payment order).

Source

fn specify_mana_combo( &mut self, _player: PlayerId, available_colors: &[String], amount: usize, _source: Option<CardId>, _express_choice: Option<u16>, ) -> Vec<String>

Specify mana color distribution for combo/any mana production. available_colors lists which colors can be produced. amount is the total mana to distribute across colors. Returns a list of color letters (e.g. [“W”, “W”, “U”]) totaling amount. Default: picks the color with least mana in pool for each unit (AI heuristic).

Source

fn notify(&mut self, _event: GameNotification)

Receive engine notifications for UI/game-log observers. Default is a no-op so simple agents do not need to handle them.

Source

fn choose_single_replacement_effect( &mut self, _player: PlayerId, _descriptions: &[String], ) -> usize

Choose which replacement effect to apply when multiple effects match the same event.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§