State-Based Actions in MTG
Overview
State-Based Actions (SBAs) are one of the foundational mechanisms of Magic: The Gathering's rules system. They serve as automatic checks that the game performs regularly to ensure game rules are properly enforced without requiring explicit player actions. These checks occur whenever a player would receive priority and before any player actually receives priority.
Core Functionality
State-based actions handle many crucial game state validations:
-
Player loss conditions:
- A player with 0 or less life loses the game
- A player attempting to draw from an empty library loses the game
- A player with 10 or more poison counters loses the game (in formats where poison counters are relevant)
-
Creature conditions:
- Creatures with toughness 0 or less are put into their owner's graveyard
- Creatures with damage marked on them greater than or equal to their toughness are destroyed
- Creatures that have been dealt damage by a source with deathtouch are destroyed
-
Permanent-specific rules:
- Planeswalker with no loyalty counters is put into its owner's graveyard
- Auras that aren't attached to anything or attached illegally are put into their owner's graveyard
- Equipment or Fortifications that are attached illegally become unattached
- Legendary permanents with the same name are put into their owner's graveyard except the most recently played one
-
Token and counter rules:
- A token that has left the battlefield ceases to exist
- If a permanent has both +1/+1 and -1/-1 counters on it, they cancel out in pairs
Implementation
The state-based actions system is implemented as a collection of systems that run between steps and phases:
#![allow(unused)] fn main() { #[derive(Resource)] pub struct StateBasedActionSystem { // Configuration for SBA processing pub enabled: bool, pub last_check_time: Duration, pub check_frequency: Duration, // Tracking for specific SBAs pub pending_legendary_checks: Vec<Entity>, pub pending_destruction: Vec<Entity>, pub pending_life_checks: Vec<Entity>, } // Systems that implement specific checks pub fn check_player_loss_conditions(/* ... */); pub fn check_creature_destruction(/* ... */); pub fn check_attachment_validity(/* ... */); pub fn check_legendary_rule(/* ... */); pub fn check_token_existence(/* ... */); pub fn check_counter_interactions(/* ... */); }
Application Order
State-based actions are applied in a specific order, but all applicable state-based actions are performed simultaneously as a single event. If performing state-based actions creates new conditions for state-based actions, those new state-based actions will be checked in the next round of checks.
This is especially important for situations like:
- A player at 0 life with a creature dying simultaneously
- Multiple legendary permanents entering the battlefield at the same time
- Creatures with damage marked receiving -X/-X effects
Multiplayer Considerations
In multiplayer games:
- State-based actions are checked simultaneously for all players and permanents
- When a player leaves the game, all cards they own leave the game
- Objects controlled by a player who left the game are exiled, unless they're controlled by a different player's ongoing effect
Optimization in Rummage
The SBA system in Rummage is optimized to:
- Only check relevant game objects (using spatial partitioning where appropriate)
- Use efficient data structures to track pending actions
- Batch similar checks where possible
- Cache results when appropriate
- Minimize performance impact during complex game states
Related Documentation
- Turn Structure: When state-based actions are checked during the turn
- Zones: How state-based actions interact with game zones
- Combat: Combat-specific state-based actions