MTG Targeting Rules
This document outlines the rules for targeting in Magic: The Gathering as implemented in Rummage.
Core Targeting Rules
According to the Magic: The Gathering Comprehensive Rules:
- The term "target" is used to describe an object that a spell or ability will affect.
- An object that requires targets is put on the stack with those targets already chosen.
- Targets are always declared as part of casting a spell or activating an ability.
- A target must be valid both when declared and when the spell or ability resolves.
Valid Targets
A valid target must:
- Meet any specific requirements of the targeting effect
- Be in the appropriate zone (usually on the battlefield)
- Not have hexproof or shroud (relative to the controller of the targeting effect)
- Not have protection from the relevant quality of the targeting effect
Implementation
In Rummage, targeting is implemented through several components:
#![allow(unused)] fn main() { pub enum TargetType { Player, Creature, Permanent, AnyTarget, // Player or creature // ...other target types } pub struct TargetRequirement { pub target_type: TargetType, pub count: TargetCount, pub additional_requirements: Vec<Box<dyn TargetFilter>>, } }
Targeting Phases
The targeting process has several phases:
- Declaration: The player declares targets for a spell or ability
- Validation: The system validates that the targets are legal
- Resolution: When the spell or ability resolves, targets are checked again
- Effect Application: The effect is applied to valid targets
Illegal Targets
If a target becomes illegal before a spell or ability resolves:
- The spell or ability will still resolve
- The effect will not be applied to the illegal target
- If all targets are illegal, the spell or ability is countered by game rules
UI Integration
The targeting rules integrate with the UI through:
- Targeting System: UI implementation of targeting
- Drag and Drop: Using drag interactions for targeting
Examples
Single Target Spell
#![allow(unused)] fn main() { // Lightning Bolt implementation let lightning_bolt = Card::new("Lightning Bolt") .with_cost(Mana::new(0, 1, 0, 0, 0, 0)) .with_target_requirement(TargetRequirement { target_type: TargetType::AnyTarget, count: TargetCount::Exactly(1), additional_requirements: vec![], }) .with_effect(|game, targets| { for target in targets { game.deal_damage(target, 3, DamageType::Spell); } }); }
Multiple Targets Spell
#![allow(unused)] fn main() { // Electrolyze implementation let electrolyze = Card::new("Electrolyze") .with_cost(Mana::new(0, 1, 0, 1, 0, 0)) .with_target_requirement(TargetRequirement { target_type: TargetType::AnyTarget, count: TargetCount::UpTo(2), additional_requirements: vec![], }) .with_effect(|game, targets| { for target in targets { game.deal_damage(target, 1, DamageType::Spell); } game.draw_cards(game.active_player, 1); }); }