Detect attack-punisher enchantments by trigger instead of by name - #11456
Open
omraj21 wants to merge 2 commits into
Open
Detect attack-punisher enchantments by trigger instead of by name#11456omraj21 wants to merge 2 commits into
omraj21 wants to merge 2 commits into
Conversation
AiAttackController only recognised Revenge of Ravens, by name, when working out whether attacking would cost the AI life. The code carried a TODO to detect it by its trigger instead. Several cards are printed with the same trigger and the AI walked straight into all of them: Hissing Miasma Whenever a creature attacks you, its controller loses 1 life Blood Reckoning same, for creatures you don't control Marchesa's Decree same, alongside the monarch ability Look for the trigger instead: an Attacks trigger on the defending player's battlefield whose effect is LoseLife aimed at TriggeredAttackerController. A test with the old name check shows the AI sending all three attackers into lethal life loss against Hissing Miasma and Blood Reckoning. Cards that punish the attacking creature rather than its controller, such as Circle of Flame dealing damage to the attacker, deliberately do not count. The creature pays that cost, not the player, and normal combat evaluation already handles it. There is a test for that too, so the check can't quietly widen. The life total is now compared against the actual life lost rather than assuming one per attacker, and the "not worth attacking" filter uses the same number instead of a hardcoded 1, so a card draining 2 per attacker is treated correctly. Amounts that aren't plain numbers are skipped rather than guessed, since overestimating here would make the AI refuse to attack for no reason. Full mvn -U -B clean test: 12 modules, 0 failures, run three times. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
omraj21
force-pushed
the
ai-attack-punisher-detection
branch
from
August 2, 2026 05:06
bdbdf27 to
051a647
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
AiAttackControlleronly recognised Revenge of Ravens, by name, when working out whether attacking would cost the AI life:Several cards are printed with the same trigger, and the AI walked straight into all of them:
This does what the TODO asks and looks for the trigger: an
Attackstrigger on the defending player's battlefield whose effect isLoseLifeaimed atTriggeredAttackerController.With the old name check, the added test shows the AI sending all three attackers into lethal life loss:
What deliberately does not count
Cards that punish the attacking creature rather than its controller — Circle of Flame dealing 1 damage to the attacker, Raking Canopy, Palazzo Archers — are excluded. The creature pays that cost, not the player, and normal combat evaluation already accounts for it. There's a test asserting the AI still attacks into Circle of Flame, so the check can't quietly widen to cards it shouldn't cover.
Two smaller corrections in the same logic
getNetCombatDamage() <= 1.Amounts that aren't plain numbers are skipped rather than guessed at, since overestimating here would make the AI refuse to attack for no reason.
Verification
5 tests: no-punisher control, Revenge of Ravens (the case the name check already covered), Hissing Miasma, Blood Reckoning, and the Circle of Flame exclusion. Two of them fail on the old code.
Full
mvn -U -B clean test: 12 modules, 308 tests, 0 failures, run three times.Written with the help of GitHub Copilot CLI; the commit carries a
Co-authored-bytrailer for it.