It is currently 21 Oct 2020, 13:56
   
Text Size

Card Development Questions

Post MTG Forge Related Programming Questions Here

Moderators: timmermac, friarsol, Blacksmith, KrazyTheFox, Agetian, CCGHQ Admins

Re: Card Development Questions

Postby Marek14 » 23 Dec 2014, 17:07

HarePaiR wrote:Ah, I see. So if not all damage is being prevented, you should be able to choose which damage, among simultaneous damage sources, gets prevented. I didn't even know you could do that! I assumed there was always some order. Thanks for the rules knowledge!

Isn't that also true for all the en-Kor, though? For example, redirecting deathtouch damage from a black source to a White Knight? I guess that's rather narrow, and I quite like having the en-Kor available.
Yes, this rule should theoretically apply to every damage prevention/redirection with specific properties (usually preventing limited amount of damage and not specifying that it must come from a specific source).

It's not the most obscure interaction (that might be that Doubling Season won't affect tokens created by using Words of Wilding on your normal turn draw), but still a troublesome one.

Ideally, something like the screen for distributing combat damage should exist for applying damage prevention and redirection (and other replacements). You'd select which effect to apply, made choices for it, if possible, then select another effect, until everything is resolved.

True Rock Hydra implementation would also only prevent 1 damage and could be used many times until you run out of either damage or counters. Not sure how your code handles unpreventable damage -- it should cause counter removal in any case.
Marek14
Tester
 
Posts: 2679
Joined: 07 Jun 2008, 07:54
Has thanked: 0 time
Been thanked: 271 times

Re: Card Development Questions

Postby HarePaiR » 23 Dec 2014, 17:31

Marek14 wrote:True Rock Hydra implementation would also only prevent 1 damage and could be used many times until you run out of either damage or counters.
This is definitely what I was going for. When taking damage, take one of it at a time, and only take real (remaining) damage if I run out of counters. Not sure if there's something wrong with how I wrote the script or if it's not currently scriptable in that way.

Marek14 wrote:Not sure how your code handles unpreventable damage -- it should cause counter removal in any case.
This is also something I was worried about. I sort of assumed that with the PreventionEffect$ True flag that would be handled by the general prevention code, as Phantom Nishoba etc. are considered scripted and use the same language.
HarePaiR
 
Posts: 20
Joined: 02 Dec 2014, 11:13
Has thanked: 10 times
Been thanked: 2 times

Re: Card Development Questions

Postby Hexadecimal » 09 Feb 2015, 14:47

Is there are a similar keyword for dig as NoReveal for mill ? I want to disable some unneeded prompt window.
Hexadecimal
 
Posts: 69
Joined: 08 Oct 2013, 20:36
Has thanked: 6 times
Been thanked: 2 times

Re: Card Development Questions

Postby friarsol » 09 Feb 2015, 15:22

Hexadecimal wrote:Is there are a similar keyword for dig as NoReveal for mill ? I want to disable some unneeded prompt window.
Try "NoLooking"
friarsol
Global Moderator
 
Posts: 7552
Joined: 15 May 2010, 04:20
Has thanked: 242 times
Been thanked: 952 times

Re: Card Development Questions

Postby Hexadecimal » 09 Feb 2015, 15:37

Thanks friarsol, it worked.
Hexadecimal
 
Posts: 69
Joined: 08 Oct 2013, 20:36
Has thanked: 6 times
Been thanked: 2 times

Re: Card Development Questions

Postby Alvy01 » 16 Mar 2015, 13:47

Hey everyone, sorry if I posted this in the wrong place I have just recently discovered Forge and I'm loving it. I am trying to learn the scripting language in order to make a custom set to be used to play with a couple friends of mine and I seem to have run into a problem with a custom Planeswalker I am making.The first two abilities work fine but the problem is the ultimate ability for the planeswalker, I want it to be as follows "You get an emblem with "At the beginning of you upkeep, Populate."" So far I have been able to make it start every upkeep and ask for the player to choose a token, but the emblem never actually puts the copy into play can anyone take a look at the code and see if you can help me out?

Name:Bryla, Faery Queen

ManaCost:2 G W

Types:Planeswalker Bryla

Loyalty:4

A:AB$ Token | Cost$ AddCounter<2/LOYALTY> | TokenAmount$ 2 | TokenName$ Dryad Fae |
TokenTypes$ Creature,Dryad,Fae | TokenOwner$ You | TokenColors$ Green | TokenPower$ 1 |
TokenToughness$ 1 | Planeswalker$ True | TokenImage$ g_1_1_dryad_fae | SpellDescription$
Put two green 1/1 Dryad Fae creature tokens onto the battlefield.

A:AB$ GainLife | Cost$ SubCounter<2/LOYALTY> | LifeAmount$ X | ValidTgts$ You | Defined$
You | References$ X | SpellDescription$ You gain 1 life for each creature you control.
SVar:X:TargetedPlayer$CreaturesInPlay

A:AB$ Effect | Cost$ SubCounter<6/LOYALTY> | Planeswalker$ True | Ultimate$ True | Name$
Elspeth, Sun's Champion emblem | Image$ elspeth_suns_champion_emblem | Triggers$ EOTTrig |
SVars$ BrylaEmblem | Duration$ Permanent | SpellDescription$ You get an emblem with "At
the beginning of your upkeep Populate."
SVar:EOTTrig:Mode$ Phase | Phase$ Upkeep |
ValidPlayer$ You | TriggerZones$ Command | Execute$ BrylaEmblem | TriggerDescription$ At
the beginning of your upkeep Populate.SVar:BrylaEmblem:AB$ ChooseCard | Cost$ 0 | Defined$
You | Amount$ 1 | Choices$ Creature.token+YouCtrl | SubAbility$ DBCopy | Mandatory$ True |
RememberChosen$ True
SVar:DBCopy:DB$ CopyPermanent | Defined$ Remembered | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True



Oracle:[+2] Put two 1/1 green fae dryad creature tokens onto the battlefield.\n[-2] You
gain 1 life for each creature you control.\n[-7] At the beginning of your upkeep,
populate. (Put a token onto the battlefield that's a copy of a creature token you
control.)
Alvy01
 
Posts: 9
Joined: 16 Mar 2015, 13:39
Has thanked: 3 times
Been thanked: 0 time

Re: Card Development Questions

Postby friarsol » 16 Mar 2015, 15:08

Alvy01 wrote:Hey everyone, sorry if I posted this in the wrong place I have just recently discovered Forge and I'm loving it. I am trying to learn the scripting language in order to make a custom set to be used to play with a couple friends of mine and I seem to have run into a problem with a custom Planeswalker I am making.The first two abilities work fine but the problem is the ultimate ability for the planeswalker, I want it to be as follows "You get an emblem with "At the beginning of you upkeep, Populate."" So far I have been able to make it start every upkeep and ask for the player to choose a token, but the emblem never actually puts the copy into play can anyone take a look at the code and see if you can help me out?


A:AB$ Effect | Cost$ SubCounter<6/LOYALTY> | Planeswalker$ True | Ultimate$ True | Name$
Elspeth, Sun's Champion emblem | Image$ elspeth_suns_champion_emblem | Triggers$ EOTTrig |
SVars$ BrylaEmblem | Duration$ Permanent | SpellDescription$ You get an emblem with "At
the beginning of your upkeep Populate."
The problem is the only SVar you are creating on the Effect is "BrylaEmblem" you also need to pass in DBCopy and DBCleanup.

SVars$ BrylaEmblem,DBCopy,DBCleanup
friarsol
Global Moderator
 
Posts: 7552
Joined: 15 May 2010, 04:20
Has thanked: 242 times
Been thanked: 952 times

Re: Card Development Questions

Postby Alvy01 » 16 Mar 2015, 15:16

Thank you very much for your quick reply. I made the change you suggested and I am now getting this error, I'm not sure what it means.
Attachments
2015-03-16-00.txt
Description: [describe what you were doing when the crash occurred]

[spoiler=RuntimeException][code]
Forge Version: 1.5.37-SNAPSHOT-r-1
Operating System: Windows 8.1 6.3 amd64
Java Version: 1.8.0_31 Oracle Corporation

java.lang.RuntimeException: TriggerFactory Parsing Error in registerTrigger() : Split length of TriggerDescription$ At the beginning of your upkeep Populate.SVar:BrylaEmblem:AB$ ChooseCard is not 2.
at forge.game.trigger.TriggerHandler.parseParams(TriggerHandler.java:189)
at forge.game.trigger.TriggerHandler.parseTrigger(TriggerHandler.java:143)
at forge.game.ability.effects.EffectEffect.resolve(EffectEffect.java:144)
at forge.game.ability.AbilityApiBased.resolve(AbilityApiBased.java:60)
at forge.game.ability.AbilityUtils.resolveApiAbility(AbilityUtils.java:1234)
at forge.game.ability.AbilityUtils.resolve(AbilityUtils.java:1216)
at forge.game.zone.MagicStack.resolveStack(MagicStack.java:466)
at forge.game.phase.PhaseHandler.startFirstTurn(PhaseHandler.java:972)
at forge.game.GameAction.startGame(GameAction.java:1390)
at forge.game.Match.startGame(Match.java:96)
at forge.match.HostedMatch$2.run(HostedMatch.java:223)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
[/code][/spoiler]
(1.35 KiB) Downloaded 113 times
Alvy01
 
Posts: 9
Joined: 16 Mar 2015, 13:39
Has thanked: 3 times
Been thanked: 0 time

Re: Card Development Questions

Postby friarsol » 16 Mar 2015, 15:25

Your end lines were all messed up when you posted it to the forums. Random endlines were added, and one very important one was removed in between the Effect line and the Trigger SVar line.

Code: Select all
A:AB$ Effect | Cost$ SubCounter<6/LOYALTY> | Planeswalker$ True | Ultimate$ True | Name$ Elspeth, Sun's Champion emblem | Image$ elspeth_suns_champion_emblem | Triggers$ EOTTrig | SVars$ BrylaEmblem,DBCopy,DBCleanup | Duration$ Permanent | SpellDescription$ You get an emblem with "At the beginning of your upkeep Populate."
SVar:EOTTrig:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Command | Execute$ BrylaEmblem | TriggerDescription$ At the beginning of your upkeep, Populate.
SVar:BrylaEmblem:AB$ ChooseCard | Cost$ 0 | Defined$ You | Amount$ 1 | Choices$ Creature.token+YouCtrl | SubAbility$ DBCopy | Mandatory$ True | RememberChosen$ True
SVar:DBCopy:DB$ CopyPermanent | Defined$ Remembered | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
friarsol
Global Moderator
 
Posts: 7552
Joined: 15 May 2010, 04:20
Has thanked: 242 times
Been thanked: 952 times

Re: Card Development Questions

Postby Alvy01 » 16 Mar 2015, 15:31

Thank you so much for your help and quick replies. It is now working perfectly. Hopefully, I won't be running into very many more issues anytime soon.
Alvy01
 
Posts: 9
Joined: 16 Mar 2015, 13:39
Has thanked: 3 times
Been thanked: 0 time

Re: Card Development Questions

Postby Midori » 16 Mar 2015, 16:42

Hi, since no1 claimed Living Lore up to this time and i am really interested in working with this card, i tried to script it myself, and possibly help to contribute to the upcomming release.
But since im not to confident about my scriptings, i tried to make it work before claiming anything.
Apparently i messed up big times with my attempt to script Living Lore and i have no clue where i went wrong.
Code: Select all
Name:Living Lore
ManaCost:3 U
Types:Creature Avatar
P/T:*/*
K:ETBReplacement:Copy:ChooseSpell
SVar:ChooseSpell:DB$ ChooseCard | Defined$ You | Amount$ 1 | Choices$ Sorcery.YouOwn,Instant.YouOwn | ChoiceTitle$ Exile a instant or sorcery card from your graveyard. ChoiceZone$ Graveyard | RemenberChoosen$ True | SubAbility$ ExileSpell |SpellDescription$ As CARDNAME enters the battlefield, exile a instant or sorcery card from your graveyard. CARDNAME's power and toughness are each equal to the exiled card's converted mana cost.
SVar:ExileSpell:DB$ ChangeZone | ChangeType$ Remembered | Origin$ Graveyard | Destination$ Exile | SubAbility$ AnimateLore
SVar:AnimateLore:DB$ Animate | Defined$ Self | Power$ TotalPT | Toughness$ TotalPT | Permanent$ True | References$ TotalPT
SVar:TotalPT:Remembered$CardManaCost
T:Mode$ DealtCombatDamageOnce | ValidSource$ Self | Execute$ TrigSacLore | TriggerZones$ Battlefield | TriggerDescription: Whenever CARDNAME deals combat damage, you may sacrifice it. If you do, you may cast the exiled card without paying its mana cost.
SVar:TrigSacLore:AB$ Play | Cost$ Sac<1/CARDNAME> | Defined$ Remembered | Amount$ All | Controller$ You | WithoutManaCost$ True | Optional$ True | ForgetRemembered$ True
SVar:RemRandomDeck:True
I used Sutured Ghoul as reference and i was pretty confident it could work. But all i get is a error in the deckeditor, telling me something about the first ability "isnt 2"?. I would really appreciate if someone could look over this script and tell me where i went wrong or if i just produced a big jam of unworkable code.
Midori
 
Posts: 55
Joined: 20 Apr 2014, 12:43
Has thanked: 1 time
Been thanked: 4 times

Re: Card Development Questions

Postby Marek14 » 16 Mar 2015, 16:58

Well, I see a few problems with the ability:
1. Lack of | between ChoiceTitle$ and ChoiceZone$
2. RemenberChoosen$ instead of RememberChosen$
Marek14
Tester
 
Posts: 2679
Joined: 07 Jun 2008, 07:54
Has thanked: 0 time
Been thanked: 271 times

Re: Card Development Questions

Postby Midori » 16 Mar 2015, 17:24

I "hopefully" fixed the problems, but i still get this error
RuntimeException | Open
Code: Select all
Forge Version:    1.5.34-r-1
Operating System: Windows XP 5.1 x86
Java Version:     1.7.0_51 Oracle Corporation

java.lang.RuntimeException: TriggerFactory Parsing Error in registerTrigger() : Split length of TriggerDescription: Whenever CARDNAME deals combat damage, you may sacrifice it. If you do, you may cast the exiled card without paying its mana cost. is not 2.
   at forge.game.trigger.TriggerHandler.parseParams(TriggerHandler.java:177)
   at forge.game.trigger.TriggerHandler.parseTrigger(TriggerHandler.java:131)
   at forge.game.card.CardFactory.readCardFace(CardFactory.java:405)
   at forge.game.card.CardFactory.readCard(CardFactory.java:369)
   at forge.game.card.CardFactory.getCard(CardFactory.java:227)
   at forge.game.card.CardFactory.getCard(CardFactory.java:222)
   at forge.game.card.Card.fromPaperCard(Card.java:6329)
   at forge.game.card.Card.getCardForUi(Card.java:6337)
   at forge.game.card.CardView.getCardForUi(CardView.java:45)
   at forge.screens.match.controllers.CDetail.showCard(CDetail.java:61)
   at forge.screens.deckeditor.CDeckEditorUI.setCard(CDeckEditorUI.java:70)
   at forge.screens.deckeditor.CDeckEditorUI$8.valueChanged(CDeckEditorUI.java:258)
   at forge.itemmanager.views.ItemView.onSelectionChange(ItemView.java:256)
   at forge.itemmanager.views.ItemListView$ItemTableModel$1.valueChanged(ItemListView.java:571)
   at javax.swing.DefaultListSelectionModel.fireValueChanged(Unknown Source)
   at javax.swing.DefaultListSelectionModel.fireValueChanged(Unknown Source)
   at javax.swing.DefaultListSelectionModel.fireValueChanged(Unknown Source)
   at javax.swing.DefaultListSelectionModel.changeSelection(Unknown Source)
   at javax.swing.DefaultListSelectionModel.changeSelection(Unknown Source)
   at javax.swing.DefaultListSelectionModel.setSelectionInterval(Unknown Source)
   at javax.swing.JTable.changeSelectionModel(Unknown Source)
   at javax.swing.JTable.changeSelection(Unknown Source)
   at javax.swing.plaf.basic.BasicTableUI$Actions.actionPerformed(Unknown Source)
   at javax.swing.SwingUtilities.notifyAction(Unknown Source)
   at javax.swing.JComponent.processKeyBinding(Unknown Source)
   at javax.swing.JTable.processKeyBinding(Unknown Source)
   at javax.swing.JComponent.processKeyBindings(Unknown Source)
   at javax.swing.JComponent.processKeyEvent(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.KeyboardFocusManager.redispatchEvent(Unknown Source)
   at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(Unknown Source)
   at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(Unknown Source)
   at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(Unknown Source)
   at java.awt.DefaultKeyboardFocusManager.dispatchEvent(Unknown Source)
   at java.awt.Component.dispatchEventImpl(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$200(Unknown Source)
   at java.awt.EventQueue$3.run(Unknown Source)
   at java.awt.EventQueue$3.run(Unknown Source)
   at java.security.AccessController.doPrivileged(Native Method)
   at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
   at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
   at java.awt.EventQueue$4.run(Unknown Source)
   at java.awt.EventQueue$4.run(Unknown Source)
   at java.security.AccessController.doPrivileged(Native Method)
   at java.security.ProtectionDomain$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)
Refined Living Lore Code | Open
Code: Select all
Name:Living Lore
ManaCost:3 U
Types:Creature Avatar
P/T:*/*
K:ETBReplacement:Copy:ChooseSpell
SVar:ChooseSpell:DB$ ChooseCard | Defined$ You | Amount$ 1 | Choices$ Sorcery.YouOwn,Instant.YouOwn | ChoiceTitle$ Exile a instant or sorcery card from your graveyard. | ChoiceZone$ Graveyard | RemenberChosen$ True | SubAbility$ ExileSpell |SpellDescription$ As CARDNAME enters the battlefield, exile a instant or sorcery card from your graveyard. CARDNAME's power and toughness are each equal to the exiled card's converted mana cost.
SVar:ExileSpell:DB$ ChangeZone | ChangeType$ Remembered | Origin$ Graveyard | Destination$ Exile | SubAbility$ AnimateLore
SVar:AnimateLore:DB$ Animate | Defined$ Self | Power$ TotalPT | Toughness$ TotalPT | Permanent$ True | References$ TotalPT
SVar:TotalPT:Remembered$CardManaCost
T:Mode$ DealtCombatDamageOnce | ValidSource$ Self | Execute$ TrigSacLore | TriggerZones$ Battlefield | TriggerDescription: Whenever CARDNAME deals combat damage, you may sacrifice it. If you do, you may cast the exiled card without paying its mana cost.
SVar:TrigSacLore:AB$ Play | Cost$ Sac<1/CARDNAME> | Defined$ Remembered | Amount$ All | Controller$ You | WithoutManaCost$ True | Optional$ True | ForgetRemembered$ True
SVar:RemRandomDeck:True
Midori
 
Posts: 55
Joined: 20 Apr 2014, 12:43
Has thanked: 1 time
Been thanked: 4 times

Re: Card Development Questions

Postby Agetian » 16 Mar 2015, 17:30

I think it should be "TriggerDescription$" instead of "TriggerDescription:" (a dollar sign instead of a colon).

- Agetian
Agetian
Programmer
 
Posts: 3387
Joined: 14 Mar 2011, 05:58
Has thanked: 653 times
Been thanked: 507 times

Re: Card Development Questions

Postby Midori » 16 Mar 2015, 18:07

Marek14 wrote:Well, I see a few problems with the ability:
1. Lack of | between ChoiceTitle$ and ChoiceZone$
2. RemenberChoosen$ instead of RememberChosen$
Agetian wrote:I think it should be "TriggerDescription$" instead of "TriggerDescription:" (a dollar sign instead of a colon).

- Agetian
Ok this fixed the error in the deck editor, but the card still doesnt work as intended (and it has absolutely no text on it).
When it enters the battlefield, i get to choose a Instant or Sorcery but Living Lore dies instantly.
Midori
 
Posts: 55
Joined: 20 Apr 2014, 12:43
Has thanked: 1 time
Been thanked: 4 times

PreviousNext

Return to Developer's Corner

Who is online

Users browsing this forum: No registered users and 21 guests


Who is online

In total there are 21 users online :: 0 registered, 0 hidden and 21 guests (based on users active over the past 10 minutes)
Most users ever online was 1371 on 09 Feb 2020, 16:22

Users browsing this forum: No registered users and 21 guests

Login Form