Core Types

This document provides a reference for the fundamental data types used in Rummage.

Game State Types

Phase and Step Types

#![allow(unused)]
fn main() {
/// The phases of a Magic: The Gathering turn
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Reflect)]
pub enum Phase {
    /// Beginning phase
    Beginning,
    /// First main phase
    PreCombatMain,
    /// Combat phase
    Combat,
    /// Second main phase
    PostCombatMain,
    /// Ending phase
    Ending,
}

/// The steps within phases of a Magic: The Gathering turn
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Reflect)]
pub enum Step {
    /// Beginning phase - Untap step
    Untap,
    /// Beginning phase - Upkeep step
    Upkeep,
    /// Beginning phase - Draw step
    Draw,
    /// Combat phase - Beginning of combat step
    BeginningOfCombat,
    /// Combat phase - Declare attackers step
    DeclareAttackers,
    /// Combat phase - Declare blockers step
    DeclareBlockers,
    /// Combat phase - First strike damage step (only if needed)
    FirstStrikeDamage,
    /// Combat phase - Combat damage step
    CombatDamage,
    /// Combat phase - End of combat step
    EndOfCombat,
    /// Ending phase - End step
    End,
    /// Ending phase - Cleanup step
    Cleanup,
}
}

Zone Types

#![allow(unused)]
fn main() {
/// Game zones in Magic: The Gathering
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Reflect)]
pub enum ZoneType {
    /// The library (deck) zone
    Library,
    /// The hand zone
    Hand,
    /// The battlefield zone (permanents in play)
    Battlefield,
    /// The graveyard zone (discard pile)
    Graveyard,
    /// The stack zone (spells and abilities being cast/activated)
    Stack,
    /// The exile zone (removed from game)
    Exile,
    /// The command zone (for commanders, emblems, etc.)
    Command,
    /// The sideboard zone (unused in Commander)
    Sideboard,
}
}

Card Types

Card Type System

#![allow(unused)]
fn main() {
/// Types of Magic: The Gathering cards
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Reflect)]
pub struct CardTypes {
    /// Card super types (Legendary, Basic, etc.)
    pub super_types: HashSet<String>,
    /// Card types (Creature, Instant, etc.)
    pub card_types: HashSet<String>,
    /// Card sub types (Human, Wizard, Equipment, etc.)
    pub sub_types: HashSet<String>,
}

impl CardTypes {
    /// Constant for the Creature type
    pub const TYPE_CREATURE: Self = Self { 
        card_types: HashSet::from(["Creature".to_string()]),
        super_types: HashSet::new(),
        sub_types: HashSet::new(),
    };
    
    /// Create a new creature type
    pub fn new_creature(creature_types: Vec<String>) -> Self {
        Self {
            card_types: HashSet::from(["Creature".to_string()]),
            super_types: HashSet::new(),
            sub_types: HashSet::from_iter(creature_types),
        }
    }
    
    /// Check if this is a creature
    pub fn is_creature(&self) -> bool {
        self.card_types.contains("Creature")
    }
    
    /// Get creature types
    pub fn get_creature_types(&self) -> Vec<String> {
        if !self.is_creature() {
            return Vec::new();
        }
        self.sub_types.iter().cloned().collect()
    }
    
    // Similar methods for other card types
}
}

Card Details

#![allow(unused)]
fn main() {
/// Details specific to different card types
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Reflect)]
pub enum CardDetails {
    /// Creature card details
    Creature(CreatureCard),
    /// Planeswalker card details
    Planeswalker { loyalty: i32 },
    /// Instant card details
    Instant(SpellCard),
    /// Sorcery card details
    Sorcery(SpellCard),
    /// Enchantment card details
    Enchantment(EnchantmentCard),
    /// Artifact card details
    Artifact(ArtifactCard),
    /// Land card details
    Land(LandCard),
    /// Other card types
    Other,
}

/// Creature card details
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Reflect)]
pub struct CreatureCard {
    /// Creature's power
    pub power: i32,
    /// Creature's toughness
    pub toughness: i32,
    /// Creature's type
    pub creature_type: CreatureType,
}
}

Mana System

Mana Types

#![allow(unused)]
fn main() {
/// Representation of mana in Magic: The Gathering
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Reflect)]
pub struct Mana {
    /// Generic/colorless mana
    pub generic: u32,
    /// White mana
    pub white: u32,
    /// Blue mana
    pub blue: u32,
    /// Black mana
    pub black: u32,
    /// Red mana
    pub red: u32,
    /// Green mana
    pub green: u32,
}

impl Mana {
    /// Create a new Mana value
    pub fn new(generic: u32, white: u32, blue: u32, black: u32, red: u32, green: u32) -> Self {
        Self {
            generic,
            white,
            blue,
            black,
            red,
            green,
        }
    }
    
    /// Calculate the converted mana cost (total mana value)
    pub fn converted_mana_cost(&self) -> u32 {
        self.generic + self.white + self.blue + self.black + self.red + self.green
    }
    
    /// Get the amount of a specific color
    pub fn colored_mana_cost(&self, color: Color) -> u32 {
        match color {
            Color::Generic => self.generic,
            Color::White => self.white,
            Color::Blue => self.blue,
            Color::Black => self.black,
            Color::Red => self.red,
            Color::Green => self.green,
        }
    }
}

/// Color in Magic: The Gathering
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Reflect)]
pub enum Color {
    /// Generic/colorless mana
    Generic,
    /// White mana
    White,
    /// Blue mana
    Blue,
    /// Black mana
    Black,
    /// Red mana
    Red,
    /// Green mana
    Green,
}
}

Keyword Abilities

#![allow(unused)]
fn main() {
/// Keyword abilities in Magic: The Gathering
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Reflect)]
pub enum KeywordAbility {
    /// Flying
    Flying,
    /// First Strike
    FirstStrike,
    /// Double Strike
    DoubleStrike,
    /// Deathtouch
    Deathtouch,
    /// Lifelink
    Lifelink,
    /// Haste
    Haste,
    /// Hexproof
    Hexproof,
    /// Indestructible
    Indestructible,
    /// Menace
    Menace,
    /// Protection
    Protection,
    /// Reach
    Reach,
    /// Trample
    Trample,
    /// Vigilance
    Vigilance,
    // And many more...
}

/// Container for a card's keyword abilities
#[derive(Debug, Clone, Default, Serialize, Deserialize, Reflect)]
pub struct KeywordAbilities {
    /// Set of abilities this card has
    pub abilities: HashSet<KeywordAbility>,
    /// Values for abilities that need them (e.g., "Protection from black")
    pub ability_values: HashMap<KeywordAbility, String>,
}

impl KeywordAbilities {
    /// Parse keywords from rules text
    pub fn from_rules_text(rules_text: &str) -> Self {
        // Implementation that parses keywords from rules text
        let mut abilities = HashSet::new();
        let mut ability_values = HashMap::new();
        
        // Example parsing logic
        if rules_text.contains("Flying") {
            abilities.insert(KeywordAbility::Flying);
        }
        
        if rules_text.contains("First strike") {
            abilities.insert(KeywordAbility::FirstStrike);
        }
        
        // Handle Protection keyword with value
        if let Some(protection_text) = rules_text.find("Protection ") {
            abilities.insert(KeywordAbility::Protection);
            // Extract the protection value (e.g., "from black")
            // and store it in ability_values
        }
        
        Self { abilities, ability_values }
    }
}
}

Stack and Effects

#![allow(unused)]
fn main() {
/// An item on the stack
#[derive(Debug, Clone, Serialize, Deserialize, Reflect)]
pub struct StackItem {
    /// Unique identifier
    pub id: Uuid,
    /// Source entity of the stack item
    pub source: Entity,
    /// Controller of the stack item
    pub controller: Entity,
    /// Type of stack item
    pub item_type: StackItemType,
    /// Target entities
    pub targets: Vec<Entity>,
    /// Effects to apply when resolved
    pub effects: Vec<Effect>,
}

/// Types of stack items
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Reflect)]
pub enum StackItemType {
    /// A spell being cast
    Spell,
    /// An activated ability
    ActivatedAbility,
    /// A triggered ability
    TriggeredAbility,
}

/// An effect that can be applied to the game state
#[derive(Debug, Clone, Serialize, Deserialize, Reflect)]
pub enum Effect {
    /// Deal damage to target(s)
    DealDamage {
        /// Amount of damage
        amount: u32,
        /// Source of the damage
        source: Entity,
    },
    /// Draw cards
    DrawCards {
        /// Number of cards to draw
        count: u32,
        /// Player who draws the cards
        player: Entity,
    },
    /// Add mana to a player's mana pool
    AddMana {
        /// Mana to add
        mana: Mana,
        /// Player to receive the mana
        player: Entity,
    },
    /// Destroy target permanent(s)
    DestroyPermanent {
        /// Whether the permanent can be regenerated
        can_regenerate: bool,
    },
    /// Exile target(s)
    Exile {
        /// Return zone if temporary
        return_zone: Option<ZoneType>,
        /// When to return (e.g., end of turn)
        return_condition: Option<ReturnCondition>,
    },
    // And many more effect types...
}
}

Game Actions

#![allow(unused)]
fn main() {
/// Actions that players can take
#[derive(Debug, Clone, Serialize, Deserialize, Reflect)]
pub enum PlayerAction {
    /// Play a land
    PlayLand {
        /// The land card to play
        card: Entity,
    },
    /// Cast a spell
    CastSpell {
        /// The spell to cast
        card: Entity,
        /// Targets for the spell
        targets: Vec<Entity>,
        /// Mana to spend
        mana: Mana,
    },
    /// Activate an ability
    ActivateAbility {
        /// Source of the ability
        source: Entity,
        /// Index of the ability on the source
        ability_index: usize,
        /// Targets for the ability
        targets: Vec<Entity>,
        /// Mana to spend
        mana: Option<Mana>,
    },
    /// Attack with creatures
    DeclareAttackers {
        /// Attacking creatures
        attackers: Vec<(Entity, Entity)>, // (Attacker, Defender)
    },
    /// Block with creatures
    DeclareBlockers {
        /// Blocking assignments
        blockers: Vec<(Entity, Entity)>, // (Blocker, Attacker)
    },
    /// Pass priority
    PassPriority,
    /// Mulligan
    Mulligan,
    /// Keep hand
    KeepHand,
    /// Concede game
    Concede,
}
}

Network Types

#![allow(unused)]
fn main() {
/// Network action to synchronize across clients
#[derive(Debug, Clone, Serialize, Deserialize, Reflect)]
pub struct NetworkAction {
    /// Player who initiated the action
    pub player_id: u64,
    /// The action taken
    pub action: PlayerAction,
    /// Timestamp for ordering
    pub timestamp: f64,
    /// Sequence number for this client
    pub sequence: u32,
}

/// Rollback information for network synchronization
#[derive(Debug, Clone, Serialize, Deserialize, Reflect)]
pub struct RollbackInfo {
    /// Snapshot ID to roll back to
    pub snapshot_id: Uuid,
    /// Reason for rollback
    pub reason: RollbackReason,
    /// New actions to apply after rollback
    pub actions: Vec<NetworkAction>,
}

/// Reasons for a rollback
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Reflect)]
pub enum RollbackReason {
    /// State desynchronization detected
    StateMismatch,
    /// Random number generator desynchronization
    RngMismatch,
    /// Network latency compensation
    LatencyCompensation,
    /// Action validation failure
    InvalidAction,
}
}

Event Types

#![allow(unused)]
fn main() {
/// Event triggered when a phase changes
#[derive(Event, Debug, Clone)]
pub struct PhaseChangeEvent {
    /// The new phase
    pub new_phase: Phase,
    /// The new step (if applicable)
    pub new_step: Option<Step>,
    /// The previous phase
    pub old_phase: Phase,
    /// The previous step (if applicable)
    pub old_step: Option<Step>,
}

/// Event triggered when damage is dealt
#[derive(Event, Debug, Clone)]
pub struct DamageEvent {
    /// Entity receiving damage
    pub target: Entity,
    /// Entity dealing damage
    pub source: Entity,
    /// Amount of damage
    pub amount: u32,
    /// Whether the damage is combat damage
    pub is_combat_damage: bool,
}

/// Event triggered when a card changes zones
#[derive(Event, Debug, Clone)]
pub struct ZoneChangeEvent {
    /// The card that changed zones
    pub card: Entity,
    /// The source zone
    pub from: ZoneType,
    /// The destination zone
    pub to: ZoneType,
    /// The entity that owns the destination zone
    pub to_owner: Entity,
    /// Position in the destination zone (if applicable)
    pub position: Option<usize>,
}

/// Event triggered when a snapshot should be taken
#[derive(Event, Debug, Clone)]
pub enum SnapshotEvent {
    /// Take a new snapshot
    Take,
    /// Apply a specific snapshot
    Apply(Uuid),
    /// Save the current state to disk
    Save(String),
    /// Load a state from disk
    Load(String),
}
}

Integration Types

#![allow(unused)]
fn main() {
/// Configuration for the game engine
#[derive(Resource, Debug, Clone, Serialize, Deserialize)]
pub struct GameConfig {
    /// Number of players
    pub player_count: usize,
    /// Starting life total
    pub starting_life: u32,
    /// Whether commander damage is enabled
    pub enable_commander_damage: bool,
    /// Starting hand size
    pub starting_hand_size: usize,
    /// Maximum hand size
    pub maximum_hand_size: usize,
    /// Number of cards to draw per turn
    pub draw_per_turn: usize,
    /// Random seed for deterministic gameplay
    pub random_seed: Option<u64>,
}

/// Configuration for snapshots
#[derive(Resource, Debug, Clone)]
pub struct SnapshotConfig {
    /// Whether to automatically take snapshots on turn change
    pub auto_snapshot_on_turn: bool,
    /// Whether to automatically take snapshots on phase change
    pub auto_snapshot_on_phase: bool,
    /// Maximum number of snapshots to process per frame
    pub max_snapshots_per_frame: usize,
    /// Compression level for snapshots (0-9)
    pub compression_level: u8,
}
}