Files
systemic-game-design-course/course/02-action-queue/scenarios.md
T
Lucas WintherandClaude Opus 5.5 8a4eba1948 feat: module 03 death step
Deferred death: damage and destroy only mark minions; the Death Creation
Step removes them when the outermost Phase ends, and Death Phases resolve
Deathrattles in order of play until no new deaths occur. Deathrattle
summons use the board position the Death Event remembered. Harness adds
destroy(target). Expansion Drop: Twisting Nether as content only.

test_02_mortally_wounded_still_triggers no longer asserts the Acolyte is
still on the board: from Module 3 on it leaves at the end of the Sequence,
and verify-references runs Module 2's tests against the Module 3 reference.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 02:42:12 +01:00

56 lines
3.2 KiB
Markdown

# Module 2 scenarios: The action queue, depth-first
Each heading is a test name. The Rust test lives in `tests/rust/test_02.rs` and the TypeScript test in `tests/ts/test_02.test.ts`; both state exactly what is written here. Player 0 is the first player, player 1 the second. Every minion in these tests is summoned for player 0, in the order listed, so the first one listed has the lowest order of play. Each test calls `clearLog()` after its setup, so `log()` holds only the events of the action under test.
Cards used (text from `course/catalog.json`):
- `Armorsmith`, 1/4: "Whenever a friendly minion takes damage, gain 1 Armor."
- `Acolyte of Pain`, 1/4: "Whenever this minion takes damage, draw a card."
- `Whirlwind`, spell: "Deal 1 damage to ALL minions."
- `Test Echo` (fictional), 1/5: "Whenever a minion takes damage, deal 1 damage to the enemy hero." Player 0's enemy hero is `hero(1)`.
- `Test Reactor` (fictional), 1/5: "Whenever a hero takes damage, gain +1 Attack."
- `Test Filler` (fictional), 1/1, no text. Used to fill decks.
Heroes have 30 Health and 0 Armor at the start of a game.
### test_02_aoe_damage_then_triggers
- Setup: `newGame` with a deck of 5 `Test Filler` for each player. Summon `Armorsmith` (id S), then `Acolyte of Pain` (id A).
- Action: player 0 casts `Whirlwind`.
- Assertions:
- The log has two `Damaged` events, for S then A (area damage is created in order of play), each of amount 1.
- Every `Damaged` event comes before every `Triggered` event in the log.
- `Triggered` events: S appears twice (once for each damaged friendly minion, itself included), A once. The test does not check how those three are interleaved.
- `armor(0)` is 2.
- `hand(0)` has 1 card.
### test_02_mortally_wounded_still_triggers
- Setup: `newGame` with a deck of 5 `Test Filler` for player 0. Summon `Acolyte of Pain` (id A). `dealDamage(A, 3)`, which leaves A at 1 Health and draws one card. Record `hand(0)`'s length as N.
- Action: player 0 casts `Whirlwind`.
- Assertions:
- The log contains `Triggered{source: A, trigger: "damaged"}` and a `Drew` event for player 0.
- `hand(0)` has N + 1 cards.
- `health(A)` is 0.
- The test does not check `zoneOf(A)`. Module 2 has no death step, so A stays on the board at 0 Health. Module 3 adds the step that removes A once the Sequence's reactions have resolved, and this test must keep passing then.
### test_02_depth_first_nesting
- Setup: an empty game. Summon `Test Echo` (id E), then `Armorsmith` (id S), then `Test Reactor` (id R).
- Action: `dealDamage(S, 1)`.
- Assertions:
- The sources of the `Triggered` events, in log order, are E, R, S. E and S both respond to S taking damage. E resolves first (older), and the hero damage it deals makes R trigger and resolve before S gets its turn.
- The `StatsChanged` event for R comes before the `ArmorGained` event in the log.
- `attack(R)` is 2.
- `armor(0)` is 1.
- `health(hero(1))` is 29.
### test_02_empty_deck_draw_is_fatigue
- Setup: an empty game (no decks). Summon `Acolyte of Pain` (id A).
- Action: `dealDamage(A, 1)`.
- Assertions:
- The log is exactly `Damaged{target: A, amount: 1}`, `Triggered{source: A, trigger: "damaged"}`, `Fatigue{player: 0}`.
- `hand(0)` is empty.
- `health(hero(0))` is 30: in this course, Fatigue is only an event.