If you read my previous post I asked the question, “How do you condense a Magic card into reusable parts that can be written as text?” There are many answers to this question but I will show you how I plan to do it for MTG Forge version 2. I plan to encode cards using only text.
Assassinate
2 B
Sorcery
Spell
Text: Destroy target tapped creature.
Target: creature
Resolve: destroy target creature
Royal Assassin
1 B B
Creature Human Assassin
1/1
Activated Ability
Text: tap: Destroy target tapped creature.
Cost: tap
Target: tapped creature
Resolve: destroy target creature
This is how cards will be encoded in version 2. Gone are the days of having to know Java. There is a lot of similarity between these two cards. Assassinate and Royal Assassin’s ability both have the same targets and resolve. My goal is to reuse the same Java code for both of these cards. My current way of cutting-and-pasting code is hacky to say the least.
The format above is similar to the current format in cards.txt. I love plaintext because it is so easy to read and understand. I am thrilled with the possibility of being able to encode spells like Assassinate using only plaintext. I realize that the format above won’t work for all cards, like Fire//Ice, but it will work for 90% of them.
This plaintext encoding is also very easy to parse. (Parsing is when the program interprets the plaintext and actually constructs the code for the card.) My goal is to reduce a card into a set of reusable parts. I want multiple cards to use the same targeting and resolve code.
Personally I am very excited about this “discovery.” The plaintext is very readable by both humans and machines. Practically I could add this to MTG Forge version 1 but I’m going to put it into version 2, because version 1 has many bugs.
I already have the experience of programming many Magic cards and I know what needs to be improved. Multiple cards need to use the same code. All cards that say “gain life” should use the exact same code and in version 2 they will.
Like I’ve said before, there are many ways to encode cards as text. My way may not be the best way for someone else, but it is the best way for me. I understand these plaintext cards and I “see” the code in my head. The targeting and resolve code can be separated and I also understand how to connect the targeting code to the resolve code.
p.s.
It seems like I could remove the “text:” line but it greatly simplifies everything by keeping it. My goal is to make parsing as easy as possible and hopefully idiot proof, lol. (Parsing tends to be very complicated and hard to test. And yes regular expressions make parsing easier, but I want it to be very easy. And like all things in MTG Forge, it can be changed later. For all your programmers out there, I call that “very late binding” LOL.)
This plaintext encoding can also work for triggered and static abilities.
Venerable Monk
2 W
Creature Monk
2/2
Triggered Ability
Text: When Venerable Monk comes into play, you gain 2 life.
Trigger: comes into play
Resolve: gains X life – controller, 2
Glorious Anthem
1 W W
Enchantment
Static Ability
Text: Creatures you control get +1/+1.
Effect: creatures you control get X/X, 1, 1
Shock
R
Instant
Spell
Text: Shock deals 2 damage to target creature or player.
Target: creature or player
Resolve: damage target creature or player, 2
Ballista Squad
3 W
Creature Human Rebel
2/2
Activated Ability
Text: XW, tap: Ballista Squad deals X damage to target attacking or blocking creature.
Cost: X W
Cost: tap
Target: attacking or blocking creature
Resolve: damage target creature – X paid
Mobilization
2 W
Enchantment
Static Ability
Effect: your creatures (subtype X) have keyword X, soldier, vigilance
Activated Ability
Cost: 2 W
Resolve: create token, 1, 1, soldier, W
You should be careful because for example for Royal Assassin his ability also checks on the resolve if the creature is still tapped.
ReplyDeleteIt is not only the targeting restriction.
The good thing of this is that all of us could help you and get all the cards coded (at least the easier ones)
ReplyDeleteSeems difficult to me, though
i hope the examples were not exactly as you imagine them. in whole, it's a good idea, but you should be careful with using the targeting restrictions in the resolve part. for example, ballista squad says "attacking or blocking creature" in the target but only "target creature" in the resolve. parsing that is maybe not that simple
ReplyDeletealso, for finding cards by properties (creatures you control, cards in your graveyard...), i think you should use a more generic ability.
the "creatures you control get X/X" ability is very specific. it doesn't even allow night of souls betrayal. I imagine cards(controler=you,type=creature) or something like this.
the same could easily be done for targeting. it would mean to target one card matching the criterion, which would be also checked on resolution.
Making these generic abilities is easy as long as they're uniform in targeting. It's providing for these cases where there are many different restriction combinations....
ReplyDeleteCreatures you control is easy. All Creatures is easy. All Black Creatures is moderate. Black Elf Creatures You Control is getting more difficult. And those are just dealing with color, type and controller, the most very basic restrictions. Throw tapped into the mix, and wait for hell to freeze.... Reading this information is no problem. It's using this information later to form the spell abilities in code where it gets sticky. When I tried to implement a fraction of what Forge is talking about, I ended up with so many nested if-then-else blocks that I lost track of what I was trying to do in the first place 100 lines ago.
"You should be careful because for example for Royal Assassin his ability also checks on the resolve if the creature is still tapped.
ReplyDeleteIt is not only the targeting restriction."
True, I sometimes forget the the legality of a target is also checked before the card is resolved.
"i hope the examples were not exactly as you imagine them."
Sorry to burst your bubble, but yeah. I'm not saying that I will only use this kind of formatting but to begin with I plan to program cards this way.
I'm just trying to reduce a large number of cards and spells into text, I'm not planning on reducing every card into a text format. I the future I'll probably use XML also.
i didn't mean that your notation is bad. i like the splitting of cost, target and effect, which reflects the actions really taken. i just meant that you should be careful with the targets in your effects section.
ReplyDeleteif the target is "attacking or blocking creature" you also have to destroy "target attacking or blocking creature". if you skip "attacking or blocking" you could also just say "destroy target"
Well maybe Royal Assassin's resolve should say.
ReplyDeleteResolve: destory target tapped creature
All this is a little bit hypothetical and I haven't worked out all the details and problems that can and will occur.