Monday, February 8, 2010

Scripted Cards

There are two ways to add to implement a card in Forge. One, you code it in Java. Two, you encode it using regular text, these types of cards are referred to as "scripted cards". Forge uses the file "cards.txt" to hold most of the card text, the text for most activated abilities is hardcoded elsewhere in Java.

OK, enough boring explanation, let me show you some examples from "cards.txt".

Eyeblight's Ending
2 B
Tribal Instant Elf
Destroy target non-Elf creature.
spDestroyTgt:Creature.nonElf

The card Eyeblight's Ending was implemented in Forge by only the above text, no other programming was necessary. In case you can't figure out what spDestroyTgt, it means "spell destroy target".

Miscalculation
1 U
Instant
Counter target spell unless its controller pays 2.
Cycling:2

This card is implemented by both scripting and Java. The scripting adds the cycling ability and elsewhere in the program Java is used to implement the counter spell.

Burning Fields
4 R
Sorcery
no text
spDamageTgtOpp:5:Burning Fields deals 5 damage to target opponent.:Burning Fields - deals 5 damage

Searing Flesh
6 R
Sorcery
no text
spDamageTgtOpp:7:Searing Flesh deals 7 damage to target opponent.:Searing Flesh - deals 7 damage

Scripting makes it easy to add multiple cards that do the same thing, like the two cards above.

The reason that these cards have the line "no text" is because that line of text is used for static abilities and sorceries/instants.


Kiss of Death
4 B B
Sorcery
no text
spDamageTgtOpp:4:Drawback$YouGainLife/4:Kiss of Death deals 4 damage to target opponent. You gain 4 life.:Kiss of Death - deals 4 damage; you gain 4 life.

Scripting can become complicated.

Eternal Flame
2 R R
Sorcery
no text
spDamageTgtOpp:Count$NumTypeYouCtrl.Mountain:Drawback$DamageYou/X.HalfUp:Eternal Flame deals X damage to target opponent where X is the number of mountains you control. It deals half X damage, rounded up, to you.:Eternal Flame - deals X damage and half X damage to you.

And scripting can become very complicated. I'm very impressed that such a complex card can be added so easily. (Easier than coding it in Java and easy only if you know how the spDamageTgtOpp keyword works.)

Scripting is very powerful and useful because it can be used to add many similar types of spells. Scripting is much shorter than using Java itself. Scripting is sort of "condensed Java" and is an example of a domain specific language, commonly referred as DSL.

Since scripting is such a fun topic, I'll be talking more about it on Wednesday. (Yes, I said that I wasn't going to post two times a week and I may not post next Wednesday but this Wednesday I’m going to post something.)

And I feel like I haven't injected enough humor into this article so I'll close by saying that scripting is better than chocolate covered bacon, hm....bacon. (I'm also a big Simpson fan.)

p.s.
I haven't done any of the real work when it comes to scripting. Yes, I did create very simple keywords like haste and trample but nothing complicated. All of the credit goes to Dennis, Rob, and the other guys at the forums.

For more info on Forge's scripting please consult the forums. (Thankfully we have a forum so you can ask questions.) Thanks to huggybaby for providing a forum for Forge and other Magic projects.

p.p.s.
And in case you are wondering, all mana costs in Forge have extra spaces in them, “3 W W ” versus “3WW” because it makes the coding easier. (The extra spaces makes the parsing very easy.)

2 comments:

DennisBergkamp said...

Rob has been busy adding and expanding functionality of his existing keywords, he's added most of them.

There's quite a few cards right now that are exclusively supported through keywords, especially damage/draw/discard effects, which I have always found painful to code, so that's a very good thing :)

I've added a few triggered keywords (Whenever this card ... / Whenever this creature ...), more recently I've also rewritten some of the mana lands/creatures that add mana based on permanents in play/control of a certain type.
(Priest of Titania / Gaea's Cradle / Tolarian Academy, etc.).
It uses Rob's xCount method, and it allows Priest of Titania and Serra's Sanctum to be scripted like this:

Priest of Titania
1 G
Creature Elf Druid
no text
1/1
tap: add G to your mana pool for each Elf on the battlefield.

Serra's Sanctum
no cost
Legendary Land
no text
tap: add W to your mana pool for each Enchantment you control.

Forge said...

It seems best to script as many cards as possible although I know it is hard to know how flexible (nad hard to program) to make each keyword.

Combining keywords could be tricky also.