Files
systemic-game-design-course/course/04-interceptors/scenarios.md
T

63 lines
5.3 KiB
Markdown

# Module 4 scenarios: Interceptors and "trigger twice"
Each heading is a test name. The Rust test lives in `tests/rust/test_04.rs` and the TypeScript test in `tests/ts/test_04.test.ts`; both state exactly what is written here. Player 0 is the first player, player 1 the second. Every minion in these tests belongs to player 0 and is summoned in the order listed, so the first one listed has the lowest order of play and stands furthest left. Each test calls `clearLog()` after its setup, so `log()` holds only the events of the action under test. Every test starts with `newGame` and a deck of 5 `Test Filler` for player 0.
Cards used (text from `course/catalog.json`):
- `Baron Rivendare`, 1/7: "Your minions trigger their Deathrattles twice."
- `Loot Hoarder`, 2/1: "Deathrattle: Draw a card."
- `Harvest Golem`, 2/3: "Deathrattle: Summon a 2/1 Damaged Golem."
- `Damaged Golem`, 2/1, no text. Only Harvest Golem creates it.
- `Novice Engineer`, 1/1: "Battlecry: Draw a card."
- `Whirlwind`, spell: "Deal 1 damage to ALL minions."
- `Twisting Nether`, spell: "Destroy all minions and locations." The course has no locations, so it destroys all minions (the Module 3 Expansion Drop card).
- `Test Filler` (fictional), 1/1, no text. Used to fill decks.
A trigger multiplier is an aura: data on a card that says "triggers of this kind, belonging to my owner's minions, activate N times". The set of active multipliers is read at two points only: when a minion is summoned, and in the Aura Update (Other) that follows each Death Creation Step. A queued trigger reads that set when it starts to resolve and then activates that many times in a row, recording `Triggered{source, trigger}` for each activation, before the next queued trigger starts. Baron Rivendare's multiplier does not stack: two Barons double, they do not quadruple.
### test_04_baron_doubles
- Setup: Summon `Baron Rivendare` (id B), then `Loot Hoarder` (id H), then `Harvest Golem` (id G). `dealDamage(G, 2)`, which leaves G at 1 Health.
- Action: player 0 casts `Whirlwind`.
- Assertions:
- `hand(0)` has 2 cards; call them C1 and C2, in hand order. The log has exactly 2 `Summoned` events; call their ids D1 and D2, in log order.
- The log is exactly, in this order: `SpellCast{card: "Whirlwind"}`, `Damaged{target: B, amount: 1}`, `Damaged{target: H, amount: 1}`, `Damaged{target: G, amount: 1}`, `Destroyed{id: H}`, `Destroyed{id: G}`, `DeathPhase{round: 1}`, `Triggered{source: H, trigger: "deathrattle"}`, `Drew{player: 0, id: C1}`, `Triggered{source: H, trigger: "deathrattle"}`, `Drew{player: 0, id: C2}`, `Triggered{source: G, trigger: "deathrattle"}`, `Summoned{id: D1}`, `Triggered{source: G, trigger: "deathrattle"}`, `Summoned{id: D2}`. Each Deathrattle is queued once and activates twice back to back: the Hoarder's two activations both finish before the Golem's first one starts.
- `nameOf(D1)` and `nameOf(D2)` are `"Damaged Golem"`.
- `board(0)` has 3 minions: B first, then D1 and D2 in either order. Both Damaged Golems appear where the Golem stood; this test doesn't fix their order relative to each other.
- `health(B)` is 6: Baron survives the Whirlwind, so his aura is still active when the Death Phase starts.
### test_04_simultaneous_death_not_doubled
- Setup: Summon `Baron Rivendare` (id B), then `Loot Hoarder` (id H).
- Action: player 0 casts `Twisting Nether`.
- Assertions:
- `hand(0)` has exactly 1 card.
- The log contains exactly one `Triggered{source: H, trigger: "deathrattle"}`.
- `zoneOf(B)` and `zoneOf(H)` are graveyard.
- Baron and the Hoarder leave play in the same Death Creation Step. The Aura Update (Other) after that step finds no Baron in play, so the Hoarder's Deathrattle activates once.
### test_04_two_barons_do_not_stack
- Setup: Summon `Baron Rivendare` (id B1), then another `Baron Rivendare` (id B2), then `Loot Hoarder` (id H).
- Action: `dealDamage(H, 1)`.
- Assertions:
- `hand(0)` has 2 cards; call them C1 and C2, in hand order.
- The log is exactly, in this order: `Damaged{target: H, amount: 1}`, `Destroyed{id: H}`, `DeathPhase{round: 1}`, `Triggered{source: H, trigger: "deathrattle"}`, `Drew{player: 0, id: C1}`, `Triggered{source: H, trigger: "deathrattle"}`, `Drew{player: 0, id: C2}`. Two Barons give two activations, not three or four.
### test_04_aura_timing_order
- Setup: Summon `Loot Hoarder` (id H), then `Baron Rivendare` (id B). This time the Hoarder is older than Baron.
- Action: player 0 casts `Twisting Nether`.
- Assertions:
- `hand(0)` has exactly 1 card; call it C.
- The log is exactly, in this order: `SpellCast{card: "Twisting Nether"}`, `Destroyed{id: H}`, `Destroyed{id: B}`, `DeathPhase{round: 1}`, `Triggered{source: H, trigger: "deathrattle"}`, `Drew{player: 0, id: C}`. The Hoarder's Death Event is created before Baron's, while Baron is still on the board, but `Destroyed{id: B}` comes before the Hoarder's only `Triggered`: the multiplier is read after the whole Death Creation Step, in the Aura Update (Other), not while each Death Event is created.
### test_04_battlecry_on_play
- Setup: `addToHand("Novice Engineer", 0)` (id E).
- Action: `play(E)`.
- Assertions:
- `hand(0)` has exactly 1 card; call it C.
- The log is exactly, in this order: `Summoned{id: E}`, `Triggered{source: E, trigger: "battlecry"}`, `Drew{player: 0, id: C}`. Playing a minion from hand puts it on the board, then its Battlecry resolves.
- `zoneOf(E)` is board and `board(0)` is `[E]`.