Skip to main content

✅ Chain fires when moved demon was readied

CategoryInteraction
StatusPassing
Testtests/test_abilities_complex.py::TestGamiginMalphasStolasCombo::test_chain_fires_when_moved_demon_was_readied

Simulating Gamigin's Possession on a READIED P2 demon

Preconditions

  • P1 Main Phase, both players at 6 AP

  • Lane 0: P1's Malphas (#041) — READIED

  • Lane 0: P1's Stolas (#022) — READIED

  • Lane 0: P1's Murmur (#002, HP=9, 0 damage) — innocent bystander, also Local to Stolas

  • Lane 0: P2's Gamigin (#031, HP=6, 0 damage) — READIED, Local to Malphas

Action

  • Simulate Possession moving Gamigin from lane 0 to lane 1.

  • Fire DEMON_MARCHED with target=Gamigin, value=0 (pre-move lane), lane=1.

POSTCONDITIONS (expected per rulebook):

  • Gamigin: EXHAUSTED (Malphas's trigger fired, Gamigin was readied so the

  • Murmur: 1 damage (Stolas's field triggered on Gamigin's exhaust — Murmur

  • Gamigin: 1 damage (also "another Local demon" from Stolas's perspective,

  • Stolas: 0 damage (excluded from its own trigger).

  • Malphas: 0 damage (Local to Stolas but untargeted; Stolas's trigger

result = fire_event(state2, event)

gamigin_after = next(d for d in result.demons if d.unit_id == "031")
murmur_after = next(d for d in result.demons if d.unit_id == "002")
stolas_after = next(d for d in result.demons if d.unit_id == "022")
malphas_after = next(d for d in result.demons if d.unit_id == "041")

# Malphas should have exhausted Gamigin on the move.

Expected Postconditions

  • See assertions below.

Assertions

assert gamigin_after.state == DemonState.EXHAUSTED, (
f"Malphas should exhaust Gamigin on move (Gamigin was Local+Readied). "
f"Got state={gamigin_after.state}."
)

# Stolas's field should fire on the exhaust: 1 damage to OTHER Local demons.
assert murmur_after.damage == 1, (
f"Murmur should take 1 damage from Stolas's field triggering on Gamigin's exhaust. "
f"Got {murmur_after.damage}. If 0, the engine is not emitting DEMON_EXHAUSTED "
f"when Malphas exhausts a demon — a gap in the chain."
)
assert stolas_after.damage == 0, (
f"Stolas is excluded from its own field trigger. Got {stolas_after.damage}."
)
assert malphas_after.damage == 1, (
f"Malphas is Local to Stolas and 'other', so should also take 1 damage. "
f"Got {malphas_after.damage}."
)