Card Development Questions
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins
Re: Card Development Questions
by slowe » 03 Dec 2011, 04:44
This topic is for scripting/development questions, not card requests. You should try to script the cards first, and then if you run into problems you could ask for help figuring out what's wrong here.Iran wrote:Urge to Feed, Bloodbond March and Blood Tribute. Anyone see any problem to script them?
Can I script Urge to Feed like a cost? the part of tap any number of vampires to put +1/+1 on them.
As for the cards, Urge to Feed isn't scriptable because you can't choose an arbitrary number of vampires and remember which ones they are to put counters on them afterward. Blood Tribute is almost doable, but the problem is "lost this way" - if your opponent has a Platinum Emperion out, you can't script it so you don't gain any life, for example. Bloodbond March seems feasible, but I could be missing something. Go ahead and script it, and if you don't mind corner cases with Blood Tribute, you can script yourself an almost-correct version of that.
Re: Card Development Questions
by slowe » 04 Dec 2011, 22:58
I think I have a fully-working Countryside Crusher. I scripted the "repeat this process" upkeep trigger as "reveal until you reveal a nonland card", which should be functionally equivalent. I know the timing of the triggers works correctly, but I want to make sure I'm not missing something else.
Perhaps Sol, Rules Lawyer has some insight -- you usually seem to be the judge of what's kosher.
Perhaps Sol, Rules Lawyer has some insight -- you usually seem to be the judge of what's kosher.

- script | Open
- Name:Countryside Crusher
ManaCost:1 R R
Types:Creature Giant Warrior
Text:no text
PT:3/3
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigReveal | TriggerDescription$ At the beginning of your upkeep, reveal the top card of your library. If it's a land card, put it into your graveyard and repeat this process.
T:Mode$ ChangesZone | Origin$ Any | Destination$ Graveyard | ValidCard$ Land.YouOwn | TriggerZones$ Battlefield | Execute$ TrigAddCounter | TriggerDescription$ Whenever a land card is put into your graveyard from anywhere, put a +1/+1 counter on Countryside Crusher.
SVar:TrigReveal:AB$DigUntil | Cost$ 0 | DigNum$ 1 | Valid$ Card.nonLand | ValidDescription$ a nonland card | FoundDestination$ Library | LibraryPosition$ 0 | RevealedDestination$ Graveyard
SVar:TrigAddCounter:AB$PutCounter | Cost$ 0 | CounterType$ P1P1 | CounterNum$ 1
SVar:Rarity:Rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/countryside_crusher.jpg
End
Re: Card Development Questions
by friarsol » 05 Dec 2011, 00:05
I'm fine with the slight inaccuracy here. The main difference between Countryside Crusher and something like Hermit Druid is ordering of cards. With the Crusher, the cards have to enter the graveyard in the order they are revealed. With Hermit Druid, since they all hit the grave at the same time the player can put it in any order they choose.slowe wrote:I think I have a fully-working Countryside Crusher. I scripted the "repeat this process" upkeep trigger as "reveal until you reveal a nonland card", which should be functionally equivalent. I know the timing of the triggers works correctly, but I want to make sure I'm not missing something else.
Perhaps Sol, Rules Lawyer has some insight -- you usually seem to be the judge of what's kosher.![]()
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Card Development Questions
by Iran » 05 Dec 2011, 02:41
I ask here because I do not I know if these cards are scriptable. Some cards I asks with technical details (In the case of Urge to feed and others I asks other time)slowe wrote:This topic is for scripting/development questions, not card requests. You should try to script the cards first, and then if you run into problems you could ask for help figuring out what's wrong here.Iran wrote:Urge to Feed, Bloodbond March and Blood Tribute. Anyone see any problem to script them?
Can I script Urge to Feed like a cost? the part of tap any number of vampires to put +1/+1 on them.
As for the cards, Urge to Feed isn't scriptable because you can't choose an arbitrary number of vampires and remember which ones they are to put counters on them afterward. Blood Tribute is almost doable, but the problem is "lost this way" - if your opponent has a Platinum Emperion out, you can't script it so you don't gain any life, for example. Bloodbond March seems feasible, but I could be missing something. Go ahead and script it, and if you don't mind corner cases with Blood Tribute, you can script yourself an almost-correct version of that.
Trying to script Bloodbond March
- "Bloodbond March" | Open
- Name:Bloodbond March
ManaCost:2 B G
Types:Enchantment
Text:no text
T:Mode$ ChangesZone | ValidCard$ Creature | Origin$ Any | Destination$ Stack | RememberTargets$ True | ForgetOtherTargets$ True | Execute$ TrigReturn | TriggerZones$ Battlefield | TriggerDescription$ Whenever a player casts a creature spell, each player returns all cards with the same name as that spell from his or her graveyard to the battlefield.
SVar:TrigReturn:AB$ ChangeZoneAll | Cost$ 0 | ChangeType$ Remembered+Other+sameName | Origin$ Graveyard | Destination$ Battlefield | SubAbility$ DBCleanup
SVar:DBCleanup:DB$Cleanup | ClearRemembered$ True
SVar:RemRandomDeck:True
SVar:Rarity:rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/bloodbond_march.jpg
End
When I have Bloodbond March in battlefield and cast a creature spell, I get this crash Report
- "Crash Report" | Open
- This is a Crash Report. An error has occurred. Please save this message to a file.
Please follow the instructions at this address to submit this Crash Report, plus what you were doing at the time:
http://tinyurl.com/3zzrnyb
Reporting bugs in Forge is very important. We thank you for your time.
AbilityFactory : SpellAbility was not created for Bloodbond March. Looking for API: ChangesZoneAll
Version:
Forge version 1.1.8-r12238
OS: Windows XP Version: 5.1 Architecture: x86
Java Version: 1.6.0_25 Vendor: Sun Microsystems Inc.
Detailed error trace:
java.lang.RuntimeException: AbilityFactory : SpellAbility was not created for Bloodbond March. Looking for API: ChangesZoneAll
at forge.card.abilityfactory.AbilityFactory.getAbility(AbilityFactory.java:1174)
at forge.card.trigger.TriggerHandler.runSingleTrigger(TriggerHandler.java:464)
at forge.card.trigger.TriggerHandler.runTrigger(TriggerHandler.java:325)
at forge.GameAction.changeZone(GameAction.java:167)
at forge.GameAction.moveTo(GameAction.java:220)
at forge.GameAction.moveToStack(GameAction.java:325)
at forge.card.spellability.SpellAbilityRequirements.fillRequirements(SpellAbilityRequirements.java:96)
at forge.card.spellability.SpellAbilityRequirements.fillRequirements(SpellAbilityRequirements.java:77)
at forge.GameAction.playSpellAbility(GameAction.java:2639)
at forge.GameAction.playCard(GameAction.java:1846)
at forge.gui.input.InputPassPriority.selectCard(InputPassPriority.java:66)
at forge.GuiInput.selectCard(GuiInput.java:103)
at forge.GuiDisplay$19.mousePressed(GuiDisplay.java:596)
at java.awt.AWTEventMulticaster.mousePressed(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Last edited by Iran on 05 Dec 2011, 02:55, edited 2 times in total.
Re: Card Development Questions
by slapshot5 » 05 Dec 2011, 02:47
It's ChangeZoneAll, not ChangesZoneAllIran wrote:When I have Bloodbond March in battlefield and cast a creature spell, I get this crash Report
- slapshot5
- Programmer
- Posts: 1391
- Joined: 03 Jan 2010, 17:47
- Location: Mac OS X
- Has thanked: 25 times
- Been thanked: 68 times
Re: Card Development Questions
by Iran » 05 Dec 2011, 02:54
It´s true, but unfortunately the card not returns the creatures from the players graveyard and the trigger fires when the spell is not a creature spell.slapshot5 wrote:It's ChangeZoneAll, not ChangesZoneAllIran wrote:When I have Bloodbond March in battlefield and cast a creature spell, I get this crash Report
I think this Remembered not work. The card don't hold the memory of the card casted.
Re: Card Development Questions
by slapshot5 » 05 Dec 2011, 03:43
For your trigger, try Mode$ SpellCastIran wrote:It´s true, but unfortunately the card not returns the creatures from the players graveyard and the trigger fires when the spell is not a creature spell.slapshot5 wrote:It's ChangeZoneAll, not ChangesZoneAllIran wrote:When I have Bloodbond March in battlefield and cast a creature spell, I get this crash Report
I think this Remembered not work. The card don't hold the memory of the card casted.
It's still not quite going to work I fear.
-slapshot5
- slapshot5
- Programmer
- Posts: 1391
- Joined: 03 Jan 2010, 17:47
- Location: Mac OS X
- Has thanked: 25 times
- Been thanked: 68 times
Re: Card Development Questions
by slowe » 05 Dec 2011, 05:53
Here's a working script:Iran wrote:It´s true, but unfortunately the card not returns the creatures from the players graveyard and the trigger fires when the spell is not a creature spell.slapshot5 wrote:It's ChangeZoneAll, not ChangesZoneAllIran wrote:When I have Bloodbond March in battlefield and cast a creature spell, I get this crash Report
I think this Remembered not work. The card don't hold the memory of the card casted.
- script | Open
- Name:Bloodbond March
ManaCost:2 B G
Types:Enchantment
Text:no text
T:Mode$ SpellCast | ValidCard$ Card.Creature | TriggerZones$ Battlefield | Execute$ TrigReturn | TriggerDescription$ Whenever a player casts a creature spell, each player returns all cards with the same name as that spell from his or her graveyard to the battlefield.
SVar:TrigReturn:AB$ ChangeZoneAll | Cost$ 0 | ChangeType$ Triggered.sameName | Origin$ Graveyard | Destination$ Battlefield
SVar:RemRandomDeck:True
SVar:Rarity:Rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/bloodbond_march.jpg
End
I found the script of Mishra, Artificer Prodigy to be a helpful reference. Always try to find cards that work in the same way as the one you're trying to script. It seems you were looking at a spell that needed to remember the name of its target, but Bloodbond March needs to remember the name of the card that causes it to trigger.
Re: Card Development Questions
by slowe » 05 Dec 2011, 06:22
As DigUntil currently works, it puts the cards in my graveyard (in the correct order) without having me order them. I think Forge doesn't ever makes you order multiple cards going to the GY, whether from dredge, Wrath effects, or something else. (I know ordering is built in to an AF or two, like whatever Lead the Stampede uses.) It's certainly less tedious not to order cards, but now Forge implements cards that care about GY order like Nether Shadow. Optimally, making the player order cards would be a toggle-able option, so if you want to play manaless dredge or some other craziness, you can do it right without excessive dialogs/clicking the rest of the time. This is probably low-priority functionality.friarsol wrote:I'm fine with the slight inaccuracy here. The main difference between Countryside Crusher and something like Hermit Druid is ordering of cards. With the Crusher, the cards have to enter the graveyard in the order they are revealed. With Hermit Druid, since they all hit the grave at the same time the player can put it in any order they choose.
Oh, and I realized that if Wheel of Sun and Moon is added, my script incorrectly doesn't cause an infinite loop with a land-only library. About as innocuous as an inaccuracy gets, I daresay.
Just waiting on commit privileges now.
Re: Card Development Questions
by SoulStorm » 05 Dec 2011, 07:33
Sorry it took me so long to reply, I got distracted by other things. I tried the fix, but it still didn't work. Maybe some kind soul will offer a fix for the problem in the near future. Thanks!moomarc wrote:After TokenSVars$ TrigReturn, there's no space between TrigReturn and the pipe splitter. As far as I recall that will stop the svar from being added so will fail to trigger. I can't test it right now but hope that helps. My own attempt to do this card ended in failure because of 'remember' timing issues, so hope your's works.SoulStorm wrote:Attempted to code Tatsumasa, the Dragon's Fang, but ran into a problem. The token generation works fine and exiles Tatsumasa, the Dragon's Fang correctly, but when the token dies, Tatsumasa, the Dragon's Fang doesn't return from exile. Thanks for the help as always.
- Code: Select all
Name:Tatsumasa, the Dragon's Fang
ManaCost:6
Types:Legendary Artifact Equipment
Text:Equipped creature gets +5/+5.
K:eqPump 3:+5/+5
A:AB$ Token | Cost$ 6 Exile<1/CARDNAME> | TokenAmount$ 1 | TokenName$ Dragon Spirit | TokenTypes$ Creature,Dragon,Spirit | TokenOwner$ You | TokenColors$ Blue | TokenPower$ 5 | TokenToughness$ 5 | TokenKeywords$ Flying | TokenTriggers$ TriggerJunior | TokenSVars$ TrigReturn| SpellDescription$ Put a 5/5 blue Dragon Spirit creature token with flying onto the battlefield. Return Tatsumasa to the battlefield under its owner's control when that token dies.
SVar:TriggerJunior:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ Return Tatsumasa to the battlefield under its owner's control when that token dies.
SVar:TrigReturn:AB$ChangeZone | Cost$ 0 | ChangeType$ Card.namedTatsumasa, the Dragon's Fang | ChangeNum$ 1 | Origin$ Exile | Destination$ Battlefield | Hidden$ True | SpellDescription$ Return Tatsumasa to the battlefield under its owner's control when that token dies.
SVar:Rarity:Rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/tatsumasa_the_dragons_fang.jpg
End
Re: Card Development Questions
by SoulStorm » 05 Dec 2011, 07:38
. Vish Kal, Blood Arbiter
Ok, this card works as advertized, but I wanted to make sure it was technically correct before submitting, because cards similar to this one have gotten me in trouble in the past.
Thanks!
Ok, this card works as advertized, but I wanted to make sure it was technically correct before submitting, because cards similar to this one have gotten me in trouble in the past.

- Code: Select all
Name:Vish Kal, Blood Arbiter
ManaCost:4 W B B
Types:Legendary Creature Vampire
Text:no text
PT:5/5
K:Flying
K:Lifelink
A:AB$PutCounter | Cost$ Sac<1/Creature> | Defined$ Self | CounterType$ P1P1 | CounterNum$ Y | SpellDescription$ Put X +1/+1 counters on Vish Kal, Blood Arbiter, where X is the sacrificed creature's power.
A:AB$ Pump | Cost$ 0 | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ -X | NumDef$ -X | SubAbility$ DBRemove | SpellDescription$ Remove all +1/+1 counters from Vish Kal: Target creature gets -1/-1 until end of turn for each +1/+1 counter removed this way.
SVar:Y:Sacrificed$CardPower
SVar:DBRemove:DB$RemoveCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ X
SVar:X:Count$CardCounters.P1P1
SVar:RemAIDeck:True
SVar:RemRandomDeck:True
SVar:Rarity:Rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/vish_kal_blood_arbiter.jpg
End
Re: Card Development Questions
by moomarc » 05 Dec 2011, 07:44
The one technical error would be that removing the counters for the second ability is meant to be a cost. So the opponent should be able to Stifle the ability and leave you with no p1p1 counters on it (whereas currently it would counter that part as well).SoulStorm wrote:. Vish Kal, Blood Arbiter
Ok, this card works as advertized, but I wanted to make sure it was technically correct before submitting, because cards similar to this one have gotten me in trouble in the past.Thanks!
- Code: Select all
Name:Vish Kal, Blood Arbiter
ManaCost:4 W B B
Types:Legendary Creature Vampire
Text:no text
PT:5/5
K:Flying
K:Lifelink
A:AB$PutCounter | Cost$ Sac<1/Creature> | Defined$ Self | CounterType$ P1P1 | CounterNum$ Y | SpellDescription$ Put X +1/+1 counters on Vish Kal, Blood Arbiter, where X is the sacrificed creature's power.
A:AB$ Pump | Cost$ 0 | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ -X | NumDef$ -X | SubAbility$ DBRemove | SpellDescription$ Remove all +1/+1 counters from Vish Kal: Target creature gets -1/-1 until end of turn for each +1/+1 counter removed this way.
SVar:Y:Sacrificed$CardPower
SVar:DBRemove:DB$RemoveCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ X
SVar:X:Count$CardCounters.P1P1
SVar:RemAIDeck:True
SVar:RemRandomDeck:True
SVar:Rarity:Rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/vish_kal_blood_arbiter.jpg
End
-Marc
-
moomarc - Pixel Commander
- Posts: 2091
- Joined: 04 Jun 2010, 15:22
- Location: Johannesburg, South Africa
- Has thanked: 371 times
- Been thanked: 372 times
Re: Card Development Questions
by SoulStorm » 05 Dec 2011, 08:46
Arrgh!!!, I knew my spidey sense was tingling for a reason. I couldn't figure out how to script the card with the remove all counters cost, because there is no way I know of to define the variable if I do that. Hmmm... any suggestions?moomarc wrote:The one technical error would be that removing the counters for the second ability is meant to be a cost. So the opponent should be able to Stifle the ability and leave you with no p1p1 counters on it (whereas currently it would counter that part as well).
Re: Card Development Questions
by moomarc » 05 Dec 2011, 09:03
I've just tried a few methods to make it work with Cost$ SubCounter<X/P1P1> with SVar:X:Count$CardCounters.P1P1 but there doesn't seem to be a way to record the counters removed this way. Count$xPaid only recognises X mana spent (at least it doesn't work here), ChosenX needs the XChoice variable so doesn't work, and just leaving NumAtt and NumDef referencing X doesn't work because by the time the counters are checked they've been used to pay the ability cost so equals zero.
One way I can see to make this work is to have have an extra parameter on XChoice (maybe XChoice.All) that would automatically select the maximum choice. Then you could so something like this (I've tried with regular XChoice manually selecting the max and it all works, so if this could be implemented there are a few more cards that use the same mechanic):
One way I can see to make this work is to have have an extra parameter on XChoice (maybe XChoice.All) that would automatically select the maximum choice. Then you could so something like this (I've tried with regular XChoice manually selecting the max and it all works, so if this could be implemented there are a few more cards that use the same mechanic):
- Vish Kal, Blood Arbiter | Open
- Code: Select all
Name:Vish Kal, Blood Arbiter
ManaCost:4 W B B
Types:Legendary Creature Vampire
Text:no text
PT:5/5
K:Flying
K:Lifelink
A:AB$ PutCounter | Cost$ Sac<1/Creature> | Defined$ Self | CounterType$ P1P1 | CounterNum$ Y | SpellDescription$ Put X +1/+1 counters on CARDNAME, where X is the sacrificed creature's power.
A:AB$ Pump | Cost$ SubCounter<X/P1P1> | CostDesc$ Remove all +1/+1 counters from Vish Kal: | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ -ChosenX | NumDef$ -ChosenX | IsCurse$ True | SpellDescription$ Target creature gets -1/-1 until end of turn for each +1/+1 counter removed this way.
SVar:Y:Sacrificed$CardPower
SVar:X:XChoice.All
SVar:RemAIDeck:True
SVar:Rarity:Rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/vish_kal_blood_arbiter.jpg
SetInfo:COM|Rare|http://magiccards.info/scans/en/cmd/234.jpg
Oracle:Flying, lifelink\nSacrifice a creature: Put X +1/+1 counters on Vish Kal, Blood Arbiter, where X is the sacrificed creature's power.\nRemove all +1/+1 counters from Vish Kal: Target creature gets -1/-1 until end of turn for each +1/+1 counter removed this way.
End
Last edited by moomarc on 05 Dec 2011, 09:24, edited 1 time in total.
-Marc
-
moomarc - Pixel Commander
- Posts: 2091
- Joined: 04 Jun 2010, 15:22
- Location: Johannesburg, South Africa
- Has thanked: 371 times
- Been thanked: 372 times
Re: Card Development Questions
by SoulStorm » 05 Dec 2011, 09:21
Thanks for all the effort moomarc. Sounds like we have one more task for our kindly souls to put on their never-ending list.
Who is online
Users browsing this forum: No registered users and 40 guests