Skip to content

Way of the Mind Sculptor (FRA) - #11986

Merged
tool4ever merged 3 commits into
Card-Forge:masterfrom
liamiak:way-of-the-mind-sculptor
Sep 21, 2026
Merged

tool4ever merged 3 commits into
Card-Forge:masterfrom
liamiak:way-of-the-mind-sculptor

Conversation

@liamiak

@liamiak liamiak commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

Adds Way of the Mind Sculptor, the last unimplemented card in the FRA Way of the ___ cycle. The ETB
half needed nothing new — the other six cycle members already script Empower | Type$ Jace | Num$ 5
verbatim.

The second ability is the blocker:

Whenever you activate a loyalty ability, if you removed two or more loyalty counters to activate it,
draw a card.

It has to read the payment rather than the printed cost, because cost modification changes it: Carth
the Lion raises every loyalty cost by [+1], so a printed [-2] removes one counter and must not
draw. The 21 cards with SubCounter<X/LOYALTY> have no printed number at all.

Forge already records this — CostRemoveCounter stores the amount paid in the CostCountersRemoved
SVar, which ten cards read. What was missing is a way for a trigger on another permanent to match on
it, so this adds one comparison property to SpellAbilityProperty, following XCost directly above
it.

The card gates the trigger itself, ValidSA$ Activated.Loyalty+CountersRemovedToPayGE2 on the T:
line, rather than putting a condition on the executed ability — so a failing condition keeps the
trigger off the stack instead of resolving it to nothing. CheckSVar can't serve here:
requirementsCheck runs without runParams, so a trigger-level SVar cannot reach the activated
ability, while ValidSA is evaluated in performTest, which can.

LoyaltyPaidGateTest drives five activations through the real activation path, asserting the loyalty
spent and whether the trigger reached the stack as well as the draw:

activation removed on stack draws
Garruk [-4] 4 yes 1
Garruk [-1] 1 no 0
Carth + Garruk [-4] 3 yes 1
Carth + Sorin [-2] 1 no 0
Carth + Garruk [-1] 0 no 0

Reverting SpellAbilityProperty.java alone fails the two drawing cases.

Two things worth knowing: the property reads the total counters removed rather than splitting by type,
so it relies on Activated.Loyalty to keep that sound; and folding the condition into ValidSA checks
it once, where a true intervening-if is also rechecked on resolution — equivalent here, since counters
already removed cannot change.

Written with Claude Code (Opus 5); I have reviewed and tested it.

🤖 Generated with Claude Code

Record the counters removed to pay an ability's costs on the SpellAbility and
expose them as Count$CountersRemovedToPay <CounterName>, so the card's trigger
can tell whether two or more loyalty counters were paid to activate an ability.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Comment thread forge-game/src/main/java/forge/game/cost/CostRemoveCounter.java
Comment thread forge-gui/res/cardsfolder/upcoming/way_of_the_mind_sculptor.txt Outdated
Drop the per-CounterType tally on SpellAbility and read the existing
CostCountersRemoved SVar instead, as tool4ever asked. A remove-counter cost
names its type, so the payment cannot mix types and the tally bought nothing.

Move the two-or-more test onto the trigger's ValidSA so a failing condition
keeps the trigger off the stack, rather than resolving it to no effect.
CheckSVar cannot serve here: requirementsCheck runs without runParams, so a
trigger-level SVar cannot reach the activated ability. A CountersRemovedToPay
comparison property can, following XCost.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@liamiak

liamiak commented Sep 21, 2026

Copy link
Copy Markdown
Contributor Author

Pushed 59a8f07 for both review comments — replies are in the two threads, which are now collapsed as outdated.

Short version: the engine side drops from 7 files to 1. The per-CounterType tally on SpellAbility is gone in favour of the existing CostCountersRemoved SVar, read through a CountersRemovedToPay comparison property on SpellAbilityProperty, following XCost. The card gates on it in ValidSA$ so a failing condition keeps the trigger off the stack, and the test now asserts that as well as the draw. Full suite green, checkstyle clean.

@tool4ever
tool4ever merged commit eb50a8d into Card-Forge:master Sep 21, 2026
3 checks passed
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.

3 participants