Skip to content

fix(parser): scope "that player" to triggering player for Aura/Equipment damage triggers#6540

Open
hitomi1 wants to merge 4 commits into
phase-rs:mainfrom
hitomi1:fix/damage-trigger-that-player-scope
Open

fix(parser): scope "that player" to triggering player for Aura/Equipment damage triggers#6540
hitomi1 wants to merge 4 commits into
phase-rs:mainfrom
hitomi1:fix/damage-trigger-that-player-scope

Conversation

@hitomi1

@hitomi1 hitomi1 commented Jul 23, 2026

Copy link
Copy Markdown

Fixes #4240.

Problem

Sigil of Sleep froze the game (p0 softlock — the "set resolve order" prompt could not be actioned). Its trigger — "Whenever enchanted creature deals damage to a player, return target creature that player controls to its owner's hand" — surfaced two target slots (a Player and a creature) instead of one. The phantom Player slot has no meaningful prompt, so the client hung waiting on it.

Root cause

parse_damage_source_subject (in parser/oracle_trigger.rs) required a leading article, so the article-less Aura/Equipment subjects "enchanted creature" / "equipped creature" failed the strict is_damage_done_trigger_pattern check and fell through to condition_introduces_target_player. That mis-bound the effect's "that player controls" anaphor to ControllerRef::TargetPlayer — whose documented behavior is to auto-surface a companion Player target slot — instead of ControllerRef::TriggeringPlayer (the damaged player identified by the triggering event).

Fix

Recognize the two article-less determiner subjects at the top of parse_damage_source_subject, resolving them to TargetFilter::AttachedTo (which is also the correct valid_source for the source-led trigger path — not Typed(Enchanted/EquippedBy), which would match any attached creature). The DamageDone pattern now matches, so relative_player_scope_for_condition returns TriggeringPlayer and the anaphor binds correctly — a single creature target scoped to the damaged player.

Scope (built for the class, not the card)

Fixes Sigil of Sleep, Hammer of Ruin, Fishing Gear, Whispersteel Dagger. Komainu Battle Armor's compound "this creature or equipped creature" subject is a disjunctive variant left for a follow-up (unchanged here — no regression).

Tests

  • Building-block test on relative_player_scope_for_condition asserting both determiner subjects → TriggeringPlayer (covers the class).
  • Sigil of Sleep bounce-target test asserting TriggeringPlayer-scoped creature target (was red before the fix).
  • Full engine suite green (17530 lib + 3753 integration), clippy -D warnings clean, cargo fmt applied.

CR 303.4b + CR 301.5a + CR 120.3a.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved parsing of damage triggers that use article-less phrases like “enchanted creature” and “equipped creature.”
    • Fixed “that player” targeting so it correctly resolves to the player who was dealt the damage.
    • Corrected Sigil of Sleep’s target selection so the effect targets only the damaged player’s eligible creatures.
  • Tests
    • Added unit and integration regression coverage for article-less damage triggers and Sigil of Sleep’s targeting behavior.

…ent damage triggers

Article-less damage-source subjects ("enchanted creature" / "equipped
creature") failed the DamageDone-pattern check in
`parse_damage_source_subject` (it required a leading article), so a later
"that player controls/'s" anaphor mis-bound to `ControllerRef::TargetPlayer`
— surfacing a phantom companion Player target slot that froze the game
(Sigil of Sleep). Recognize the two determiner subjects as
`TargetFilter::AttachedTo` so the DamageDone pattern matches and the
anaphor binds to `TriggeringPlayer`.

Covers Sigil of Sleep, Hammer of Ruin, Fishing Gear, Whispersteel Dagger.
Komainu Battle Armor's compound "this creature or equipped creature"
subject is a separate follow-up.

CR 303.4b + CR 301.5a + CR 120.3a.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@hitomi1
hitomi1 requested a review from matthewevans as a code owner July 23, 2026 08:14
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: d72f1bbd-6700-4e98-b30e-7879f3bd8a46

📥 Commits

Reviewing files that changed from the base of the PR and between 17a1018 and 6aed42b.

📒 Files selected for processing (2)
  • crates/engine/src/parser/oracle_trigger_tests.rs
  • crates/engine/tests/integration/main.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • crates/engine/tests/integration/main.rs
  • crates/engine/src/parser/oracle_trigger_tests.rs

📝 Walkthrough

Walkthrough

Changes

Oracle trigger parsing

Layer / File(s) Summary
Attached-creature damage subject support
crates/engine/src/parser/oracle_trigger.rs, crates/engine/src/parser/oracle_trigger_tests.rs
Article-less “enchanted creature” and “equipped creature” subjects parse as attached-creature damage sources. Tests verify triggering-player scope and Sigil of Sleep’s creature target filter.
Sigil of Sleep target-scope regression
crates/engine/tests/integration/issue_4240_sigil_of_sleep_target_scope.rs, crates/engine/tests/integration/main.rs
An integration test verifies one legal creature target controlled by the damaged player and confirms it returns to its owner’s hand after resolution.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the parser scoping fix for Aura/Equipment damage triggers and matches the PR's main change.
Linked Issues check ✅ Passed The changes address #4240 by fixing Sigil of Sleep's trigger parsing and adding regression coverage for the broken resolve-order flow.
Out of Scope Changes check ✅ Passed The PR stays focused on parser logic and regression tests for the reported trigger-stack bug, with no unrelated code changes.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@matthewevans matthewevans self-assigned this Jul 23, 2026
@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown

Parse changes introduced by this PR · 6 card(s), 4 signature(s) (baseline: main b2628643ad65)

🟡 Modified fields (4 signatures)

  • 2 cards · 🔄 ability/DealDamage · changed field amount: cards in hand (scoped player)target zone card count
    • Affected (first 3): Sword of Fire and Ice and War and Peace, Sword of War and Peace
  • 2 cards · 🔄 ability/LoseLife · changed field amount: divide(life total (scoped player), 2, rounded up)divide(life total (target player), 2, rounded up)
    • Affected (first 3): Quietus Spike, Scytheclaw
  • 1 card · 🔄 ability/Bounce · changed field target: target player controls creaturetriggering player controls creature
    • Affected (first 3): Sigil of Sleep
  • 1 card · 🔄 ability/Destroy · changed field target: target player controls Equipmenttriggering player controls Equipment
    • Affected (first 3): Hammer of Ruin

2 card(s) had Oracle-text changes (errata/reprint) — excluded as non-parser.

@matthewevans matthewevans added the bug Bug fix label Jul 23, 2026

@matthewevans matthewevans left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requested change

P1 — Explain or constrain the parser blast radius

The fresh coverage-parse-diff shows parser-output changes for four cards outside this PR’s claimed Sigil of Sleep / Hammer of Ruin scope: Sword of Fire and Ice, Sword of War and Peace, Quietus Spike, and Scytheclaw.

Please either narrow the grammar so these changes do not occur, or document why each change is intended and add card-level runtime coverage for the affected behavior. Re-run the parse diff on the updated head.

This is blocking because parse_damage_source_subject is shared damage-trigger grammar, and the current PR does not provide evidence that those additional behavior changes are correct.

@matthewevans matthewevans removed their assignment Jul 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sigil of Sleep breaks trigger stack — [[Sigil of Sleep]] trigger breaks trigger stack, cannot click the button "set res…

2 participants