Version 2 is progressing nicely and I although I haven’t gotten to the point of actually programming cards yet I have a set of 10 cards that I am refining on paper. I’m going to only show you 4 of those cards because I don’t want to bore you.
Writing cards in this format is easy and even nonprogrammers should be able to add a card or two. All the cards will be in one directory and each card will be in a separate file. So if someone else writes a card, all you have to do is download the file and put it in your card directory.
It seems like I could write a simple Card Maker application that would check your card text for errors and would allow you to choose the target and resolve from a list of all available choices, without making you cut-and-paste. The card format below won’t work for all Magic cards but it will work for most of them.
p.s. I put extra information at the end of the resolve text after the comma. You should notice that both Shock and Prodigal Pyromancer share the same targets and resolves, my heart jumps with happiness, code reuse is good.
Shock.txt
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
Prodigal_Pyromancer.txt
Prodigal Pyromancer
2 R
Creature Human Wizard
1/1
Activated Ability
Text: tap: Prodigal Pyromancer deals 1 damage to target creature or player.
Cost: tap
Resolve: damage target creature or player, 1
Venerable_Monk.txt
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: gain life – controller, 2
Holy_Strength.txt
Holy Strength
W
Enchant Creature
Static Ability
Text: Enchanted creature gets +1/+2.
Effect: enchanted creature gets, +1/+2
Text: Shock deals 2 damage to target creature or player.
ReplyDeleteTarget: creature or player
Resolve: damage target creature or player, 2
I smell redundancy
Well then, eve, you should come up with something better.
ReplyDelete@anonymous: Text on M:tG cards uses a simple subset of English language, so it seems possible to write a parser for it.
ReplyDeleteI agree with e.v.e. If you parse the card rules text it means that players can add cards by transcribing the card rules text verbatim - no need for the player to translate it into an intermediate format.
ReplyDeleteIn fact, thinking about it, with an automatic parser - I reckon you could make your cards from the information available in gatherer - no need to program a single magic card yourself!
I'd agree with eve... here's my take:
ReplyDeleteShock
R
Instant
Shock deals 2 damage to target creature or player.
Spell
Text: Shock deals 2 damage to {Target}.
Target: Creature|Player
Resolve: SingleTargetDamage,2
There should be a difference between the card's printed/oracle text and the stack text. The stack text can/should include the chosen target. The target list can be parsed using the String.split() method, which I guess, you could still do with the word "or" as the delimiter. You should also have a "Restriction:" option like for Terror -
Target: Creature
Restriction: NonBlack&NonArtifact
Parsing text as free-form as "damage target creature or player, 2" is going to be nightmaresih.... It's difficult enough to parse well-structured text. And while it would be really cool to parse a "subset of the English language" I don't think it's possible beyond some REALLY basic stuff.... Like a self-pump spell, sure. Shock, yes. "Draw a card", sure. But not a heck of a lot else.
Something no one else has mentioned, is how well this opens up the ability of MTGForge to support other languages. Just translate the text parts of the card files.
I'm also thinking we should change our source of card pics to magiccards.info - slightly higher resolution, and I think they have the different languages available.
ReplyDeleteMy preference would be to keep the size/format the same for card pics. Maybe there could be a preference option to change it.
ReplyDelete@tim, this would be really really difficult to do.
ReplyDeleteWow, those are some nice quality images, Rob. I definitely vote for getting images from there.
My take on redundancy, a la e.v.e, is this:
ReplyDeleteThe Text line is for display purposes, and doesn't influence the game play. So redundancy between the Text and the other lines is not necessarily something you could, or would, want to eliminate.
I'm not sure of all the neuron settings inside Forge's head, so I'm not sure how he plans to use the text in the Target and Resolve lines. I personally would want the Resolve to say "damage target, 2", where 'target' indicates to use the previously selected target.
As for parsing a "simple subset of the English language", I would agree it's a subset; I wouldn't agree that it's simple. Making a parser that handles ALL current cards would be difficult. Making a parser that handles 50% of current cards would be easier, but still challenging.
Hand coding over 10,000 cards will take some time. But if many people are playing MTG Forge, then if each one coded a handful of cards, it would be done in no time.
Having an automatic method of generating the cards would be great, and if someone wants to make one, that would be great too. But as long as there is a way to do it by hand, that's enough for now. He only needs a small set of cards to test his code with.
The focus now for Forge is to get the game working. If someone else wants to try their hand at an automatic translator, power to you!
These plaintext cards make sense to me. My previous way of just hardcoding the cards into Java was ok for a first try, but it could be improved. By using plaintext instead of Java, I'm hoping to be able to add more cards.
ReplyDeleteMy goal is to reuse the targeting and resolve code for many cards. So my simple parser will see the text "Target: creature or player" and will get the appropriate code for that.
Later on I might use a different format like XML but this format is a good starting point. It is easy to get things so complicated that it never gets finished, so I try to always make things easy to begin with, so I will actually DO them. Procrastination is horrible but we all do it, lol.
And the truth is that the Text line is redundant but I definitely don't want to parse it.
ReplyDeleteHypothetically you could just read the Oracle wording from Gatherer and parse it, but you are in for a world of pain.
Rob Cashwalker,
ReplyDeleteSpell
Text: Shock deals 2 damage to {Target}.
Target: Creature|Player
Resolve: SingleTargetDamage,2
This would work but I want to make it super simple :)
I dunno, I thought my format looked pretty simple.....
ReplyDeletewell.... i think that even with redundancy, it is still easy...
ReplyDeletecopy /paste is still fast. If there would be a 1 second delay because of redundant programming it would take (for 10000 cards) just a few hours. And if you want to change structure it would also take some time just to re-think all over.(Not to mention how many hour does he already spend programming)
Also if someone would want to help, it is easier to understand something with easy structure rather than complicated.
So I suggest his method