fix(engine): evaluate 'attacks alone' relative to the attacker, not the ability source#5378
fix(engine): evaluate 'attacks alone' relative to the attacker, not the ability source#5378dhgoal wants to merge 1 commit into
Conversation
…he ability source Closes phase-rs#5328. TriggerCondition::MinCoAttackers counted co-attackers by excluding the ability SOURCE (source_id) from the tally. 'Attacks alone' is encoded as Not(MinCoAttackers{minimum:1}); when a non-attacking observer (Exalted / Agent 13, Sharon Carter) stays back and a DIFFERENT creature attacks alone, source_id is not in combat, so excluding it is a no-op. The lone attacker stays counted, MinCoAttackers returns true, and Not(...) makes the 'attacks alone' ability silently fail to fire. Exclude the creature that fired the trigger instead: read the single attacker named by the per-attacker AttackersDeclared event (produced by matching_attack_events and re-checked at resolution, CR 603.4), falling back to source_id when the event names no single attacker (self-referential paths, unchanged). source_id still resolves the filter's source object so Training's power-relative co-attacker comparison (CR 702.149a) is unaffected. CR 506.5 (attacks alone = only creature declared) + CR 508.1a + CR 603.2c + CR 702.83b (Exalted). Adds tests/attacks_alone_observer_5328.rs pinning both the fire-when-another-attacks-alone case (was 0 clues, now 1) and the two-attackers negative control.
|
🚨 Contributor flagged. Click here for more info: Superagent Dashboard |
There was a problem hiding this comment.
Code Review
This pull request adds a new integration test file attacks_alone_observer_5328.rs to verify the "attacks alone" mechanic (Issue #5328). The tests ensure that the mechanic is evaluated relative to the attacking creature rather than the ability's source, verifying that the trigger fires correctly when a different creature attacks alone and does not fire when multiple creatures attack. There are no review comments, so I have no feedback to provide.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Parse changes introduced by this PR✓ No card-parse changes detected. |
Tier: Frontier
Model: claude-opus-4-8
Thinking: high
Closes #5328.
Summary
The "attacks alone" mechanic silently failed to fire when the observing permanent stayed back and a different creature attacked alone.
TriggerCondition::MinCoAttackerstallied co-attackers by excluding the ability source (source_id). "Attacks alone" is encoded asNot(MinCoAttackers { minimum: 1 }). When a non-attacking observer (an Exalted-style card — the issue's Agent 13, Sharon Carter / Black Widow Double Agent) is the ability source but is not in combat, excludingsource_idfrom the tally is a no-op — so the lone attacker stays counted,MinCoAttackersreturnstrue, andNot(...)reports "not alone." The ability never fires.Fix: exclude the creature that actually fired the trigger, not the ability source. The per-attacker
AttackersDeclaredevent (produced bymatching_attack_events, and re-checked at resolution per CR 603.4) names exactly the triggering attacker; use it, falling back tosource_idwhen the event names no single attacker (self-referential trigger paths — behavior unchanged).source_idstill resolves thefilter's source object, so Training's power-relative co-attacker comparison (CR 702.149a) is unaffected.Reproduction (confirmed failing-before / passing-after)
A four-board probe isolates exactly one wrong quadrant on
main:mainThe new test
other_creature_attacks_alone_fires_even_when_observer_stays_backis the regression pin (0 before this change, 1 after);two_other_creatures_attacking_do_not_fire_attacks_aloneis the negative control.Anchored on
crates/engine/src/game/triggers.rs— theTriggerCondition::MinCoAttackersarm incheck_trigger_condition: the co-attacker filter previously reada.object_id != source_id, now excludes the event's triggering attacker.AttackersDeclared { attacker_ids, .. }event (frommatching_attack_events, re-passed at resolution-time re-check per CR 603.4) — the source of the single triggering-attacker id.Verification
cargo fmt --all— clean.cargo clippy -p engine --tests -- -D warnings— clean.cargo test -p engine --test attacks_alone_observer_5328— 2/2 pass (fail-on-revert).cargo test -p engine --lib -- game::triggers::— 353 passed; fullintegrationsuite — 1823 passed. Pre-existing related tests still green:issue_5159_attacks_alone_investigate,training_condition_counts_only_higher_power_coattackers,granted_ability_self_binding.CR verified against
docs/MagicCompRules.txt: 506.5, 508.1a, 603.2c, 603.4, 702.83b, 702.149a.Scope Expansion
None.