Card Development Questions
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins
Re: Card Development Questions
by friarsol » 17 Mar 2011, 02:40
The last time I tried working on it, I almost had it fixed. I'll try to take a crack at it the next time I get some coding time.
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Card Development Questions
by Hellfish » 17 Mar 2011, 10:01
I've gotten as far as seeing that the entire spell fizzles because there is no target for the ReturnCreature drawback. For most triggers, targeting happens when it's put on stack, and I don't think that that code checks wether the subabilities need to target. I am not at home right now and cannot verify, but could you try using Hidden$ True (I think that's it, the parameter that specifies that the target be chosen on resolution). It's a long-shot but still.Jaedayr wrote:Hmm, I made the change you suggested and now it does not exile or trigger the drawback. Now what?Hellfish wrote:should be a drawback. i.e
- Code: Select all
SVar:ReturnCreature:AB$ChangeZone | Cost$ 0 | Origin$ Graveyard | Destination$ Hand | TgtPrompt$ Select target creature card in your graveyard | ValidTgts$ Creature.YouCtrl | SpellDescription$ Return target creature card from your graveyard to your hand.
- Code: Select all
SVar:ReturnCreature:DB$ChangeZone | Origin$ Graveyard | Destination$ Hand | TgtPrompt$ Select target creature card in your graveyard | ValidTgts$ Creature.YouCtrl
So now you're
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
-
Hellfish - Programmer
- Posts: 1297
- Joined: 07 Jun 2009, 10:41
- Location: South of the Pumphouse
- Has thanked: 110 times
- Been thanked: 169 times
Re: Card Development Questions
by Jaedayr » 17 Mar 2011, 17:37
Tried Hidden$ True and did not get the exile or the return from graveyard. I have Acid Web Spider in the graveyard, in case there is something happening with that card.
Re: Card Development Questions
by friarsol » 17 Mar 2011, 21:35
Hidden$ True needs different parameters. Does trigger follow down subAbilities to check if anything else needs to target?
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Card Development Questions
by Hellfish » 17 Mar 2011, 21:52
Nope, that is likely the issue. Still not at home, but I'll give it a whack with the blunt end of IDEA soon.
So now you're
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
-
Hellfish - Programmer
- Posts: 1297
- Joined: 07 Jun 2009, 10:41
- Location: South of the Pumphouse
- Has thanked: 110 times
- Been thanked: 169 times
Re: Card Development Questions
by jeffwadsworth » 17 Mar 2011, 22:26
Here is script for Lethal Vapors.
- Code: Select all
Name:Lethal Vapors
ManaCost:2 B B
Types:Enchantment
Text:no text
A:AB$ Destroy | Cost$ 0 | Defined$ Self | AnyPlayer$ True | SubAbility$ SVar=DBSkipTurn | SpellDescription$ Destroy CARDNAME. You skip your next turn. Any player may activate this ability.
T:Mode$ ChangesZone | ValidCard$ Creature | Origin$ Any | Destination$ Battlefield | TriggerZones$ Battlefield | Execute$ TrigDestroy | TriggerDescription$ Whenever a creature enters the battlefield, destroy it.
SVar:TrigDestroy:AB$Destroy | Cost$ 0 | Defined$ TriggeredCard
SVar:DBSkipTurn:DB$AddTurn | NumTurns$ 1 | Defined$ You
SVar:Rarity:Rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/lethal_vapors.jpg
End
- jeffwadsworth
- Super Tester Elite
- Posts: 1172
- Joined: 20 Oct 2010, 04:47
- Location: USA
- Has thanked: 287 times
- Been thanked: 70 times
Re: Card Development Questions
by SoulStorm » 18 Mar 2011, 06:23
Having difficulty with Overburden. Whenever I start Forge I receive the following error:
java.lang.NullPointerException
at forge.Card.addTrigger(Card.java:209)
at forge.ReadCard.loadCard(ReadCard.java:234)
at forge.ReadCard.run(ReadCard.java:119)
at forge.card.cardFactory.CardFactory.readCards(CardFactory.java:130)
at forge.card.cardFactory.CardFactory.<init>(CardFactory.java:99)
at forge.AllZone.<clinit>(AllZone.java:33)
at forge.Gui_NewGame$2.run(Gui_NewGame.java:149)
at java.awt.event.InvocationEvent.dispatch(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)
java.lang.RuntimeException: CardFactory : readCards() thread error - null
at forge.card.cardFactory.CardFactory.readCards(CardFactory.java:134)
at forge.card.cardFactory.CardFactory.<init>(CardFactory.java:99)
at forge.AllZone.<clinit>(AllZone.java:33)
at forge.Gui_NewGame$2.run(Gui_NewGame.java:149)
at java.awt.event.InvocationEvent.dispatch(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)
java.lang.NullPointerException
at forge.Card.addTrigger(Card.java:209)
at forge.ReadCard.loadCard(ReadCard.java:234)
at forge.ReadCard.run(ReadCard.java:119)
at forge.card.cardFactory.CardFactory.readCards(CardFactory.java:130)
at forge.card.cardFactory.CardFactory.<init>(CardFactory.java:99)
at forge.AllZone.<clinit>(AllZone.java:33)
at forge.Gui_NewGame$2.run(Gui_NewGame.java:149)
at java.awt.event.InvocationEvent.dispatch(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)
java.lang.RuntimeException: CardFactory : readCards() thread error - null
at forge.card.cardFactory.CardFactory.readCards(CardFactory.java:134)
at forge.card.cardFactory.CardFactory.<init>(CardFactory.java:99)
at forge.AllZone.<clinit>(AllZone.java:33)
at forge.Gui_NewGame$2.run(Gui_NewGame.java:149)
at java.awt.event.InvocationEvent.dispatch(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)
- Code: Select all
Name:Overburden
ManaCost:1 U
Types:Enchantment
Text:no text
T:Mode$ ChangeZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.nonToken+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigBounceYou | TriggerDescription$ Whenever a player puts a nontoken creature onto the battlefield, that player returns a land he or she controls to its owner's hand.
T:Mode$ ChangeZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.nonToken+YouDontCtrl | TriggerZones$ Battlefield | Execute$ TrigBounceOpp | Secondary$ True | TriggerDescription$ Whenever a player puts a nontoken creature onto the battlefield, that player returns a land he or she controls to its owner's hand.
SVar:TrigBounceYou:AB$ ChangeZone | Cost$ 0 | Origin$ Battlefield | Destination$ Hand | ValidTgts$ Land.YouCtrl | ChangeNum$ 1 | TgtPrompt$ Select target land | Defined$ You
SVar:TrigBounceOpp:AB$ ChangeZone | Cost$ 0 | Origin$ Battlefield | Destination$ Hand | ChangeType$ Land.YouDontCtrl | ChangeNum$ 1 | Defined$ Opponent | Hidden$ True
SVar:RemAIDeck:True
SVar:Rarity:Rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/overburden.jpg
End
Re: Card Development Questions
by Hellfish » 18 Mar 2011, 07:59
Mode$ should be ChangesZone. Note the s 

So now you're
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
-
Hellfish - Programmer
- Posts: 1297
- Joined: 07 Jun 2009, 10:41
- Location: South of the Pumphouse
- Has thanked: 110 times
- Been thanked: 169 times
Re: Card Development Questions
by SoulStorm » 18 Mar 2011, 10:32
Huh, somehow I never noticed that the trigger uses ChangesZone instead of ChangeZone. Thanks Hellfish!
Re: Card Development Questions
by jeffwadsworth » 18 Mar 2011, 17:01
Script for Daru Spiritualist:
- Code: Select all
Name:Daru Spiritualist
ManaCost:1 W
Types:Creature Human Cleric
Text:no text
PT:1/1
T:Mode$ SpellAbilityCast | TargetsValid$ Cleric.YouCtrl | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever a Cleric creature you control becomes the target of a spell or ability, it gets +0/+2 until end of turn.
SVar:TrigPump:AB$Pump | Cost$ 0 | Defined$ TriggeredTarget | NumDef$ +2
SVar:Rarity:Common
SVar:Picture:http://www.wizards.com/global/images/magic/general/daru_spiritualist.jpg
End
- jeffwadsworth
- Super Tester Elite
- Posts: 1172
- Joined: 20 Oct 2010, 04:47
- Location: USA
- Has thanked: 287 times
- Been thanked: 70 times
Re: Card Development Questions
by slapshot5 » 18 Mar 2011, 17:05
SpellCast doesn't define the target variable at the moment.jeffwadsworth wrote:Script for Daru Spiritualist:Is there an issue with AB$ Pump and Defined$ TriggerTarget? The trigger goes off by the pump is never executed on the cleric.
- Code: Select all
Name:Daru Spiritualist
ManaCost:1 W
Types:Creature Human Cleric
Text:no text
PT:1/1
T:Mode$ SpellAbilityCast | TargetsValid$ Cleric.YouCtrl | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever a Cleric creature you control becomes the target of a spell or ability, it gets +0/+2 until end of turn.
SVar:TrigPump:AB$Pump | Cost$ 0 | Defined$ TriggeredTarget | NumDef$ +2
SVar:Rarity:Common
SVar:Picture:http://www.wizards.com/global/images/magic/general/daru_spiritualist.jpg
End
-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 friarsol » 19 Mar 2011, 17:07
Some questions/comments for cards that people tried to script but they thought don't work:
Trap Digger: This looks really straightforward to me. The second ability should be:
Foil: I'm not sure what the reason means, but it's incorrect. Fireblast does basically the same thing that Foil would do, just for a different AF. At the very worst we can attach a second AF to it with the alternate cost.
Dominate: Works just like Detonate and many other cards that are written where X is based on the target (Gorilla Shaman was the first of these kind).
Tallowisp: Enchant creature is a keyword. Can't we just use "Aura.withEnchant creature"
Hope and Glory: The subAbility would just use Defined$ Targeted.
Toil to Renown: We don't need to add up each type of permanent, should be something like SVar:X:Count$Valid Artifact.YouCtrl+tapped,Creature.YouCtrl+tapped,Land.YouCtrl+tapped
Puncture Blast: Why would this be a hack? Just give the spell K:Wither . The only thing I'm not sure about is if Wither displays on the card detail panel for spells, but that's an easy fix if that's the case.
Wrap in Flames: This is similar as Hope and Glory. Just use MinTargets$ 0 and MaxTargets$ 3. With a SubAbility$ to Pump Defined$ Targeted.
Disappear: Does this mean the Enchantment gets sent to the graveyard before ChangeZone returns it? If so, that's a bug where the Enchantment shouldn't check it's state until the spell is fully resolved.
Trap Digger: This looks really straightforward to me. The second ability should be:
- Code: Select all
A:AB$DealDamage | Cost$ Sac<1/Land.countersGE1TRAP> | CostDesc$ Sacrifice a land with a trap counter on it: | ValidTgts$ Creature.attacking+withoutFlying | TgtPrompt$ Select target attacking creature without flying | NumDmg$ 3 | SpellDescription$ CARDNAME deals 3 damage to target attacking creature without flying.
Foil: I'm not sure what the reason means, but it's incorrect. Fireblast does basically the same thing that Foil would do, just for a different AF. At the very worst we can attach a second AF to it with the alternate cost.
Dominate: Works just like Detonate and many other cards that are written where X is based on the target (Gorilla Shaman was the first of these kind).
Tallowisp: Enchant creature is a keyword. Can't we just use "Aura.withEnchant creature"
Hope and Glory: The subAbility would just use Defined$ Targeted.
Toil to Renown: We don't need to add up each type of permanent, should be something like SVar:X:Count$Valid Artifact.YouCtrl+tapped,Creature.YouCtrl+tapped,Land.YouCtrl+tapped
Puncture Blast: Why would this be a hack? Just give the spell K:Wither . The only thing I'm not sure about is if Wither displays on the card detail panel for spells, but that's an easy fix if that's the case.
Wrap in Flames: This is similar as Hope and Glory. Just use MinTargets$ 0 and MaxTargets$ 3. With a SubAbility$ to Pump Defined$ Targeted.
Disappear: Does this mean the Enchantment gets sent to the graveyard before ChangeZone returns it? If so, that's a bug where the Enchantment shouldn't check it's state until the spell is fully resolved.
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Card Development Questions
by jeffwadsworth » 19 Mar 2011, 22:01
I was fooling around in another section, but will look at the above cards.
Here is a sample script for Foil. Doesn't work.
Here is a sample script for Foil. Doesn't work.
- Code: Select all
Name:Foil
ManaCost:2 U U
Types:Instant
Text:no text
A:SP$ Counter | Cost$ 2 U U | Type$ Spell | Destination$ Graveyard | SpellDescription$ Counter target spell.
SVar:AltCost:Discard<1/Island> Discard<1/Card>$You may discard an Island card and another card rather than pay CARDNAME's mana cost.
SVar:Rarity:Uncommon
SVar:Picture:http://www.wizards.com/global/images/magic/general/foil.jpg
End
- Code: Select all
An error has occured. You can copy/paste this message or save it to a file.
Please report this, plus what you tried to do, to:
http://www.slightlymagic.net/forum/viewforum.php?f=26
If you don't want to register an account, you can mail it directly to
mtgerror@yahoo.com
Mana_Part : checkMana() error, argument mana is invalid mana, mana - D
Version:
Forge -- official beta: $Date: 2011-01-06 10:34:48 -0600 (Thu, 06 Jan 2011) $, SVN revision: $Revision: 4891 $
OS: Windows 7 Version: 6.1 Architecture: amd64
Java Version: 1.6.0_22 Vendor: Sun Microsystems Inc.
Detailed error trace:
java.lang.RuntimeException: Mana_Part : checkMana() error, argument mana is invalid mana, mana - D
at forge.card.mana.Mana_Part.checkSingleMana(Mana_Part.java:32)
at forge.card.mana.Mana_PartColor.<init>(Mana_PartColor.java:17)
at forge.card.mana.ManaCost.getManaPart(ManaCost.java:293)
at forge.card.mana.ManaCost.split(ManaCost.java:263)
at forge.card.mana.ManaCost.<init>(ManaCost.java:33)
at forge.card.spellability.Cost.changeCost(Cost.java:292)
at forge.card.spellability.Cost_Payment.changeCost(Cost_Payment.java:655)
at forge.GameAction.playSpellAbility(GameAction.java:3216)
at forge.GameAction.playCard(GameAction.java:2712)
at forge.gui.input.Input_PassPriority.selectCard(Input_PassPriority.java:52)
at forge.GuiInput.selectCard(GuiInput.java:49)
at forge.GuiDisplay4$11.mousePressed(GuiDisplay4.java:393)
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.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)
- jeffwadsworth
- Super Tester Elite
- Posts: 1172
- Joined: 20 Oct 2010, 04:47
- Location: USA
- Has thanked: 287 times
- Been thanked: 70 times
Re: Card Development Questions
by Hellfish » 19 Mar 2011, 23:29
I think the double discard cost is the problem there, I ran into something similar trying to implement Viscerid Drone 's double sac costs.
So now you're
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
-
Hellfish - Programmer
- Posts: 1297
- Joined: 07 Jun 2009, 10:41
- Location: South of the Pumphouse
- Has thanked: 110 times
- Been thanked: 169 times
Re: Card Development Questions
by jeffwadsworth » 20 Mar 2011, 20:44
Another card with quirks...
- Code: Select all
Name:Powerstone Minefield
ManaCost:2 R W
Types:Enchantment
Text:no text
T:Mode$ Attacks | ValidCard$ Creature | Execute$ TrigDamageAttacker | TriggerZones$ Battlefield | TriggerDescription$ Whenever a creature attacks or blocks, CARDNAME deals 2 damage to it.
T:Mode$ Blocks | ValidCard$ Creature | Execute$ TrigDamageBlocker | Secondary$ True | TriggerZones$ Battlefield | TriggerDescription$ Whenever a creature attacks or blocks, CARDNAME deals 2 damage to it.
SVar:TrigDamageAttacker:AB$DealDamage | Cost$ 0 | Defined$ TriggeredAttacker | NumDmg$ 2
SVar:TrigDamageBlocker:AB$DealDamage | Cost$ 0 | Defined$ TriggeredBlocker | NumDmg$ 2
SVar:Rarity:Rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/powerstone_minefield.jpg
End
- jeffwadsworth
- Super Tester Elite
- Posts: 1172
- Joined: 20 Oct 2010, 04:47
- Location: USA
- Has thanked: 287 times
- Been thanked: 70 times
Who is online
Users browsing this forum: No registered users and 13 guests