Files
systemic-game-design-course/course/02-action-queue/scenarios.md
T
2026-10-29 02:30:26 +01:00

3.1 KiB

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.
    • zoneOf(A) is still board. Module 2 has no death step; Module 3 adds one.

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.