Stop the AI paying real costs for abilities that do nothing - #11441
Closed
omraj21 wants to merge 2 commits into
Closed
Stop the AI paying real costs for abilities that do nothing#11441omraj21 wants to merge 2 commits into
omraj21 wants to merge 2 commits into
Conversation
BecomeMonarch was mapped to AlwaysPlayAi, which accepts every activation without looking at the board. GameAction.becomeMonarch returns immediately when the chosen player is already the monarch, so activating one of these abilities while holding the crown does nothing. That is not just a wasted activation. Throne of the High City taps and sacrifices itself for 4, King Solomon's Frogs exiles itself, and Tchaka, Venerable King exiles itself from the graveyard, so the AI was throwing a permanent away for no effect. A test with the old mapping shows Throne of the High City going from one copy on the battlefield to zero. Add BecomeMonarchAi, which declines only when every player the ability would crown is already the monarch. Targeted versions are deliberately left alone: cards like Jared Carthalion, True Heir and Garland, Royal Kidnapper hand the crown to an opponent on purpose to turn on another ability, so the previous always-play behaviour is still right for them. Initiative is intentionally not changed. GameAction.takeInitiative documents that "You can take the initiative even if you already have it" and still runs the trigger, so AlwaysPlayAi remains correct there. forge.ai.** test suite: 249 tests, 0 failures. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
UnlockDoor was mapped to AlwaysPlayAi, which accepts every activation without
looking at the board. For Mode$ LockOrUnlock that is wrong in two ways.
When every door of the targeted Room is already unlocked, UnlockDoorEffect's
case 0 branch can only call lockRoom, so the ability shuts off one of the AI's
own Rooms. Keys to the House pays {3}, taps and sacrifices itself for that
ability, so the AI was throwing away a permanent to make its own board worse.
With the old mapping the test here shows Keys to the House going from one copy
on the battlefield to zero.
When exactly one door is locked, the effect offers both doors and locks the one
that is still open. The choice went through SpellAbilityAi.chooseCardState,
whose base implementation prints a "default implementation is used" warning and
returns the first element, so which door the AI got was down to state ordering
rather than a decision.
Add UnlockDoorAi: decline when no reachable Room has a locked door, and pick a
locked door when asked to choose, so the ability always opens a Room instead of
closing one. Mode$ Unlock and Mode$ ThisDoor can only ever unlock, so they keep
the previous always-play behaviour.
Affects Keys to the House and Marina Vendrell.
forge.ai.** test suite: 251 tests, 0 failures.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
|
Probably should do separate PRs for Monarch/Unlock |
This was referenced Jul 29, 2026
Contributor
Author
|
Splitting this into two PRs so each fix can be reviewed on its own, since they are unrelated beyond both being AlwaysPlayAi mappings:
Same commits, no content changes apart from correcting the test counts now that each branch is measured on its own. |
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.
Two abilities were mapped to
AlwaysPlayAi, whose entire logic isreturn WillPlaywith no look at the board. In both cases the engine can resolvethe ability to a no-op (or worse), while the activation cost sacrifices a permanent.
Monarch
GameAction.becomeMonarchreturns immediately when the chosen player is alreadythe monarch, so activating one of these abilities while holding the crown does
nothing. Throne of the High City taps and sacrifices itself for {4}, King
Solomon's Frogs exiles itself, and Tchaka, Venerable King exiles itself from the
graveyard, so the AI was throwing a permanent away for no effect. With the old
mapping the added test shows Throne of the High City going from one copy on the
battlefield to zero.
BecomeMonarchAideclines only when every player the ability would crown isalready the monarch. Targeted versions are deliberately left alone: cards like
Jared Carthalion, True Heir and Garland, Royal Kidnapper hand the crown to an
opponent on purpose to turn on another ability.
Initiative is intentionally not changed -
GameAction.takeInitiativedocumentsthat "You can take the initiative even if you already have it" and still runs the
trigger, so always-play is correct there.
Rooms
UnlockDoorwithMode$ LockOrUnlockis wrong in two ways. When every door ofthe targeted Room is already unlocked,
UnlockDoorEffect'scase 0branch canonly call
lockRoom, so the ability shuts off one of the AI's own Rooms. Keys tothe House pays {3}, taps and sacrifices itself for that ability.
When exactly one door is locked, the effect offers both doors and locks the one
that is still open. That choice went through
SpellAbilityAi.chooseCardState,whose base implementation prints a "default implementation is used" warning and
returns the first element, so which door the AI got was down to state ordering.
UnlockDoorAideclines when no reachable Room has a locked door, and picks alocked door when asked to choose.
Mode$ UnlockandMode$ ThisDoorcan onlyever unlock, so they keep the previous behaviour. Affects Keys to the House and
Marina Vendrell.
Each fix comes with a test that fails on the old mapping.
Verified: forge.ai.** test suite, 251 tests, 0 failures. Full
mvn -U -B clean testacross all 12 modules passes.
Written with the help of GitHub Copilot CLI; the commits carry a
Co-authored-bytrailer for it.