The game view
A StateUpdate carries one field, gameView — a complete
GameViewDto snapshot of the game. It is the only carrier of authoritative
game state: the client throws away its previous view and re-renders the board
from each one.
GameViewDto
Section titled “GameViewDto”The whole-game snapshot: turn structure, both players, the battlefield, the stack, and game-end state.
interface GameViewDto { gameId: string; turn: number; step: string; combatAssignments: Array<CombatAssignmentDto>; activePlayerId: string; priorityPlayerId: string; players: Array<PlayerDto>; battlefield: Array<CardDto>; stack: Array<StackObjectDto>; gameOver: boolean; winnerId: string | null; concededPlayerIds: Array<string>; monarchId: string | null; initiativeHolderId: string | null;}#[serde(rename_all = "camelCase")]pub struct GameViewDto { pub game_id: String, pub turn: u32, pub step: String, pub combat_assignments: Vec<CombatAssignmentDto>, pub active_player_id: String, pub priority_player_id: String, pub players: Vec<PlayerDto>, pub battlefield: Vec<CardDto>, pub stack: Vec<StackObjectDto>, pub game_over: bool, pub winner_id: Option<String>, #[serde(default)] pub conceded_player_ids: Vec<String>, pub monarch_id: Option<String>, pub initiative_holder_id: Option<String>,}
References: CardDto , CombatAssignmentDto , PlayerDto , StackObjectDto
PlayerDto
Section titled “PlayerDto”One player’s public and private state — life, counters, and the cards in each of their zones.
interface PlayerDto { id: string; name: string; isHuman: boolean; life: number; poison: number; hand: Array<CardDto>; graveyard: Array<CardDto>; exile: Array<CardDto>; commandZone: Array<CardDto>; libraryCount: number; manaPool: Record<string, number>; commanderDamage: Record<string, number>; energyCounters: number; radiationCounters: number; hasCityBlessing: boolean; ringLevel: number; speed: number;}#[serde(rename_all = "camelCase")]pub struct PlayerDto { pub id: String, pub name: String, pub is_human: bool, pub life: i32, pub poison: i32, pub hand: Vec<CardDto>, pub graveyard: Vec<CardDto>, pub exile: Vec<CardDto>, pub command_zone: Vec<CardDto>, pub library_count: usize, pub mana_pool: HashMap<String, i32>, pub commander_damage: HashMap<String, i32>, pub energy_counters: i32, pub radiation_counters: i32, pub has_city_blessing: bool, pub ring_level: i32, pub speed: i32,}
References: CardDto
CardDto
Section titled “CardDto”The engine’s snapshot of a single card — every zone holds these. Only id and
name are needed to round-trip a choice; the rest drives richer rendering. The
prompt pages that show cards reference this same type.
interface CardDto { id: string; name: string; setCode: string; cardNumber: string; color: string; manaCost: string; cmc: number; types: Array<string>; subtypes: Array<string>; supertypes: Array<string>; power: string | null; toughness: string | null; basePower?: number; baseToughness?: number; text: string; controllerId: string; ownerId: string; zoneId: string; tapped: boolean; isCrewed: boolean; isAttacking: boolean; attackingPlayerId?: string; keywords: Array<string>; counters: Record<string, number>; damage: number; summoningSick: boolean; isToken: boolean; isCopy: boolean; isDoubleFaced: boolean; isTransformed: boolean; isFaceDown: boolean; isBestowed: boolean; phasedOut: boolean; exerted: boolean; isRingBearer: boolean; attachedTo?: string; attachmentIds: Array<string>; flashbackCost?: string; kickerCost?: string; effectiveManaCost?: string; madnessCost?: string; isMadnessExiled: boolean; isPlotted: boolean; isWarpExiled: boolean; foil: boolean; wouldDieInCombat: boolean;}#[serde(rename_all = "camelCase", default)]pub struct CardDto { pub id: String, pub name: String, pub set_code: String, pub card_number: String, pub color: String, pub mana_cost: String, pub cmc: i32, pub types: Vec<String>, pub subtypes: Vec<String>, pub supertypes: Vec<String>, pub power: Option<String>, pub toughness: Option<String>, #[serde(skip_serializing_if = "Option::is_none")] pub base_power: Option<i32>, #[serde(skip_serializing_if = "Option::is_none")] pub base_toughness: Option<i32>, pub text: String, pub controller_id: String, pub owner_id: String, pub zone_id: String, pub tapped: bool, #[serde(default, skip_serializing_if = "std::ops::Not::not")] pub is_crewed: bool, #[serde(default, skip_serializing_if = "std::ops::Not::not")] pub is_attacking: bool, #[serde(default, skip_serializing_if = "Option::is_none")] pub attacking_player_id: Option<String>, pub keywords: Vec<String>, pub counters: HashMap<String, i32>, pub damage: i32, pub summoning_sick: bool, pub is_token: bool, #[serde(default, skip_serializing_if = "std::ops::Not::not")] pub is_copy: bool, pub is_double_faced: bool, pub is_transformed: bool, pub is_face_down: bool, pub is_bestowed: bool, pub phased_out: bool, pub exerted: bool, #[serde(default, skip_serializing_if = "std::ops::Not::not")] pub is_ring_bearer: bool, #[serde(skip_serializing_if = "Option::is_none")] pub attached_to: Option<String>, #[serde(default, skip_serializing_if = "Vec::is_empty")] pub attachment_ids: Vec<String>, #[serde(skip_serializing_if = "Option::is_none")] pub flashback_cost: Option<String>, #[serde(skip_serializing_if = "Option::is_none")] pub kicker_cost: Option<String>, #[serde(skip_serializing_if = "Option::is_none")] pub effective_mana_cost: Option<String>, #[serde(skip_serializing_if = "Option::is_none")] pub madness_cost: Option<String>, #[serde(default, skip_serializing_if = "std::ops::Not::not")] pub is_madness_exiled: bool, #[serde(default, skip_serializing_if = "std::ops::Not::not")] pub is_plotted: bool, #[serde(default, skip_serializing_if = "std::ops::Not::not")] pub is_warp_exiled: bool, #[serde(default, skip_serializing_if = "std::ops::Not::not")] pub foil: bool, #[serde(default, skip_serializing_if = "std::ops::Not::not")] pub would_die_in_combat: bool,}CombatAssignmentDto
Section titled “CombatAssignmentDto”A declared block: which blocker is assigned to which attacker.
interface CombatAssignmentDto { blockerId: string; attackerId: string;}#[serde(rename_all = "camelCase")]pub struct CombatAssignmentDto { pub blocker_id: String, pub attacker_id: String,}StackObjectDto
Section titled “StackObjectDto”A spell or ability currently on the stack, with its targets.
interface StackObjectDto { id: string; sourceId: string; controllerId: string; name: string; text: string; setCode: string; cardNumber: string; isPermanentSpell: boolean; isCasting: boolean; targets: Array<StackTargetDto>;}#[serde(rename_all = "camelCase", default)]pub struct StackObjectDto { pub id: String, pub source_id: String, pub controller_id: String, pub name: String, pub text: String, pub set_code: String, pub card_number: String, pub is_permanent_spell: bool, pub is_casting: bool, pub targets: Vec<StackTargetDto>,}
References: StackTargetDto
StackTargetDto
Section titled “StackTargetDto”One target chosen by a StackObjectDto, tagged with the TargetingIntent
the engine inferred for it.
interface StackTargetDto { kind: StackTargetKindDto; id: string; nodeIndex: number; targetIndex: number; hostile: boolean; intent: TargetingIntent;}#[serde(rename_all = "camelCase")]pub struct StackTargetDto { pub kind: StackTargetKindDto, pub id: String, pub node_index: u32, pub target_index: u32, pub hostile: bool, pub intent: TargetingIntent,}
References: StackTargetKindDto , TargetingIntent
StackTargetKindDto
Section titled “StackTargetKindDto”Which id space a StackTargetDto points into — a card, a
player, or another object on the stack.
type StackTargetKindDto = "card" | "player" | "stack";#[serde(rename_all = "camelCase")]pub enum StackTargetKindDto { Card, Player, Stack,}TargetingIntent
Section titled “TargetingIntent”A semantic hint describing what an effect intends to do to its target — the
client uses it to pre-highlight sensible targets. Carried by StackTargetDto
and by the targeting prompts.
type TargetingIntent = | "damage" | "destroy" | "sacrifice" | "exile" | "bounce" | "mill" | "discard" | "counter" | "tap" | "untap" | "copy" | "buff" | "debuff" | "heal" | "loseLife" | "reveal" | "draw" | "gainControl" | "fight" | "attach" | "attack" | "block" | "hostile" | "friendly"; Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize, TS, strum_macros::Display,)]#[serde(rename_all = "camelCase")]pub enum TargetingIntent { #[default] Damage, Destroy, Sacrifice, Exile, Bounce, Mill, Discard, Counter, Tap, Untap, Copy, Buff, Debuff, Heal, LoseLife, Reveal, Draw, GainControl, Fight, Attach, Attack, Block, Hostile, Friendly,}