Skip to content

Let the AI use Venser, the Sojourner (and two other mass-unblockable cards) - #11396

Open
liamiak wants to merge 2 commits into
Card-Forge:masterfrom
liamiak:let-ai-use-venser
Open

Let the AI use Venser, the Sojourner (and two other mass-unblockable cards)#11396
liamiak wants to merge 2 commits into
Card-Forge:masterfrom
liamiak:let-ai-use-venser

Conversation

@liamiak

@liamiak liamiak commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

28 added lines outside the test, which is a droppable second commit.

Venser, the Sojourner is AI:RemoveDeck:All. Two of his three abilities turn out to work already —
the flag was covering for one dead one, and that one turned out not to be his alone.

What was dead

The -1 never fired on any board, including one where it wins on the spot:

AI power Opponent life Blockers Before After
18 15 2 CantPlayAi activates
18 18 2 CantPlayAi activates
18 19 2 CantPlayAi declines
6 20 2 CantPlayAi declines
no creatures 20 2 CantPlayAi declines
18, but Main 2 15 2 CantPlayAi declines

While there are corner cases there unblockability without being able to swing for the win is worth it, those are relatively rare and not implemented. However, the case of "can I make everything unblockable and swing for the win" is key, and now implemented.

UnblockableForLethal holds the ability until attacking with everything that can attack would take
an opponent to zero with nothing able to block — the state the ability itself creates, so blockers
are not counted.

The same gap on two other cards

Every card where granting mass unblockability is an optional choice had the identical problem —
CantPlayAi on every board, lethal ones included — and all three now fire only on lethal:

Card Ability Flag
Venser, the Sojourner -1 AI:RemoveDeck:All, removed here
Jace, Arcane Strategist -7 ultimate AI:RemoveDeck:Random, left alone — that is a deck-building signal, not a playability one
Tezzeret's Gatebreaker {5}{U}, {T}, Sacrifice none — this one was simply misplaying in AI decks

Those two argue for the gate harder than Venser does: Jace spends seven loyalty and Gatebreaker
sacrifices itself, so firing either off-lethal is a real loss rather than a wasted tick.

The rest of the cards with the same effect are deliberately untouched, because using it is not a
choice they make: Keeper of Keys and Veiling Oddity are mandatory triggers, and Bedlam, Tazeem and
Tanglewalker are static. Glaring Spotlight grants hexproof alongside it, so it is also a protection
card and a lethal-only gate would be wrong for it. Reverse the Polarity offers it as a Charm mode,
which CharmAi picks through a different path and would want its own verification.

No priority plumbing was needed — ComputerUtilAbility already sorts planeswalker abilities
most-costly-first, so the -1 outranks the +2 by itself once it starts saying yes.

What already works

The +2 (exile a permanent you own, return it at end of turn) lands in ChangeZoneAi's existing
blink logic, because the ability has Destination$ Exile with a DB$ DelayedTrigger sub. That logic
is good: it skips tokens, prefers permanents with ETB triggers, holds until post-combat, and takes
anything the AI owns but an opponent controls immediately rather than waiting. Measured:

Board Phase Result
Opponent controls my Wall of Omens Main 1 takes it back
Opponent controls my Grizzly Bears (no ETB) Main 1 takes it back
My Wall of Omens Main 1 declines, waits
My Wall of Omens Main 2 blinks it
My Mulldrifter Main 2 blinks it
Creatures with no ETB, or lands only either declines

The -8 is already AILogic$ Always, and the emblem it makes behaves: whenever the AI ultimates,
the emblem exiles Ancient Brontodon and then Grizzly Bears — the opponent's board, biggest first —
leaving its own Colossal Dreadmaw alone.

Testing

  • mvn -pl forge-gui-desktop -am test: 287 tests, 0 failures.
  • The test fails without the change, in both directions.
  • It asks the AI directly rather than playing a game out, so it does not depend on MyRandom.

The flag comes off on the back of that.

🤖 Implemented with the assistance of Claude Code (Opus 5).

liamiak1 and others added 2 commits July 25, 2026 19:55
Making everything unblockable is worth nothing unless the attack it enables
wins the game, and EffectAi had no way to ask that, so every card with the
effect declined on every board - including boards where it was lethal.

Add an UnblockableForLethal logic that holds the ability until attacking
with everything that can attack would take an opponent to zero with nothing
able to block, which is precisely the state the ability creates. Blockers
are therefore not counted.

Applied to the three cards where using it is an optional choice - Venser,
the Sojourner's -1, Jace, Arcane Strategist's -7 and Tezzeret's Gatebreaker.
All three went from declining on every board to firing only on lethal ones.

The others with the same effect are not decisions: Keeper of Keys and
Veiling Oddity are mandatory triggers, Bedlam, Tazeem and Tanglewalker are
static. Glaring Spotlight grants hexproof alongside it, so it is also a
protection card and a lethal-only gate would be wrong for it. Reverse the
Polarity offers it as a Charm mode, which CharmAi picks through a different
path and would need its own verification.

Venser also loses AI:RemoveDeck:All. His other two abilities already work -
ChangeZoneAi's blink logic handles the +2 (skips tokens, prefers ETB
triggers, waits for post-combat, and takes back anything an opponent has
gained control of), and the -8 is already AILogic$ Always.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Both directions on Venser's -1: fires at exactly lethal, holds one damage
short. Calls the AI directly rather than playing a game out, so it does not
depend on MyRandom.

Drop this commit if you would rather not carry the test.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants