(This was written awhile ago, but it is still true. New sets scare me to dead because they usually involve some weird mechanic like "When this card goes to the graveyard and you tapped an Island this turn, you may draw up to 2 cards.")
Yes, the tagline is totally outrageous and false, like all good taglines. :) Checkout Beseech the Queen, a new Shadamoor card. That is some funky mana. I assume it means “You can pay BBB or 2BB or 4B or 6”. This has to be correct or very close since Mark Rosewater (head Wizard card designer) mentioned that the converted mana cost is 6. What this means to me, is more programming and more headaches, aka Wizards is trying to kill me. (By the way that sounds like a bad Dungeons and Dragons dream.)
A few weeks ago, while waiting for a job interview I sketched out an idea to program hybrid mana costs, introduced in Ravnica. And while I didn’t get the job, I did come up with a pretty nifty solution. Thankfully with a little bit of tweaking, it worked. I’m not sure exactly how to implement this new mana cost, but maybe something will come to me. If not, I’ll just code, test, debug, and repeat until finished. Hopefully it will only take me 1 hour, but maybe I’m just blowing my own horn.
Currently the mana cost is just a string. A string is a sequence of letters like “I am a string”. All text that you see on the screen is a string. This new mana, along with split cards, make any operations like finding the converted mana cost more difficult. The solution is to replace the string mana cost with a class that represents the mana cost.
A class is a collection of operations, called methods, that act on the same data. A number class would have methods add and subtract. The mana cost class should have methods like getConvertedCost and getCardColor. The card’s color is important and is usually determined by the mana cost, some exceptions are Pact of Negation and Ancestral Vision. The mana class could also have the methods addToCost and reduceCost for cards like Thorn of Amethyst (Noncreature spells cost 1 more to play) and Cloud Key (Spells you play of the chosen type [Creature, Instant, etc...] cost 1 less to play).
Screenshots of MTG Forge
Wednesday, December 31, 2008
Monday, December 29, 2008
AI - Mana Smoothing
The computer AI used to stumble when playing mono-colored decks. The AI seemed slow and would actually play the same land twice, the cards ID numbers were the same. The problem was in the code that smoothed the computer’s land, also known as mana threading. The code presumed a two color deck. I fixed the code and now it will worked with 1,2,3,4 or 5 color decks. With a 2 color deck the computer’s mana is threaded like 1,2,1,2,1,2.
The computer’s land is threaded in a very particular order. The computer’s opening hand has no lands and then draws a land for the next 5 turns. You may be asking yourself, why? The idea is to increase the number of spells the computer has an opportunity to play. On the computer’s first turn he has 7 spells and 1 land. So hopefully he has a one mana spell in his hand. On the computer’s second turn, he draws a land and plays it. So now he has 6 or 7 spells in his hand, depending if he played a spell. The computer’s hand is all spells, increasing the “quality” of cards he has. Being technical, I guess the computer has “virtual card advantage,” but I don’t really know, lol.
The computer draws an additional land on his 8th and 11th turn. The computer will never have more than 7 lands in play at a time, assuming he doesn’t play cards that fetch lands. Threading the computer’s land like Forest, Mountain, Forest, Mountain, gives it an advantage. Assuming a 2 color deck, the computer will be able to play any double-costed spell like RR as early as turn 3 and always by turn 4.
p.s.
I probably should have made the "AI land smoothing" code optional, so the user could select when to turn it off and on. The only time I know of that this really backfires is if you play land destruction, but even then you are not guaranteed to win the game. If some card makes the computer shuffle his deck, this doesn't hurt the computer since his deck will be completely randomized. The lands that are not put on top of the computer's deck, are put on the bottom.
I'm thinking about implementing an optional feature that lets the AI draw 2 cards per turn. I'm not sure if this would really help the AI or not. Obviously this would hose discard decks but that is why I would make the feature optional.
The computer’s land is threaded in a very particular order. The computer’s opening hand has no lands and then draws a land for the next 5 turns. You may be asking yourself, why? The idea is to increase the number of spells the computer has an opportunity to play. On the computer’s first turn he has 7 spells and 1 land. So hopefully he has a one mana spell in his hand. On the computer’s second turn, he draws a land and plays it. So now he has 6 or 7 spells in his hand, depending if he played a spell. The computer’s hand is all spells, increasing the “quality” of cards he has. Being technical, I guess the computer has “virtual card advantage,” but I don’t really know, lol.
The computer draws an additional land on his 8th and 11th turn. The computer will never have more than 7 lands in play at a time, assuming he doesn’t play cards that fetch lands. Threading the computer’s land like Forest, Mountain, Forest, Mountain, gives it an advantage. Assuming a 2 color deck, the computer will be able to play any double-costed spell like RR as early as turn 3 and always by turn 4.
p.s.
I probably should have made the "AI land smoothing" code optional, so the user could select when to turn it off and on. The only time I know of that this really backfires is if you play land destruction, but even then you are not guaranteed to win the game. If some card makes the computer shuffle his deck, this doesn't hurt the computer since his deck will be completely randomized. The lands that are not put on top of the computer's deck, are put on the bottom.
I'm thinking about implementing an optional feature that lets the AI draw 2 cards per turn. I'm not sure if this would really help the AI or not. Obviously this would hose discard decks but that is why I would make the feature optional.
Friday, December 26, 2008
Who Uses MTG Forge?
This question pops occasionally pops into my head and I’m not entirely sure what the answer is. So who does use my program? Players who are cheap? (That would be me!!) Players who don’t use Magic Online (Me again, lol.) Players who use land destruction and other mean decks. (Sometimes I do.) Players who are afraid of losing to another human player since their ego is so small. (Definitely me.)
Primarily, I would guess that the people who download and play MTG Forge are the casual crowd who just want to have an interesting, fun game of Magic. Yes winning is important, but having fun is more important. I enjoy winning and losing in an awesome, blow-up-the-world fashion. I love the games where the computer surprises me or I win with 1 life left. My goal is not to just win or lose, it is to get there in the most spectacular, remarkable way.
I also play MTG Forge to use great rares like Akroma, Angel of Wrath and Kokusho, the Evening Star, cards that I could/would never buy in real life. Playing with Korlash, Heir to Blackblade also lets me get a feel for cards that people are currently talking about. I also enjoy the crazy sealed deck and drafting games. Which card is better to draft, Mox Jet or Kokusho? Lol I don’t know, they are both awesome cards. I play Magic, and MTG Forge, in order to experience something. Why do you play Magic?
p.s.
Maybe new players use MTG Forge but it seems like most users know the rules of Magic pretty well. Some players who haven't played in awhile have written me e-mail like, "Wow, Magic has sure added a lot of cards since I've played."
Primarily, I would guess that the people who download and play MTG Forge are the casual crowd who just want to have an interesting, fun game of Magic. Yes winning is important, but having fun is more important. I enjoy winning and losing in an awesome, blow-up-the-world fashion. I love the games where the computer surprises me or I win with 1 life left. My goal is not to just win or lose, it is to get there in the most spectacular, remarkable way.
I also play MTG Forge to use great rares like Akroma, Angel of Wrath and Kokusho, the Evening Star, cards that I could/would never buy in real life. Playing with Korlash, Heir to Blackblade also lets me get a feel for cards that people are currently talking about. I also enjoy the crazy sealed deck and drafting games. Which card is better to draft, Mox Jet or Kokusho? Lol I don’t know, they are both awesome cards. I play Magic, and MTG Forge, in order to experience something. Why do you play Magic?
p.s.
Maybe new players use MTG Forge but it seems like most users know the rules of Magic pretty well. Some players who haven't played in awhile have written me e-mail like, "Wow, Magic has sure added a lot of cards since I've played."
Tuesday, December 23, 2008
AI Overview
I have gotten questions about how the computer AI is programmed. I presume that the AI seems believable and even smart sometimes. The AI is divided up into 2 parts: cards and combat. A different component handles each one.
The AI that plays cards is essentially very simple, it just randomly plays a card in his hand. Most cards have some AI code hardcoded into them. The computer will only play Wrath of God if you have a creature in play. Elvish Piper’s ability will choose the biggest creature in hand to put into play. The code in Giant Growth will only target a creature that will attack. The AI for each card is usually pretty simple, but combined together it makes the computer seem alive.
Some cards and abilities the computer cannot play because I wasn’t sure how to evaluate them. The computer cannot play Thought Courier’s draw a card, discard a card ability or Remove Soul, I couldn’t get the code to work correctly. Thankfully some cards like Pestilence the computer uses very efficiently.
Combat is divided up into attacking and blocking. Basically the computer trades creatures when attacking or blocking. (Trading means that both creatures die.) The computer will not block a non-flyer with a flyer, which is usually the correct thing to do. The AI combat routines sound simple but they were really hard to program. My mind felt twisted after I got done with them. It is really hard trying to handle all attacking and blocking situations. The object ComputerUtil_Attack2 is 125 lines and ComputerUtil_Block2 is 210 lines.
The code blocks creatures in this order.
-safe block: attacker dies, blocker lives
-shield block: attacker lives, blocker lives
-trade block: attacker dies, blocker dies
-chump block: attacker lives, blocker dies
-multiple blockers: attacker dies, some or all blockers die
p.s.
In the future it would be nice if the computer was playing with a control deck that the AI would attack/block differently than if the computer was playing an aggro deck. Currently the computer always uses the same code to attack and block.
Another fundamental question about combat is "Does the AI want the game to go long or short?" If the AI is winning, it will want the game to end quickly so he will attack more aggressively. If the AI is losing and wants the game to go long (in hopes that he draws a card to save him) he would block more passively and wouldn't trade creatures during combat.
As a player, you should often be asking yourself the same question, "Do I want the game to end now or later?"
The AI that plays cards is essentially very simple, it just randomly plays a card in his hand. Most cards have some AI code hardcoded into them. The computer will only play Wrath of God if you have a creature in play. Elvish Piper’s ability will choose the biggest creature in hand to put into play. The code in Giant Growth will only target a creature that will attack. The AI for each card is usually pretty simple, but combined together it makes the computer seem alive.
Some cards and abilities the computer cannot play because I wasn’t sure how to evaluate them. The computer cannot play Thought Courier’s draw a card, discard a card ability or Remove Soul, I couldn’t get the code to work correctly. Thankfully some cards like Pestilence the computer uses very efficiently.
Combat is divided up into attacking and blocking. Basically the computer trades creatures when attacking or blocking. (Trading means that both creatures die.) The computer will not block a non-flyer with a flyer, which is usually the correct thing to do. The AI combat routines sound simple but they were really hard to program. My mind felt twisted after I got done with them. It is really hard trying to handle all attacking and blocking situations. The object ComputerUtil_Attack2 is 125 lines and ComputerUtil_Block2 is 210 lines.
The code blocks creatures in this order.
-safe block: attacker dies, blocker lives
-shield block: attacker lives, blocker lives
-trade block: attacker dies, blocker dies
-chump block: attacker lives, blocker dies
-multiple blockers: attacker dies, some or all blockers die
p.s.
In the future it would be nice if the computer was playing with a control deck that the AI would attack/block differently than if the computer was playing an aggro deck. Currently the computer always uses the same code to attack and block.
Another fundamental question about combat is "Does the AI want the game to go long or short?" If the AI is winning, it will want the game to end quickly so he will attack more aggressively. If the AI is losing and wants the game to go long (in hopes that he draws a card to save him) he would block more passively and wouldn't trade creatures during combat.
As a player, you should often be asking yourself the same question, "Do I want the game to end now or later?"
Monday, December 22, 2008
Attack!!!
In Magic, knowing when to attack is a fundamental question. Naturally you attack when it helps you win. In limited games in particular, there are times when you and your opponent just go back and forth attacking each other, this is known as racing. You should race if you will win, which unfortunately requires a little math, but not much.
Your Turn 15 life, 2/2 creature – Opponent 7 life, 3/3 creature – Should you race?
The easiest way to figure out to race is to first calculate how many turns it will take for you to kill your opponent. Now compute how many turns it takes your opponent to kill you. Obviously if you can kill your opponent first, attack. In this example, you will win in 4 turns, and you opponent will win in 5 turns, so you should attack.
Your Turn 2 life, 3/3 creature – Opponent 5 life, 1/1 creature – Should you race?
Yes
Your Turn 5 life, 2/2 creature – Opponent 11 life, 1/1 creature – Should you race?
No
Your Turn 17 life, 3/3 creature – Opponent 15 life, 2/2 creature – Should you race?
Yes
Your Turn 19 life, flying 1/1 creature – Opponent 9 life, 2/2 creature – Should you race?
Yes
Your Turn 8 life, flying 2/2 creature – Opponent 7 life, 3/3 creature – Should you race?
No
Obviously you don’t know what cards your opponent will draw, but you can race to reduce his chances of winning. Racing increases your chances of winning because it puts pressure on your opponent. If you are loosing the race, you will want to trade creatures in combat, both of them will die, in hopes that you can draw a solution. In most games you will be both the aggressor, who wants to race, and the defender. Aggro decks are built upon the concept of racing, and hope to attack on every turn.
p.s.
MTG Forge probably works best as a limited simulator and limited decks tend to attack alot compared to some types constructed decks. Limited control decks do exist, but usually they win by brutally attacking.
Your Turn 15 life, 2/2 creature – Opponent 7 life, 3/3 creature – Should you race?
The easiest way to figure out to race is to first calculate how many turns it will take for you to kill your opponent. Now compute how many turns it takes your opponent to kill you. Obviously if you can kill your opponent first, attack. In this example, you will win in 4 turns, and you opponent will win in 5 turns, so you should attack.
Your Turn 2 life, 3/3 creature – Opponent 5 life, 1/1 creature – Should you race?
Yes
Your Turn 5 life, 2/2 creature – Opponent 11 life, 1/1 creature – Should you race?
No
Your Turn 17 life, 3/3 creature – Opponent 15 life, 2/2 creature – Should you race?
Yes
Your Turn 19 life, flying 1/1 creature – Opponent 9 life, 2/2 creature – Should you race?
Yes
Your Turn 8 life, flying 2/2 creature – Opponent 7 life, 3/3 creature – Should you race?
No
Obviously you don’t know what cards your opponent will draw, but you can race to reduce his chances of winning. Racing increases your chances of winning because it puts pressure on your opponent. If you are loosing the race, you will want to trade creatures in combat, both of them will die, in hopes that you can draw a solution. In most games you will be both the aggressor, who wants to race, and the defender. Aggro decks are built upon the concept of racing, and hope to attack on every turn.
p.s.
MTG Forge probably works best as a limited simulator and limited decks tend to attack alot compared to some types constructed decks. Limited control decks do exist, but usually they win by brutally attacking.
Friday, December 19, 2008
Software Engineering Books
I went to Barnes and Noble today and looked around. I always tend to make my way to the computer books, my favorite section. For some reason, I enjoy browsing through yards of computers books. Computer books tend to be some of the largest volumes in the whole store.
I was vaguely looking for a book that would help me with my MTG Forge project. It’s probably a small project by most estimations, but it does some useful that the common person can and would use. Most computer books cover the foundations or architecture, nothing is really written about implementing a whole program. All the code is short, because it makes it easier to read and understand. Larger programs are talked about in vague terms like, “Make sure you have a standardized error reporting process,” but what does that mean in real life?
It is hard to read source code from a book and to learn from it. Any program listing longer than a few lines I usually gloss over, because reading code takes work. It seems like software engineering is talked about in the classroom but is learned in the real world. Even books that are titled “Software Engineering” don’t talk about the exact steps that are needed for a non-trivial program. But maybe that puts programming back into the realm of art, and who can teach an artist to be great?
I was vaguely looking for a book that would help me with my MTG Forge project. It’s probably a small project by most estimations, but it does some useful that the common person can and would use. Most computer books cover the foundations or architecture, nothing is really written about implementing a whole program. All the code is short, because it makes it easier to read and understand. Larger programs are talked about in vague terms like, “Make sure you have a standardized error reporting process,” but what does that mean in real life?
It is hard to read source code from a book and to learn from it. Any program listing longer than a few lines I usually gloss over, because reading code takes work. It seems like software engineering is talked about in the classroom but is learned in the real world. Even books that are titled “Software Engineering” don’t talk about the exact steps that are needed for a non-trivial program. But maybe that puts programming back into the realm of art, and who can teach an artist to be great?
Wednesday, December 17, 2008
Happy Holidays
I'll be offline for a little while, probably until Jan 5th, so if you ask me a question I won't be around to answer. Let me say, "Merry Christmas" early. I don't think I'm getting any Magic cards this Christmas, but maybe I'll buy a pack of Shards of Alara just for fun. (Currently I own zero Shards of Alara cards, but I don't play Magic in the real world anyways, lol.)
I've scheduled a new post this Friday, then Monday and Wednesday like normal. They are articles that I wrote a long time ago and I doubt you have read them. I hope they are interesting, |-)
I've scheduled a new post this Friday, then Monday and Wednesday like normal. They are articles that I wrote a long time ago and I doubt you have read them. I hope they are interesting, |-)
Source Code Privacy
Letting someone see your source code is a very private thing. Usually there are a million things that could have been done better, but your program works and that gives you a great deal of satisfaction. If your project is large enough, your source code will always have some less-than-ideal software engineering concepts like global variables.
MTG Forge has global variables and hard coded card names, but it works. People need to realize that software concepts like global variables are NOT always bad, generally they are bad. Global variables represent a trade-off and most of the time they should be avoided. Sometimes global variables help you overcome some obstacles like, “I don’t know how else to program this.” That previous statement is why I used global variables.
Source code is also very private because you like the way you split up a string, even though there are different ways to do it. You like the order of the arguments and you like the architecture that you thought of. Source code is almost a diary of your thoughts, and most people don’t post their diaries to the internet, although I do know that blogs exist. Source code almost invites criticism from other programmers.
p.s.
Version 2 doesn't have any global variables because they tend to attract errors. Version 1 used global variables as an easy way to "get and see everything." The problem with global variables in version 1 is that there isn't an easy way to reset everything and start a new game, that is why sometimes you have 7 or 8 cards in your opening hand.
MTG Forge has global variables and hard coded card names, but it works. People need to realize that software concepts like global variables are NOT always bad, generally they are bad. Global variables represent a trade-off and most of the time they should be avoided. Sometimes global variables help you overcome some obstacles like, “I don’t know how else to program this.” That previous statement is why I used global variables.
Source code is also very private because you like the way you split up a string, even though there are different ways to do it. You like the order of the arguments and you like the architecture that you thought of. Source code is almost a diary of your thoughts, and most people don’t post their diaries to the internet, although I do know that blogs exist. Source code almost invites criticism from other programmers.
p.s.
Version 2 doesn't have any global variables because they tend to attract errors. Version 1 used global variables as an easy way to "get and see everything." The problem with global variables in version 1 is that there isn't an easy way to reset everything and start a new game, that is why sometimes you have 7 or 8 cards in your opening hand.
Wednesday, December 10, 2008
SpellAbility
Last week I talked about SpellAbility and since it is such an important topic, I plan to talk about it again. (Here is a short review, the Card object holds many SpellAbility objects. SpellAbility's resolve() method does the actual function of the card, like dealing 3 damage. Java capitalizes object names like Card and SpellAbility. A card refers to a regular Magic card, but Card refers to the Card object. And an object is just a bunch of related Java code.)
SpellAbility has a mana cost which at first seems like it should go in Card. But this goes back to the question of "What is a Magic card?" I envision that a Magic card just holds spells, so the Card object is just a bucket and SpellAbility actually gets to do the fun stuff like having a mana cost and resolving off of the stack.
I'm using SpellAbilty in both MTG Forge version 1 and 2. In version 2 I have made a few minor changes to SpellAbility. In version 1, Programming ability costs like "sacrifice this card" and "tap" were complicated. In version 2 I will add a simple Command to SpellAbility that is executed before the SpellAbility is put on the stack. A Command object only has one method which is usually called something like execute(). Any code can be put into execute() so I can easily code activated ability costs like "sacrifice this card" and "tap".
Command
execute()
TapCommand extends Command
execute() - tap the card
Above is a simple representation of Command. The Command object doesn't do anything and a subclass has to be created in order make execute() useful. A subclass gets all of the code from its "parent". I subclass SpellAbility to handle instants. SpellAbility has the canPlay() method which returns true if this effect can be played. The canPlay() method of the instant subclass always returns true. The SpellAbility canPlay() method representing a sorcery would check to see if it is the Main 1 or 2 phase and that nothing is on the stack.
That last paragraph is a little complicated, but I have faith that you guys can understand it :+)
SpellAbility has a mana cost which at first seems like it should go in Card. But this goes back to the question of "What is a Magic card?" I envision that a Magic card just holds spells, so the Card object is just a bucket and SpellAbility actually gets to do the fun stuff like having a mana cost and resolving off of the stack.
I'm using SpellAbilty in both MTG Forge version 1 and 2. In version 2 I have made a few minor changes to SpellAbility. In version 1, Programming ability costs like "sacrifice this card" and "tap" were complicated. In version 2 I will add a simple Command to SpellAbility that is executed before the SpellAbility is put on the stack. A Command object only has one method which is usually called something like execute(). Any code can be put into execute() so I can easily code activated ability costs like "sacrifice this card" and "tap".
Command
execute()
TapCommand extends Command
execute() - tap the card
Above is a simple representation of Command. The Command object doesn't do anything and a subclass has to be created in order make execute() useful. A subclass gets all of the code from its "parent". I subclass SpellAbility to handle instants. SpellAbility has the canPlay() method which returns true if this effect can be played. The canPlay() method of the instant subclass always returns true. The SpellAbility canPlay() method representing a sorcery would check to see if it is the Main 1 or 2 phase and that nothing is on the stack.
That last paragraph is a little complicated, but I have faith that you guys can understand it :+)
Monday, December 8, 2008
Magic User Interfaces
I am a pretty decent programmer but coding user interfaces (UI) is just hard, very hard. That is the reason that MTG Forge looks like it does, although I still love the mini card pictures, it really improves the look. UI design is more of an art than a science and it is very hard to write a UI that is easy to use. Videogames are interesting because they are essentially one big fancy UI. A bad UI kills a videogame but a good UI can save one.
The easiest way to write a UI is to copy one, back in the day Microsoft copied Apple's UI. I can copy from Magic Online, Shandalar, Incantus, Firemox and Wagic. Wagic's UI looks great even though it is very small, about 1/4 of my monitor screen. Shandalar has a simple yet very effective UI. I can easily read the card names and stats. Incantus is just great and everything is easy to see. Magic Online has many good things going for it, but my favorite is still probably Shandalar because it is just so easy to use. Personally I think Firemox does a lot of great stuff, they have a ton of cards, but their UI is a little confusing.
One of the problems when writing a UI for Magic is that you probably can't generate the whole card picture. In Magic Online, if an ability is added to the card, that text is shown in the card picture. In MTG Forge I just show two card pictures, the top one is a generic, text only version and the lower one is the card picture itself. Incantus shows the card picture and just adds a few stats to the bottom like damage.
I continually think about MTG Forge's UI and after I get version 2 more done, I plan to work on the UI. Many of the above programs have a little pictures depicting all of the phases and many people have commented that MTG Forge's needs something like that because the phases jump too quickly.
p.s.
User interfaces are occasionally called a GUI, which stands for a graphical user interface. UI (you-ee) and GUI (goo-ey) are both standard abbreviations that IT people use.
p.s.s.
One book about UI design said something like this, "If your user spends 1 minute using your UI, it will take you 1 hour to code. If you user spends 1 hour using your UI, it will take you one week." And personally I think spending only 1 week is optimistic.
The easiest way to write a UI is to copy one, back in the day Microsoft copied Apple's UI. I can copy from Magic Online, Shandalar, Incantus, Firemox and Wagic. Wagic's UI looks great even though it is very small, about 1/4 of my monitor screen. Shandalar has a simple yet very effective UI. I can easily read the card names and stats. Incantus is just great and everything is easy to see. Magic Online has many good things going for it, but my favorite is still probably Shandalar because it is just so easy to use. Personally I think Firemox does a lot of great stuff, they have a ton of cards, but their UI is a little confusing.
One of the problems when writing a UI for Magic is that you probably can't generate the whole card picture. In Magic Online, if an ability is added to the card, that text is shown in the card picture. In MTG Forge I just show two card pictures, the top one is a generic, text only version and the lower one is the card picture itself. Incantus shows the card picture and just adds a few stats to the bottom like damage.
I continually think about MTG Forge's UI and after I get version 2 more done, I plan to work on the UI. Many of the above programs have a little pictures depicting all of the phases and many people have commented that MTG Forge's needs something like that because the phases jump too quickly.
p.s.
User interfaces are occasionally called a GUI, which stands for a graphical user interface. UI (you-ee) and GUI (goo-ey) are both standard abbreviations that IT people use.
p.s.s.
One book about UI design said something like this, "If your user spends 1 minute using your UI, it will take you 1 hour to code. If you user spends 1 hour using your UI, it will take you one week." And personally I think spending only 1 week is optimistic.
Saturday, December 6, 2008
Find Free Ebooks - Great AI and Programming Resource
This is a little random but I found this great site that lets you search for free ebooks online, pdf or doc formats. I just randomly searched for "Java Intelligence" and found these two great books. Granted I also found some guys resume, but this is the best AI information that I have ever found on the Internet.
EBook Search Engine
http://www.markwatson.com/opencontent/JavaAI3rd.pdf
http://www.markwatson.com/opencontent/AIprog.pdf
EBook Search Engine
http://www.markwatson.com/opencontent/JavaAI3rd.pdf
http://www.markwatson.com/opencontent/AIprog.pdf
Friday, December 5, 2008
Suggestions for Version 1
While I am basically done working on MTG Forge version 1, I wouldn't mind trying to add something to it which would increase its replay value. I know version 1 can get boring and I'm not sure when version 2 will be playable with a few cards. The hard part about asking for suggestions is that most people don't know which features are easy or hard to add, which I completely understand.
My only suggestion is a simple quest mode. You would start out with a basic deck which you would improve by earning money. Basically MTG Forge would look and play the same but you would earn money for each game that you won and you could buy cards and booster packs from a store. This would make the game harder since your cards would be less powerful, say bye-bye to Ancestral Recall and Lightning Bolt.
I can't really think of anything else to suggest that is easy to program. Let me hear your suggestions and what you think about "quest mode".
p.s.
Did anyone enjoy reading through this article that I typed about Magic's humble beginnings? I thought it was very interesting. The article was written by Magic's creator Richard Garfield.
My only suggestion is a simple quest mode. You would start out with a basic deck which you would improve by earning money. Basically MTG Forge would look and play the same but you would earn money for each game that you won and you could buy cards and booster packs from a store. This would make the game harder since your cards would be less powerful, say bye-bye to Ancestral Recall and Lightning Bolt.
I can't really think of anything else to suggest that is easy to program. Let me hear your suggestions and what you think about "quest mode".
p.s.
Did anyone enjoy reading through this article that I typed about Magic's humble beginnings? I thought it was very interesting. The article was written by Magic's creator Richard Garfield.
Thursday, December 4, 2008
MTG Forge - Fixed Necropotence
There was a problem when Necropotence was in play, you couldn't play a land. This is the only change that I made.
And does anyone really miss the fancy Windows installer instead of just a zip file?
And does anyone really miss the fancy Windows installer instead of just a zip file?
Wednesday, December 3, 2008
How to Play a Card - Card Objects
This article is a little long but it fully explains MTG Forge's card objects.
I was very happy when MTG Forge version 2 was able to accomplish the steps needed in order to play a card. While paying a mana cost doesn't seem difficult, in reality it involves many little steps that have to be programmed.
First let me give you a little bit of background on how MTG Forge 1 and 2 actually encodes a Magic card. (I'm skipping a lot of details that I have described elsewhere and in the actual code. And remember that an object is just another term for a group of Java statements.) A card object is very basic and holds the card's name, type (like sorcery or creature) and any creature subtypes (like Elf or Goblin). A card object holds one or more SpellAbility objects. SpellAbility objects are used to represent all spells and activated abilities. SpellAbility objects implement the actual function of a card, like destroying all creatures.
So when you play a card, you are playing the SpellAbility object that the card is holding. The potential problem is that a card may hold many SpellAbility objects. The Royal Assassin card holds two SpellAbility objects, one is the normal summon creature spell and the other SpellAbility represents Royal Assassin's "tap: destroy target tapped creature" ability.
SpellAbility also has a method called "canPlay()" which returns true if it can currently be played and false if it cannot. A sorcery like Wrath of God has a SpellAbility that allows it to be played from your hand. Activated abilities like Royal Assassin's have SpellAbility objects that can only be used when the card is in play.
To get back to my original question, "The potential problem is that a card may hold many SpellAbility objects." When you click on a card to play it, each SpellAbility is checked to see whether it can be played. If you try to play Royal Assassin from your hand, the summon creature SpellAbility can be played while the SpellAbility representing the activated ability cannot.
Using the same object, SpellAbility, to represent all spells and abilities has saved me a TON of extra work. At first I was coding spells and activated abilities differently but after stepping back from the problem, I was able to handle both situations with the same code. Finding simple solutions takes a lot of hard work, lol.
(The stack in MTG Forge only holds SpellAbility objects. The computer AI also uses SpellAbility. In the beginning I had to write a card for you, the player, and then rewrite the whole card for the computer. The computer uses SpellAbility canPlayAI() method to determine if it should play the card. With a card like Naturalize, the computer will only play it if you have an artifact or enchantment.)
p.s.
Below is a listing of the relevant methods for Card and SpellAbility. Be aware that Card objects don't have a mana cost, only SpellAbility does. Currently SpellAbility doesn't easily handle activated abilities that have additional costs like "tap" or "sacrifice this card" and I'm still working on this problem. The resolve() method in SpellAbility is where the function of a card is put like "destroy all creatures" or "target creature gets +3/+3 until end of turn."
Card
addSpellAbility(SpellAbility sp)
getSpellAbility() : SpellAbility[]
SpellAbility
resolve()
canPlay() : boolean
canPlayAI() : boolean
getManaCost() : String
setManaCost(String)
p.s.s.
The Card object also holds extra information like a creature's attack and defense. While conceptual this might be a little incorrect, the code was easy to write. Usually I have trouble coding something if my design is wrong.
I was very happy when MTG Forge version 2 was able to accomplish the steps needed in order to play a card. While paying a mana cost doesn't seem difficult, in reality it involves many little steps that have to be programmed.
First let me give you a little bit of background on how MTG Forge 1 and 2 actually encodes a Magic card. (I'm skipping a lot of details that I have described elsewhere and in the actual code. And remember that an object is just another term for a group of Java statements.) A card object is very basic and holds the card's name, type (like sorcery or creature) and any creature subtypes (like Elf or Goblin). A card object holds one or more SpellAbility objects. SpellAbility objects are used to represent all spells and activated abilities. SpellAbility objects implement the actual function of a card, like destroying all creatures.
So when you play a card, you are playing the SpellAbility object that the card is holding. The potential problem is that a card may hold many SpellAbility objects. The Royal Assassin card holds two SpellAbility objects, one is the normal summon creature spell and the other SpellAbility represents Royal Assassin's "tap: destroy target tapped creature" ability.
SpellAbility also has a method called "canPlay()" which returns true if it can currently be played and false if it cannot. A sorcery like Wrath of God has a SpellAbility that allows it to be played from your hand. Activated abilities like Royal Assassin's have SpellAbility objects that can only be used when the card is in play.
To get back to my original question, "The potential problem is that a card may hold many SpellAbility objects." When you click on a card to play it, each SpellAbility is checked to see whether it can be played. If you try to play Royal Assassin from your hand, the summon creature SpellAbility can be played while the SpellAbility representing the activated ability cannot.
Using the same object, SpellAbility, to represent all spells and abilities has saved me a TON of extra work. At first I was coding spells and activated abilities differently but after stepping back from the problem, I was able to handle both situations with the same code. Finding simple solutions takes a lot of hard work, lol.
(The stack in MTG Forge only holds SpellAbility objects. The computer AI also uses SpellAbility. In the beginning I had to write a card for you, the player, and then rewrite the whole card for the computer. The computer uses SpellAbility canPlayAI() method to determine if it should play the card. With a card like Naturalize, the computer will only play it if you have an artifact or enchantment.)
p.s.
Below is a listing of the relevant methods for Card and SpellAbility. Be aware that Card objects don't have a mana cost, only SpellAbility does. Currently SpellAbility doesn't easily handle activated abilities that have additional costs like "tap" or "sacrifice this card" and I'm still working on this problem. The resolve() method in SpellAbility is where the function of a card is put like "destroy all creatures" or "target creature gets +3/+3 until end of turn."
Card
addSpellAbility(SpellAbility sp)
getSpellAbility() : SpellAbility[]
SpellAbility
resolve()
canPlay() : boolean
canPlayAI() : boolean
getManaCost() : String
setManaCost(String)
p.s.s.
The Card object also holds extra information like a creature's attack and defense. While conceptual this might be a little incorrect, the code was easy to write. Usually I have trouble coding something if my design is wrong.
Monday, December 1, 2008
Version 2 Progress
I hope everyone had a great Thanksgiving. I had some turkey and saw a movie, to me that is as good as it gets. Today I wanted to update everyone about the current condition of MTG Forge version 2. Version 2 isn't playable but let me tell you what it can do.
First, version 2 lets you cycle through all the phases and choose which phases to stop at. While this might seem like a small feature, it is something that version 1 can't do. Also version 2 lets you choose your phase stops. Ever since MTG Forge was first released people have been asking about these features. Hopefully version 2 will help you improve your game skills by allowing you and the computer to play instants and activated abilities at end of turn.
Second, version 2 is able to let the computer play first. In version 1 the computer can't play first because it breaks everything, this was an error that I didn't find until late in development. In version 2, I have repeatedly checked to make sure that everything works as it should when you or the computer goes first. Even though version 2 is still immature, I've still found a few errors that I had to fix concerning this issue.
The problem of letting the computer go first is that it broke the code that deals with the phases. As I have said before, just coding Magic's phases is difficult. I also had a hard time getting the "StackNotEmpty" phase to work correctly, this is the "phase" that lets you respond to a spell or ability that is on the stack. While this isn't technically a phase, it is handled like a regular phase.
Version 2 also has a mana pool, I can't wait to play Dark Ritual!!! The other good news is that version 2 is at a milestone, you can actually tap mana and play a card. I'll talk more about that on Wednesday. Until then, happy Magic-ing!!!
First, version 2 lets you cycle through all the phases and choose which phases to stop at. While this might seem like a small feature, it is something that version 1 can't do. Also version 2 lets you choose your phase stops. Ever since MTG Forge was first released people have been asking about these features. Hopefully version 2 will help you improve your game skills by allowing you and the computer to play instants and activated abilities at end of turn.
Second, version 2 is able to let the computer play first. In version 1 the computer can't play first because it breaks everything, this was an error that I didn't find until late in development. In version 2, I have repeatedly checked to make sure that everything works as it should when you or the computer goes first. Even though version 2 is still immature, I've still found a few errors that I had to fix concerning this issue.
The problem of letting the computer go first is that it broke the code that deals with the phases. As I have said before, just coding Magic's phases is difficult. I also had a hard time getting the "StackNotEmpty" phase to work correctly, this is the "phase" that lets you respond to a spell or ability that is on the stack. While this isn't technically a phase, it is handled like a regular phase.
Version 2 also has a mana pool, I can't wait to play Dark Ritual!!! The other good news is that version 2 is at a milestone, you can actually tap mana and play a card. I'll talk more about that on Wednesday. Until then, happy Magic-ing!!!
Monday, November 24, 2008
The Future of This Blog
I have confused and/or frustrated a few people by saying that I plan on making my own version this great, physics game. It is called Fantastic Contraption and you can play it in your browser here.
I'm glad people are interested in MTG Forge version 2. Not to further confuse everybody, I plan on working on MTG Forge version 2 to at least get it playable. I'm thinking around 50 cards and hopefully a little better AI. I really want to have undo and use my idea of plaintext cards. After I get version 2 working, I'll probably work on Fantastic Contraption (FC) and blog about that. I'm guessing that I'll work about 6 months on FC and then get back to MTG Forge 2.0.
I tentatively plan to get MTG Forge 2.0 working and then blog about my creative efforts to copy FC. FC will be cool because it will force me to write a real videogame interface and I get to use some cool physics code that someone else wrote. (I thought I might have to write my own little physics engine but thankfully I don't, thank you Internet.)
---------------
Well I've decided to keep working on MTG Forge version 2. My interest in Magic has been renewed. (Sometimes I think I enjoy programming Magic as much as playing Magic, it just depends what kind of mood I am in.)
I'm glad people are interested in MTG Forge version 2. Not to further confuse everybody, I plan on working on MTG Forge version 2 to at least get it playable. I'm thinking around 50 cards and hopefully a little better AI. I really want to have undo and use my idea of plaintext cards. After I get version 2 working, I'll probably work on Fantastic Contraption (FC) and blog about that. I'm guessing that I'll work about 6 months on FC and then get back to MTG Forge 2.0.
I tentatively plan to get MTG Forge 2.0 working and then blog about my creative efforts to copy FC. FC will be cool because it will force me to write a real videogame interface and I get to use some cool physics code that someone else wrote. (I thought I might have to write my own little physics engine but thankfully I don't, thank you Internet.)
---------------
Well I've decided to keep working on MTG Forge version 2. My interest in Magic has been renewed. (Sometimes I think I enjoy programming Magic as much as playing Magic, it just depends what kind of mood I am in.)
Wednesday, November 19, 2008
Suggest a Topic
This is probably the lamest post ever but hopefully it will generate a number of comments. What do you, the reader, want to read about? What topics interest you the most? I feel like I’ve talked about everything concerning Magic and MTG Forge twice over.
I do a decent job of just working on MTG Forge and then writing about my experiences. I try to write about computer programming in an interesting fashion. I love to program and I think programming is exciting. And computer programming is especially exciting when you combine it with something fun like Magic: The Gathering. While I’m sure I could get a little excited about coding some sort of business billing application, working on a game I enjoy is much more interesting.
My goal when I write for this blog is to involve both computer programming and Magic. I try not to delve too deep into programming because I don’t want to alienate anyone, although I have a great idea for my update of the Observer pattern which I call an Ordered Observer.
So in closing, tell me what you want to read about. Do you want me to do the occasional Magic rules lawyering, such as explaining the interaction of continuous effects which has 6 layers, section 418.5 in the comprehensive rules? Or do you just want me to talk more about programming Magic? I wouldn’t mind writing a few articles about just Magic but I’m not sure what specifically to write about.
So just post a comment about what topics are interesting to you. For each comment you post I'll send you one mythic rare (this offer is invalid if you own more than 3 Magic cards). Truthfully I don't any mythic rares, so you all are out of luck ;)
I do a decent job of just working on MTG Forge and then writing about my experiences. I try to write about computer programming in an interesting fashion. I love to program and I think programming is exciting. And computer programming is especially exciting when you combine it with something fun like Magic: The Gathering. While I’m sure I could get a little excited about coding some sort of business billing application, working on a game I enjoy is much more interesting.
My goal when I write for this blog is to involve both computer programming and Magic. I try not to delve too deep into programming because I don’t want to alienate anyone, although I have a great idea for my update of the Observer pattern which I call an Ordered Observer.
So in closing, tell me what you want to read about. Do you want me to do the occasional Magic rules lawyering, such as explaining the interaction of continuous effects which has 6 layers, section 418.5 in the comprehensive rules? Or do you just want me to talk more about programming Magic? I wouldn’t mind writing a few articles about just Magic but I’m not sure what specifically to write about.
So just post a comment about what topics are interesting to you. For each comment you post I'll send you one mythic rare (this offer is invalid if you own more than 3 Magic cards). Truthfully I don't any mythic rares, so you all are out of luck ;)
Monday, November 17, 2008
Programming CardArray
Let me state the obvious, Magic is a game that involves cards, so almost every aspect of MTG Forge involves moving or counting cards, thus the “CardArray” object was created. (CardArray is an array that holds Card objects. Also remember that an object is just group of related code.) To begin with CardArray was very simple but as time went on more and more methods were added to it. (An object is a collection of many methods.)
CardArray does many things like it can return all cards that are creatures or lands. CardArray even has a filter option that lets you specify any type of criteria. The computer AI for Shock uses the filter option to burn 2/2 or 3/1 flyers.
The filter option is used for many different types of cards. Nevinyrral's Disk uses filter to first create a CardArray of only artifacts, creatures, and enchantments and then loops through that CardArray destroying everything. Needle Storm uses the filter to only damage creatures with flying. Anytime a card interacts with multiple other cards, CardArray is used. All zones, like your library and graveyard, are basically just CardArray objects.
And although CardArray is a simple chunk of code, it is very important. Since CardArray does one thing well, it holds cards, you can use it absolutely everywhere since it is very versatile.
p.s.
MTG Forge doesn’t have an object named CardArray, instead it is called CardList since it is basically just a fancy ArrayList. I used the name CardArray since most programmers know what the word “array” means.
CardArray does many things like it can return all cards that are creatures or lands. CardArray even has a filter option that lets you specify any type of criteria. The computer AI for Shock uses the filter option to burn 2/2 or 3/1 flyers.
The filter option is used for many different types of cards. Nevinyrral's Disk uses filter to first create a CardArray of only artifacts, creatures, and enchantments and then loops through that CardArray destroying everything. Needle Storm uses the filter to only damage creatures with flying. Anytime a card interacts with multiple other cards, CardArray is used. All zones, like your library and graveyard, are basically just CardArray objects.
And although CardArray is a simple chunk of code, it is very important. Since CardArray does one thing well, it holds cards, you can use it absolutely everywhere since it is very versatile.
p.s.
MTG Forge doesn’t have an object named CardArray, instead it is called CardList since it is basically just a fancy ArrayList. I used the name CardArray since most programmers know what the word “array” means.
Wednesday, November 12, 2008
AI – MTG Forge, Alpha-beta pruning
MTG Forge’s current AI is very basic. It tries to play the highest costed card and it attacks unless you have a creature that is bigger. A better AI would generate possible future game states and would then choose the best future. In other words, the AI would simulate what if it played card A and then simulate what if it played card B. This type of AI deals only with predicting future game states. Min-max and alpha-beta pruning are two types of predicting algorithms. This type of AI does not learn.
In order to effectively use predicting algorithms you have to generate many future states and you must decide how “deep” you want to test. Do you generate just one level deep for combat or do you want to generate three levels deep Main1, combat, Main2 or do you want to generate Computer Combat, Human Computer, Computer Combat?
On another issue, a better AI for MTG Forge’s draft mode would have access to a pick list and would just select the card that was highest on the list. The pick list could be a global pick list of all the cards or could be divided up into deck archetypes. The AI for sealed could be similar and use the same pick lists as the draft AI. The current draft AI randomly chooses two colors before the draft starts and then chooses creatures then spells in those colors. (It sounds brain-dead but it was pretty hard to program, lol.)
In order to effectively use predicting algorithms you have to generate many future states and you must decide how “deep” you want to test. Do you generate just one level deep for combat or do you want to generate three levels deep Main1, combat, Main2 or do you want to generate Computer Combat, Human Computer, Computer Combat?
On another issue, a better AI for MTG Forge’s draft mode would have access to a pick list and would just select the card that was highest on the list. The pick list could be a global pick list of all the cards or could be divided up into deck archetypes. The AI for sealed could be similar and use the same pick lists as the draft AI. The current draft AI randomly chooses two colors before the draft starts and then chooses creatures then spells in those colors. (It sounds brain-dead but it was pretty hard to program, lol.)
Monday, November 10, 2008
AI Thoughts – Genetic Algorithms and Neural Networks
AI (artificial intelligence) is a great subject so I thought I would discuss what little I know about it. Let me first tell you a little about my educational background, I have my bachelor’s in Information Science and I didn’t take any AI classes in college. My knowledge about AI comes from miscellaneous web articles and the three random books I have own the subject.
AI encompasses a huge number of topics ranging from getting a computer to drive a car to trying to find fraudulent credit card charges. There are many different types of AI algorithms and techniques. Some techniques require a vast amount of historical data while others do not. Videogame AI usually has to be fast, to simulate the response of a real human. In my opinion most videogames have only a very basic AI. Many videogames like Mario don’t have any AI and it is just the player versus the environment.
People sometimes talk about neural networks or genetic algorithms but they don’t usually work well for videogames. Neural networks usually have many inputs and only one output. They are typically used to output an answer like yes or no. Neural networks are also very complicated to setup and test.
Genetic algorithms find an optimal or near-optimal solution to a problem by generating random actions. Granted the problem could be “how to win a game of Magic” but encoding a game of Magic into a genetic algorithm would be extremely difficult. Usually genetic algorithms are encoded as strings, although this is not a requirement. The strings are split and combined to form new strings. Each string is evaluated until a solution is found.
Join me next time as I continue our journey into AI.
AI encompasses a huge number of topics ranging from getting a computer to drive a car to trying to find fraudulent credit card charges. There are many different types of AI algorithms and techniques. Some techniques require a vast amount of historical data while others do not. Videogame AI usually has to be fast, to simulate the response of a real human. In my opinion most videogames have only a very basic AI. Many videogames like Mario don’t have any AI and it is just the player versus the environment.
People sometimes talk about neural networks or genetic algorithms but they don’t usually work well for videogames. Neural networks usually have many inputs and only one output. They are typically used to output an answer like yes or no. Neural networks are also very complicated to setup and test.
Genetic algorithms find an optimal or near-optimal solution to a problem by generating random actions. Granted the problem could be “how to win a game of Magic” but encoding a game of Magic into a genetic algorithm would be extremely difficult. Usually genetic algorithms are encoded as strings, although this is not a requirement. The strings are split and combined to form new strings. Each string is evaluated until a solution is found.
Join me next time as I continue our journey into AI.
Friday, November 7, 2008
MTG Forge – New Version
I posted a new version of MTG Forge and you can get it here. This is only a minor update. You can now import and export any type of deck: sealed, draft, or constructed. When you import another person’s draft deck, it will be listed with your other draft decks, the same goes for sealed and constructed. When you import a draft deck it will only show the cards that the person picked, you don’t get to draft again.
The export deck option now creates a text file showing the deck’s contents. Below is an example of what the text file looks like. This should save some time when you post a deck. You can post and download decks here. Creating a new deck and posting it is really fun, I encourage you to try it out. You can even checkout some of my (lame) decks, lol.
And remember to save a copy of the file "all-decks2" since that holds all of the decks that you have created.
40 Total Cards
22 Creatures
-------------
1x Haunted Angel
4x Lantern Kami
4x Leonin Skyhunter
4x Mistral Charger
3x Radiant, Archangel
2x Serra Avenger
4x Suntail Hawk
2 Spells
----------
1x Glorious Anthem
1x Wrath of God
16 Land
--------
16x Plains
The export deck option now creates a text file showing the deck’s contents. Below is an example of what the text file looks like. This should save some time when you post a deck. You can post and download decks here. Creating a new deck and posting it is really fun, I encourage you to try it out. You can even checkout some of my (lame) decks, lol.
And remember to save a copy of the file "all-decks2" since that holds all of the decks that you have created.
40 Total Cards
22 Creatures
-------------
1x Haunted Angel
4x Lantern Kami
4x Leonin Skyhunter
4x Mistral Charger
3x Radiant, Archangel
2x Serra Avenger
4x Suntail Hawk
2 Spells
----------
1x Glorious Anthem
1x Wrath of God
16 Land
--------
16x Plains
Wednesday, November 5, 2008
Random Thoughts
I don’t have anything specific to talk about today, so I’m just going to ramble until I get 200-300 words. I haven’t worked much on MTG Forge version 2 recently. Real life is getting in the way of my hobbies, lol. I still think about version 2, I just need to sit down for about 30 minutes a day and just get something done. I enjoy programming because it is actually pretty easy. (Usually programming is easy, but trying to fix a specific bug is usually very hard.)
For version 2 I want to implement a better AI but if I can’t, you’ll just have to make do with the current AI. Artificial intelligence is very interesting to programmers and non-programmers alike. AI covers everything, so it is hard to learn a specific concept and apply to the problem that you are working on. Like a car racing AI can only race cars. The AI also is tightly integrated with the rest of the program, so you can’t really strip the AI out and use it for something else.
On a different front, Shards of Alara looks like a great set. It is dripping flavor and has several new mechanics to learn. I remember when Lorwyn came out and no one was sure how clash was going to work, the same thing goes for Ravnica and dredge.
p.s. The card picture is from the Jace vs. Chandra decks which have their own unique, set symbol.
p.s.s. Join me next week for two semi-decent AI articles :)
For version 2 I want to implement a better AI but if I can’t, you’ll just have to make do with the current AI. Artificial intelligence is very interesting to programmers and non-programmers alike. AI covers everything, so it is hard to learn a specific concept and apply to the problem that you are working on. Like a car racing AI can only race cars. The AI also is tightly integrated with the rest of the program, so you can’t really strip the AI out and use it for something else.
On a different front, Shards of Alara looks like a great set. It is dripping flavor and has several new mechanics to learn. I remember when Lorwyn came out and no one was sure how clash was going to work, the same thing goes for Ravnica and dredge.
p.s. The card picture is from the Jace vs. Chandra decks which have their own unique, set symbol.
p.s.s. Join me next week for two semi-decent AI articles :)
Monday, November 3, 2008
How to Program Royal Assassin
From time to time I like looking at how other Magic projects implemnt a card. I love Royal Assassin, this is how Firemox (formally the Magic-Project) and Incantus encode it. Incantus has card characteristics and if you read Magic’s comprehensive rules you will notice that it uses characteristics also. Since both Firemox and Incantus put each card in a separate file, all you have to do is download the file from the Internet and put it in the right directory and voila you have just added a new card.
In an effort to be complete, I’ll also show you the code for Royal Assassin taken from MTG Forge. The code is a little long and complicated compared to Firemox and Incantus. The Input class handles all mouse input, so a new Input object is created and used to target a tapped creature.
Incantus
Firemox
MTG Forge
In an effort to be complete, I’ll also show you the code for Royal Assassin taken from MTG Forge. The code is a little long and complicated compared to Firemox and Incantus. The Input class handles all mouse input, so a new Input object is created and used to target a tapped creature.
Incantus
//filename: Royal Assassin
name = 'Royal Assassin'
cardnum = 174
type = characteristic('Creature')
supertype = characteristic('')
subtypes = characteristic(['Human', 'Assassin'])
cost = '1BB'
color = characteristic(['B'])
text = ['T Destroy target tapped creature.']
in_play_role = Creature(card, 1, 1)
in_play_role.abilities = [ActivatedAbility(card, TapCost(),
target=Target(target_types=isCreature.with(lambda c: c.tapped)),
effects=Destroy())
]
in_play_role.triggered_abilities = []
in_play_role.static_abilities = []
Firemox
//filename: Royal_Assassin.xml
//all brackets were converted to quotes
//in order to be displayed correctly
"?xml version="1.0"?"
"card xmlns="http://sourceforge.net/projects/firemox" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=http://sourceforge.net/projects/firemox ../../validator.xsd name="Royal Assassin""
"rules-author-comment"By fabdouglas"/rules-author-comment"
"init"
"registers"
"register index="colorless" value="1"/"
"register index="black" value="2"/"
"register index="power" value="1"/"
"register index="toughness" value="1"/"
"/registers"
"colors"black"/colors"
"idcards"creature "/idcards"
"properties"assassin"/properties"
"/init"
"abilities"
"ability ref="cast-spell"/"
"activated-ability playable="instant" name="" zone="play""
"cost"
"action ref="T"/"
"action ref="target-creature""
"test"
"in-zone zone="playANDtapped"/"
"/test"
"/action"
"/cost"
"effects"
"action ref="destroy"/"
"/effects"
"/activated-ability"
"/abilities"
"/card"
MTG Forge
//taken from the infamous CardFactory
if(cardName.equals("Royal Assassin"))
{
final Ability_Tap ability = new Ability_Tap(card)
{
public boolean canPlayAI()
{
CardList human =
CardFactoryUtil.AI_getHumanCreature();
human = human.filter(new CardListFilter()
{
public boolean addCard(Card c)
{return c.isTapped();}
});
CardListUtil.sortAttack(human);
CardListUtil.sortFlying(human);
if(0 < human.size())
setTargetCard(human.get(0));
return 0 < human.size();
}//canPlayAI()
public void resolve()
{
Card c = getTargetCard();
if(AllZone.GameAction.isCardInPlay(c)
&& c.isTapped())
{
AllZone.GameAction.destroy(c);
}
}//resolve()
};//SpellAbility
Input target = new Input()
{
public void showMessage()
{
AllZone.Display.showMessage("Select target tapped creature to destroy");
ButtonUtil.enableOnlyCancel();
}
public void selectButtonCancel()
{stop();}
public void selectCard(Card c, PlayerZone zone)
{
if(c.isCreature() &&
zone.is(Constant.Zone.Play) &&
c.isTapped())
{
//tap ability
card.tap();
ability.setTargetCard(c);
AllZone.Stack.add(ability);
stop();
}//if
}//selectCard()
};//Input
card.addSpellAbility(ability);
ability.setDescription("tap: Destroy target tapped creature.");
ability.setBeforePayMana(target);
}
Wednesday, October 29, 2008
Adding New Cards
MTG Forge and Magic both revolve around cards and more specifically, new cards. Magic is a great game but if the flow of new cards ever stops, most of Magic’s popularity would evaporate. Granted a small army of people would try to keep it alive but trading card games need new cards and so does MTG Forge.
I’m glad people are using these forums and creating new cards. The problem is that you can’t just download a card that someone else makes. A whole new version of MTG Forge has to be released in order to add a new card. (Granted you can add the card code and compile it yourself, but the average use can’t do this.) You can get the latest version of MTG Forge from here. Thanks for jpb for adding all the cards from the forums. It has around 90 new cards. There are still some errors, Will-o-wisp has two regenerate abilities, and not all of the new card pictures are downloaded.
Version 2 all cards should be just text files. So in order to add a new card, you just download the file and put it in the correct directory. Each card will has its own file and the card will be generated when the program first starts up. The cards will be created on the fly, at runtime which is better than hard coded Java cards. Programming Magic cards in Java is confusing and that is why other projects use other language, Firemox uses XML and Incantus uses Python. Next time I’ll show you the code for Royal Assassin from Firemox and Incantus.
I’m glad people are using these forums and creating new cards. The problem is that you can’t just download a card that someone else makes. A whole new version of MTG Forge has to be released in order to add a new card. (Granted you can add the card code and compile it yourself, but the average use can’t do this.) You can get the latest version of MTG Forge from here. Thanks for jpb for adding all the cards from the forums. It has around 90 new cards. There are still some errors, Will-o-wisp has two regenerate abilities, and not all of the new card pictures are downloaded.
Version 2 all cards should be just text files. So in order to add a new card, you just download the file and put it in the correct directory. Each card will has its own file and the card will be generated when the program first starts up. The cards will be created on the fly, at runtime which is better than hard coded Java cards. Programming Magic cards in Java is confusing and that is why other projects use other language, Firemox uses XML and Incantus uses Python. Next time I’ll show you the code for Royal Assassin from Firemox and Incantus.
Monday, October 27, 2008
The Mighty Rules Engine
One object to rule them all and in the darkness bind them. OK, enough of my Lord of the Rings paraphrase. In MTG Forge version 2 I have an object named “RulesEngine” that holds all rules of a Magic game. All game actions go through the Rules Engine like drawing a card, destroying a creature or advancing to the next phase.
Let me briefly explain what an object is to non-programmers. An object is a group of code that works on the same data. In Magic terms, a Card object would handle all card operations like changing the toughness, adding keywords and getting the card name. The term “class” is also thrown around and for our purposes “class” means the same as object. In Java object names are typically capitalized so that is why I wrote Card object, instead of card object.
Anyways, back to the Rules Engine. Unfortunately the Rules Engine object will be a very complicated and long, since it has to do everything. Currently MTG Forge tries to group many of the rules into GameAction but I did this mostly to save code. All of the rules should be put in one object. In case some rule needs to be fixed or modified, I know where to go, the Rule Engine object.
The cool thing about the rule engine is that it can be easily modified. Do you want to play type 4 with unlimited mana, done. Any rule can be modified. Complicated cards like Mana Flare (each land produces one extra mana) should be fairly simple to implement using the rules engine. I’m also hoping to be able to program one of Magic’s most powerful cards, Time Walk. (1U, Sorcery, take an extra turn after this one.)
p.s.
I must complete my Lord of the Rings paraphrase. I find this terribly funny. And in case you didn’t get it, the one object to rule them all is the Rules Engine.
One object to rule them all, One object to find them,
One object to bring them all and in the darkness bind them
Let me briefly explain what an object is to non-programmers. An object is a group of code that works on the same data. In Magic terms, a Card object would handle all card operations like changing the toughness, adding keywords and getting the card name. The term “class” is also thrown around and for our purposes “class” means the same as object. In Java object names are typically capitalized so that is why I wrote Card object, instead of card object.
Anyways, back to the Rules Engine. Unfortunately the Rules Engine object will be a very complicated and long, since it has to do everything. Currently MTG Forge tries to group many of the rules into GameAction but I did this mostly to save code. All of the rules should be put in one object. In case some rule needs to be fixed or modified, I know where to go, the Rule Engine object.
The cool thing about the rule engine is that it can be easily modified. Do you want to play type 4 with unlimited mana, done. Any rule can be modified. Complicated cards like Mana Flare (each land produces one extra mana) should be fairly simple to implement using the rules engine. I’m also hoping to be able to program one of Magic’s most powerful cards, Time Walk. (1U, Sorcery, take an extra turn after this one.)
p.s.
I must complete my Lord of the Rings paraphrase. I find this terribly funny. And in case you didn’t get it, the one object to rule them all is the Rules Engine.
One object to rule them all, One object to find them,
One object to bring them all and in the darkness bind them
Wednesday, October 22, 2008
Phase Stops
Letting the user select which phases stop, so a card or ability can be played, is trickier than it seems. Programming phase stops is actually pretty hard because it is easy to get it wrong. I thought I was done with the phase stop code in version 2, but after testing it, the code didn’t quite work correctly. The good news is that I’ve written new code and version 2 has all the phases and the phase stops work.
The original phase stop code comes from a previous attempt at version 2 that I was working on a year ago and it had three buttons: OK, Cancel, and Reset. Each button is supposed to be very simple but they didn’t work correctly. The OK button saves your choices. The Cancel button doesn’t save your choices but it still has to reset graphic checkbox components that show you which checkboxes are selected. And the Reset button stops only during your two Main phases. (The program always lets you declare your attackers and blockers, you cannot accidentally skip those phases.)
So the phase stop code works and hopefully I won’t have to update it for a long awhile. Version 2 just cycles through the phases but this is an important step. This means that the Phase object is correctly going to the next phase, which seems minor but it is very important.
In MTG Forge, the reason that the computer can’t be the first player is because there is a problem with the phase cycle. I accidentally forgot to test if the computer could go first. In conclusion, phases and phase stops are hard to code but very important.
p.s. What are the default phase stops for Magic Online?
This is how the phase stop menu looks in version 2.
The original phase stop code comes from a previous attempt at version 2 that I was working on a year ago and it had three buttons: OK, Cancel, and Reset. Each button is supposed to be very simple but they didn’t work correctly. The OK button saves your choices. The Cancel button doesn’t save your choices but it still has to reset graphic checkbox components that show you which checkboxes are selected. And the Reset button stops only during your two Main phases. (The program always lets you declare your attackers and blockers, you cannot accidentally skip those phases.)
So the phase stop code works and hopefully I won’t have to update it for a long awhile. Version 2 just cycles through the phases but this is an important step. This means that the Phase object is correctly going to the next phase, which seems minor but it is very important.
In MTG Forge, the reason that the computer can’t be the first player is because there is a problem with the phase cycle. I accidentally forgot to test if the computer could go first. In conclusion, phases and phase stops are hard to code but very important.
p.s. What are the default phase stops for Magic Online?
This is how the phase stop menu looks in version 2.
Monday, October 20, 2008
MTG Forge - Minor Update
I uploaded a new version of MTG Forge but it is only a minor update. I think the only thing I added to the beta version were the 10 duel lands. Currently there is just a zip file but I will have the typical Windows installer uploaded by Tuesday. MTG Forge now has 870 cards.
This update has the complete source code and I updated the readme-compile.html file. I tested the source code twice and everything compiles like it should. MTG Forge will only compile with Java 1.4.
Remember to keep a copy of the file "all-decks2" because that holds all of the decks that you have created. If you still have the file “all-decks”, it is old and can be deleted.
MTG Forge comes with a “Quick Start” guide that answers common questions like how to target a player (click on the player’s life points) and how to download the card pictures (just look in the New Game menu). Just for fun I included an article written by Magic’s creator Richard Garfield that explains how he created the game and the early years in Magic History.html. You can read it here.
Download MTG Forge – includes Windows exe and Java jar for all operating systems as well as the source code
p.s. If somehow you are reading this article and you don’t know how to play Magic: The Gathering, download this demo and have some fun.
Windows Demo (85 MB)
This update has the complete source code and I updated the readme-compile.html file. I tested the source code twice and everything compiles like it should. MTG Forge will only compile with Java 1.4.
Remember to keep a copy of the file "all-decks2" because that holds all of the decks that you have created. If you still have the file “all-decks”, it is old and can be deleted.
MTG Forge comes with a “Quick Start” guide that answers common questions like how to target a player (click on the player’s life points) and how to download the card pictures (just look in the New Game menu). Just for fun I included an article written by Magic’s creator Richard Garfield that explains how he created the game and the early years in Magic History.html. You can read it here.
Download MTG Forge – includes Windows exe and Java jar for all operating systems as well as the source code
p.s. If somehow you are reading this article and you don’t know how to play Magic: The Gathering, download this demo and have some fun.
Windows Demo (85 MB)
Wednesday, October 15, 2008
More Plaintext Cards
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
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
Monday, October 13, 2008
AI and Limited Decks
While constructed decks are very focused, limited decks are not. Limited decks tend to be composed of good cards with a general theme. Limited decks tend to be more generalized because they rely on a mix of creatures and spells. The AI is very good at playing creatures since it just plays the biggest one and then attacks with it. I feel that the AI’s attacking and blocking strategy can be greatly improved in version 2.
So if MTG Forge is a limited simulator why does it matter? In case you forgot, the most important cards in limited are the commons, so I plan to program more commons in the future.
Commons are the least complicated cards, thus making them the easiest to program, and I plan to start with the commons of the Shards of Alara. (Everyone loves new cards, even programmers!!!) I’m not saying that I won’t program any uncommons or rares, I’m just saying that I will focus on the commons first.
And to tell you the truth, the effects on the common cards don’t give me nightmares like the rares. Programming one replacement effect is easy enough, but having multiple replacement effects is downright confusing. Most uncommons usually can be added with a little bit more effort. The fact of the matter is that it still takes loads of time and energy to program Magic cards, even the simple ones. If someone ever programs a whole block, bless his weary soul.
So if MTG Forge is a limited simulator why does it matter? In case you forgot, the most important cards in limited are the commons, so I plan to program more commons in the future.
Commons are the least complicated cards, thus making them the easiest to program, and I plan to start with the commons of the Shards of Alara. (Everyone loves new cards, even programmers!!!) I’m not saying that I won’t program any uncommons or rares, I’m just saying that I will focus on the commons first.
And to tell you the truth, the effects on the common cards don’t give me nightmares like the rares. Programming one replacement effect is easy enough, but having multiple replacement effects is downright confusing. Most uncommons usually can be added with a little bit more effort. The fact of the matter is that it still takes loads of time and energy to program Magic cards, even the simple ones. If someone ever programs a whole block, bless his weary soul.
Friday, October 10, 2008
Computer Programming Comics
I love computer programming and comic books but those two passions don't usually intersect, but today they do. Recently, Google wrote an Internet browser called Chrome. Instead of using a boring press release to describe Chrome's features, Google decided to use an online comic book. The comic book is very funny, smart and easy to read. Programmers and non-programmers alike will laugh.
Chrome Comic Book
Chrome Comic Book
Wednesday, October 8, 2008
What is MTG Forge's Goal?
Recently I kept asking myself this question, “What is the real point of MTG Forge?” Is MTG Forge trying to help people learn more about the rules? (Originally I envisioned MTG Forge as more of an interactive rulebook than a videogame after reading a question someone submitted about Mirrodin’s new equipment subtype. The person totally misunderstood the idea of equipment.) Obviously, one of my goals was to simply play a game of Magic but to what end? Was MTG Forge trying to be a tournament simulator?
In my head I have always thought of MTG Forge as a limited simulator. I believe MTG Forge could really shine in sealed and draft games. MTG Forge will always essentially be a little bit weaker in constructed games since they have very focused decks that execute a specific plan which require playtesting in order use correctly.
The computer AI will not have the luxury of playtesting like a human player and the computer will try to compensate by playing the deck as good as it can but the AI won’t follow deck’s overall game plan. Granted, specific AI’s could be written to play specific decks or types of decks which would improve the AI’s performance.
Join me next time as I continue my discussion of how MTG Forge’s uses limited decks, thank you and good night.
In my head I have always thought of MTG Forge as a limited simulator. I believe MTG Forge could really shine in sealed and draft games. MTG Forge will always essentially be a little bit weaker in constructed games since they have very focused decks that execute a specific plan which require playtesting in order use correctly.
The computer AI will not have the luxury of playtesting like a human player and the computer will try to compensate by playing the deck as good as it can but the AI won’t follow deck’s overall game plan. Granted, specific AI’s could be written to play specific decks or types of decks which would improve the AI’s performance.
Join me next time as I continue my discussion of how MTG Forge’s uses limited decks, thank you and good night.
Monday, October 6, 2008
MTG Forge Forum
I’m glad that MTG Forge has its own forum thanks to Slightly Magic. And thanks to some fancy programming, they even have a feature that displays the card text when your mouse is hovering over the card name. For example if you move your mouse cursor over the text “Ancestral Recall” it will show you the text for that card, very cool indeed.
On MTG Forge’s forums you can discuss anything about the program. I have posted a master list of all known bugs and other people have posted bugs also. The deck sub-forum is getting quite popular. The beta version of MTG Forge lets you import or export a deck, so people are posting their decks.
I have posted 2 decks: a Black Vise and an Akroma, Angle of Wrath deck. Posting your own deck creation is pretty fun and I would encourage you to participate. I even asked for a 5 color, 60 card singleton deck and someone posted one for me, thanks Gando. So checkout MTG Forge’s forums and have some fun.
MTG Forge Forum
Slightly Magic Forum
(Slightly Magic holds all the forums and MTG Forge has its own sub-forum, got it?)
p.s. Slightly Magic’s forums also have many other Magic programs like Incantus if you want to read about them. There is also the HQ Project which aims to provide high quality picture scans of all Magic cards in existence, which is quite a task considering there are about 10,000 cards not including promos. It is fun to download all the token pictures and look through them.
On MTG Forge’s forums you can discuss anything about the program. I have posted a master list of all known bugs and other people have posted bugs also. The deck sub-forum is getting quite popular. The beta version of MTG Forge lets you import or export a deck, so people are posting their decks.
I have posted 2 decks: a Black Vise and an Akroma, Angle of Wrath deck. Posting your own deck creation is pretty fun and I would encourage you to participate. I even asked for a 5 color, 60 card singleton deck and someone posted one for me, thanks Gando. So checkout MTG Forge’s forums and have some fun.
MTG Forge Forum
Slightly Magic Forum
(Slightly Magic holds all the forums and MTG Forge has its own sub-forum, got it?)
p.s. Slightly Magic’s forums also have many other Magic programs like Incantus if you want to read about them. There is also the HQ Project which aims to provide high quality picture scans of all Magic cards in existence, which is quite a task considering there are about 10,000 cards not including promos. It is fun to download all the token pictures and look through them.
Friday, October 3, 2008
OCTGN - Card Playing Software
There seems to be many trading card game projects floating around the Internet. I thought I would have heard about most of the major projects, and maybe I have, but here is another project called OCTGN which lets you play card games against other players over the Internet.
OCTGN supports Magic and major a few other cards games, although the documentation is nonexistent. I presume it does not enforce the rules but I could be wrong, again there is no documentation. It does support Two-Headed Giant would should be some fun, below is a screenshot. You can find more information by searching Google for OCTGN.
Main OCTGN Site
OCTGN Blog
OCTGN supports Magic and major a few other cards games, although the documentation is nonexistent. I presume it does not enforce the rules but I could be wrong, again there is no documentation. It does support Two-Headed Giant would should be some fun, below is a screenshot. You can find more information by searching Google for OCTGN.
Main OCTGN Site
OCTGN Blog
Wednesday, October 1, 2008
Random Thoughts About Version 2
I don’t have anything specific to write about today. I’ve done a lot of work on MTG Forge version 2, mostly “background code” that handles mouse clicks and stuff that is taken for granted. Thankfully the background code doesn’t usually have to be updated, so once it is written, it works.
The user interface for version 2 is working. It looks exactly like the current user interface but it uses abstract interfaces for the visual components (see the previous article). Some of the basic components like how I handle the mouse are the same as version 1, I still use the Input class.
I have all of the dialog boxes working. Dialog boxes are the popup boxes that ask you “Do you want to pay 2 life?” Yes or No. I have dialog boxes that show one card, many cards, just to show a message and one that shows a message with the yes/no button. The dialog boxes are a good example of background code.
I first started on working on MTG Forge version 2 over a year ago but I’ve only worked on it off and on. Over the last few days I’ve worked on it like a madman at 2am, 4am, and 6am. Currently version 2 is 131 KB of code, while version 1 weighs in at a hefty 1,000 KB. You have to keep in mind that version 1 probably should be 50% smaller if all of the redundant code was removed. (I would tell you the number of lines that version 2 has but I would have to write a small program and I’ve kind of burned out at the moment.)
Right now version 2 has working life points, mana pool, and board (the zones your hand and in play). Also the mouse click event works when you click on the life points, mana pool, or a card on the board. The “card detail” window on the right also works.
The next step is to get the user interface to cycle through all of the phases and to allow the user to select which phases to stop. Hopefully after I do that, I can actually program a card or two. I really want to just program cards, all of the background code is just laying the foundation. I’m going to lay a solid foundation so I don’t have to ever touch it again.
p.s. Version 2 will have ALL of Magic’s phases, so you can stop whenever you want to.
p.s. You can check out a visual spoiler of Shard of Alara here. We can all drool over the mega rares, lols.
The user interface for version 2 is working. It looks exactly like the current user interface but it uses abstract interfaces for the visual components (see the previous article). Some of the basic components like how I handle the mouse are the same as version 1, I still use the Input class.
I have all of the dialog boxes working. Dialog boxes are the popup boxes that ask you “Do you want to pay 2 life?” Yes or No. I have dialog boxes that show one card, many cards, just to show a message and one that shows a message with the yes/no button. The dialog boxes are a good example of background code.
I first started on working on MTG Forge version 2 over a year ago but I’ve only worked on it off and on. Over the last few days I’ve worked on it like a madman at 2am, 4am, and 6am. Currently version 2 is 131 KB of code, while version 1 weighs in at a hefty 1,000 KB. You have to keep in mind that version 1 probably should be 50% smaller if all of the redundant code was removed. (I would tell you the number of lines that version 2 has but I would have to write a small program and I’ve kind of burned out at the moment.)
Right now version 2 has working life points, mana pool, and board (the zones your hand and in play). Also the mouse click event works when you click on the life points, mana pool, or a card on the board. The “card detail” window on the right also works.
The next step is to get the user interface to cycle through all of the phases and to allow the user to select which phases to stop. Hopefully after I do that, I can actually program a card or two. I really want to just program cards, all of the background code is just laying the foundation. I’m going to lay a solid foundation so I don’t have to ever touch it again.
p.s. Version 2 will have ALL of Magic’s phases, so you can stop whenever you want to.
p.s. You can check out a visual spoiler of Shard of Alara here. We can all drool over the mega rares, lols.
Monday, September 29, 2008
Want to help? Write My Gui
I stink at writing user interfaces. I think they are hard, tedious and like getting a root canal (thankfully I’ve never gotten one but I’ve heard bad, bad things). The good news is that I’m making it easier for you to help me write the gui, prounounced gooey if you are actually talking to another living, breathing person about programming instead of just writing about it, joke, laugh.
The user interface in MTG Forge is pretty basic anyways. The gui basically shows cards and you can only click on those cards. I’ve made those component into abstractions (Java interfaces) so someone else could easily come along and say, “I can easily write this 3D stuff that has a virtual playmat, do you want that?” And I would say, “Sure, dude.”
The other good news is that I’m making it even easier because I am already handling all of the events of the abstract components. In other words if you were writing the code to display a Magic card, you don’t have to worry about what to do if the user clicks on the card, you worry about what is the coolest way to display that card. All of the events are already being handled, which makes the coding more complicated for me but less complicated for you. Thanks, your welcome.
The user interface in MTG Forge is pretty basic anyways. The gui basically shows cards and you can only click on those cards. I’ve made those component into abstractions (Java interfaces) so someone else could easily come along and say, “I can easily write this 3D stuff that has a virtual playmat, do you want that?” And I would say, “Sure, dude.”
The other good news is that I’m making it even easier because I am already handling all of the events of the abstract components. In other words if you were writing the code to display a Magic card, you don’t have to worry about what to do if the user clicks on the card, you worry about what is the coolest way to display that card. All of the events are already being handled, which makes the coding more complicated for me but less complicated for you. Thanks, your welcome.
Wednesday, September 24, 2008
What Other Cards Are Famous?
I recently added Black Vise to the beta version of MTG Forge and people seem to really love that card. That got me thinking about other cards that people would really love to use. I don’t know the answer so you have to leave a comment but I’ll make an educated guess about some other great cards. Since MTG Forge lets you play against the computer, you can use unfair, one-sided cards like Black Vise without making your opponent mad.
Probably most of Magic’s most memorable cards like Ancestral Recall and Lightning Bolt are from the earlier sets. Alpha had many super powerful cards. I was thinking that Land Tax is probably as famous as Black Vise. You can thoroughly abuse Land Tax and almost use it as a win condition.
Winter Orb is a very nasty card also. Orb would definitely hurt any opponent. Mana Flare is a great, fun, build-around-me card that at least doesn’t annoy your opponent. Berserk is an odd green instant that can be used as a pump spell or removal, since the creature is destroyed. I remember the computer using Berserk as a removal spell and it surprised me.
Necropotence is a very powerful black enchantment that lets you a draw card while reducing your life points. And Skullclamp was good enough to get banned, I guess drawing 2 cards every time you sacrificed a 1/1 creature was too good. White probably has the most well-known cards in all of Magic, Wrath of God and Serra Angel.
What others cards are as iconic and powerful as Black Vise?
Probably most of Magic’s most memorable cards like Ancestral Recall and Lightning Bolt are from the earlier sets. Alpha had many super powerful cards. I was thinking that Land Tax is probably as famous as Black Vise. You can thoroughly abuse Land Tax and almost use it as a win condition.
Winter Orb is a very nasty card also. Orb would definitely hurt any opponent. Mana Flare is a great, fun, build-around-me card that at least doesn’t annoy your opponent. Berserk is an odd green instant that can be used as a pump spell or removal, since the creature is destroyed. I remember the computer using Berserk as a removal spell and it surprised me.
Necropotence is a very powerful black enchantment that lets you a draw card while reducing your life points. And Skullclamp was good enough to get banned, I guess drawing 2 cards every time you sacrificed a 1/1 creature was too good. White probably has the most well-known cards in all of Magic, Wrath of God and Serra Angel.
What others cards are as iconic and powerful as Black Vise?
Monday, September 22, 2008
More Cards, More Errors
I saw the statement somewhere that said, “Maybe you should fix the current card errors rather than trying to add new cards.” I figured other people might also have this question, so I might as well answer it.
My overall goal is to add as many Magic cards as I can and if sometimes they don’t work correctly, oh well. I know some people might say that I’m taking the easy route and I certainly am. Testing a card for me means that I might play it once or twice to see if it generally works. Sometimes I don’t even check to see if the computer can play it correctly, I just hope it does.
The problem with more extensive testing is that it means fewer cards. If I test each card in five different situations, I’m going to be bored and program fewer cards. I also get a thrill by adding new cards and debugging old ones are pretty low on my agenda. For version 2, I plan to be more strict in my card implementations.
Version 1 has a good number of cards and also a fair amount of errors. While the errors are occasionally annoying, I think my time would be better spent on version 2. So I personally think that version 1 is “good enough.” If someone wants to improve version 1, go ahead, you can join my Google Project or start your own project and use my source code as a starting point.
Version 1 has many fundamental errors that can’t be fixed like the computer can’t play instants during combat, no X spells, no “removed from play” triggers, and a million other things. Version 2 is a clean slate that incorporates all of the things that I learned while programming version 1.
My overall goal is to add as many Magic cards as I can and if sometimes they don’t work correctly, oh well. I know some people might say that I’m taking the easy route and I certainly am. Testing a card for me means that I might play it once or twice to see if it generally works. Sometimes I don’t even check to see if the computer can play it correctly, I just hope it does.
The problem with more extensive testing is that it means fewer cards. If I test each card in five different situations, I’m going to be bored and program fewer cards. I also get a thrill by adding new cards and debugging old ones are pretty low on my agenda. For version 2, I plan to be more strict in my card implementations.
Version 1 has a good number of cards and also a fair amount of errors. While the errors are occasionally annoying, I think my time would be better spent on version 2. So I personally think that version 1 is “good enough.” If someone wants to improve version 1, go ahead, you can join my Google Project or start your own project and use my source code as a starting point.
Version 1 has many fundamental errors that can’t be fixed like the computer can’t play instants during combat, no X spells, no “removed from play” triggers, and a million other things. Version 2 is a clean slate that incorporates all of the things that I learned while programming version 1.
Friday, September 19, 2008
Updated Beta
There is a new beta version of MTG Forge with 869 cards. The only reason I call it beta, is because not all the card pictures download yet. Checkout my new Black Vise W/U control deck here.
What’s New
1. New Cards: Naturalize, Disenchant, Demystify, Castle, Convalescence, Black Vise, Alert Shu Infantry, Alaborn Grenadier, Archon of Justice, 10 original duel lands (Savannah, etc..), Storm Herd, Festival of Trokin (Yes it is a bunch of random cards.)
2. You can now import and export decks using the deck editor. When you export a deck it is saved to a file and someone else can import that deck into MTG Forge and use it. (There are probably a few errors lurking, but it seems to work. This code actually worked the first time and anytime you write around 100 lines of code and it works perfectly, it is unusual to say the least.)
3. Fixed: Shadow creatures being able to block non-shadow creatures.
4. Fixed: Regenerated creatures now become tapped.
5. Fixed: Sometimes you would draw more than 1 card.
6. Fixed: River Merfolk, its activated ability cost 0 and the computer would go into an infinite loop.
7. Fixed: Thunder Wall – it now has flying
8. Fixed: Creatures with flash in the cards.txt file, like Briarhorn, Havenwood Wurm, King Cheetah, Raging Kavu, Tangle Spider, Sentinels of Glen Elendra
9. Fixed: Soul Warden and Essence Warden. They had problems when you played multiple copies. (Thanks for the donated code.)
10. Fixed: Control Magic and Sower of Temptation, they didn’t reset summoning sickness, so you could steal the creature and then attack with it.
11. Fixed: Oblivion Ring and Oubliette, they now work correctly.
What’s New
1. New Cards: Naturalize, Disenchant, Demystify, Castle, Convalescence, Black Vise, Alert Shu Infantry, Alaborn Grenadier, Archon of Justice, 10 original duel lands (Savannah, etc..), Storm Herd, Festival of Trokin (Yes it is a bunch of random cards.)
2. You can now import and export decks using the deck editor. When you export a deck it is saved to a file and someone else can import that deck into MTG Forge and use it. (There are probably a few errors lurking, but it seems to work. This code actually worked the first time and anytime you write around 100 lines of code and it works perfectly, it is unusual to say the least.)
3. Fixed: Shadow creatures being able to block non-shadow creatures.
4. Fixed: Regenerated creatures now become tapped.
5. Fixed: Sometimes you would draw more than 1 card.
6. Fixed: River Merfolk, its activated ability cost 0 and the computer would go into an infinite loop.
7. Fixed: Thunder Wall – it now has flying
8. Fixed: Creatures with flash in the cards.txt file, like Briarhorn, Havenwood Wurm, King Cheetah, Raging Kavu, Tangle Spider, Sentinels of Glen Elendra
9. Fixed: Soul Warden and Essence Warden. They had problems when you played multiple copies. (Thanks for the donated code.)
10. Fixed: Control Magic and Sower of Temptation, they didn’t reset summoning sickness, so you could steal the creature and then attack with it.
11. Fixed: Oblivion Ring and Oubliette, they now work correctly.
Wednesday, September 17, 2008
Version 2
Talking about the future is a dangerous thing, just read George Orwell’s 1984, but I’m going to briefly talk about MTG Forge version 2. It will be written in Java and it will use the current user interface. I really suck at writing user interfaces and I was getting tired of trying to write a better one. Hopefully in the future, the user interface will be changed/updated by someone who has more skill in that area.
As I mentioned last week, all of the Magic cards are going to be encoded using plaintext so many cards can share the same Java code, so I can just write the “destroy creature” code once.
wrath of god.txt
Wrath of God
2 W W
Sorcery
Spell
Text: Destroy all creatures. They can’t be regenerated.
Resolve: destroy all creatures – no regeneration
I might have to update the card format above to tell the AI what phase is best to play the card. Like Wrath of God should be played during the computer’s Main 2 phase, while Giant Growth should be playing After Declaring Blockers.
I also plan to have an updated AI. The AI feature is the unique feature of MTG Forge and while the current AI is basic, I hope to improve its performance. I plan to use some type of algorithm that “looks ahead” and does a few actions, scores the results, and then does the best action. This is basically what you do in your head when you make a decision, you try to see all possible results and you choose the best action.
I plan to have at least a few AI personalities like the aggro or control player. This should at least keep you guessing about what personality the AI is currently using. I am also hoping for “deck specific” AIs that I can write to play a specific deck as good as possible.
I will also have an undo feature in case you make a mistake. This feature is necessary in order to let the AI look ahead. I also want to have a quest mode where you begin with a starter deck and you have to win money to improve your deck. This would make MTG Forge more like a videogame instead of just static 1-on-1 matches. You would also participate in simulated tournaments. Everything I’ve mentioned is possible and I can’t wait to play it myself.
p.s. When you would buy cards in “quest mode” I was thinking that you would only buy booster packs, since using a random collection of cards is more challenging. Maybe the card shop would sell mono-colored booster packs, so you knew that you would get something useful.
p.p.s. I was also thinking about having a player’s rating, but I’m not sure if that would really matter. The rating would be like your DCI rating, it would go up if you won and down if you lost.
As I mentioned last week, all of the Magic cards are going to be encoded using plaintext so many cards can share the same Java code, so I can just write the “destroy creature” code once.
wrath of god.txt
Wrath of God
2 W W
Sorcery
Spell
Text: Destroy all creatures. They can’t be regenerated.
Resolve: destroy all creatures – no regeneration
I might have to update the card format above to tell the AI what phase is best to play the card. Like Wrath of God should be played during the computer’s Main 2 phase, while Giant Growth should be playing After Declaring Blockers.
I also plan to have an updated AI. The AI feature is the unique feature of MTG Forge and while the current AI is basic, I hope to improve its performance. I plan to use some type of algorithm that “looks ahead” and does a few actions, scores the results, and then does the best action. This is basically what you do in your head when you make a decision, you try to see all possible results and you choose the best action.
I plan to have at least a few AI personalities like the aggro or control player. This should at least keep you guessing about what personality the AI is currently using. I am also hoping for “deck specific” AIs that I can write to play a specific deck as good as possible.
I will also have an undo feature in case you make a mistake. This feature is necessary in order to let the AI look ahead. I also want to have a quest mode where you begin with a starter deck and you have to win money to improve your deck. This would make MTG Forge more like a videogame instead of just static 1-on-1 matches. You would also participate in simulated tournaments. Everything I’ve mentioned is possible and I can’t wait to play it myself.
p.s. When you would buy cards in “quest mode” I was thinking that you would only buy booster packs, since using a random collection of cards is more challenging. Maybe the card shop would sell mono-colored booster packs, so you knew that you would get something useful.
p.p.s. I was also thinking about having a player’s rating, but I’m not sure if that would really matter. The rating would be like your DCI rating, it would go up if you won and down if you lost.
Monday, September 15, 2008
What Is A Great Software Project?
MTG Forge is interesting because it gives me a different idea of what software development actually is. I receive feedback from users and I create new versions of MTG Forge with more cards and bug fixes. This is a continual cycle of feedback and program updates that all software projects have. Traditionally the cycle between feedback and software updates has been lengthy, but MTG Forge is updated at least monthly.
MTG Forge is free and is an open source project, meaning that anyone can look at the code and submit updates or use the code for their own project. While the source code is still complicated, like the engine of a car, a person can just update part of the code and doesn’t have to understand the whole thing. Recently a reader updated the user interface to show the small card pictures, thanks Nantuko. (Thankfully MTG Forge is a little bit flexible.)
Like Napster, a great software project does something that people really want. People love music, so they also loved Napster. People love Magic, so they like MTG Forge. MTG Forge is an approximation of a real game. MTG Forge is far from perfect but it still lets people experience the excitement of winning with only 1 life point left.
What is your favorite piece of software? Is it a Mac, a videogame, or just regular e-mail?
MTG Forge is free and is an open source project, meaning that anyone can look at the code and submit updates or use the code for their own project. While the source code is still complicated, like the engine of a car, a person can just update part of the code and doesn’t have to understand the whole thing. Recently a reader updated the user interface to show the small card pictures, thanks Nantuko. (Thankfully MTG Forge is a little bit flexible.)
Like Napster, a great software project does something that people really want. People love music, so they also loved Napster. People love Magic, so they like MTG Forge. MTG Forge is an approximation of a real game. MTG Forge is far from perfect but it still lets people experience the excitement of winning with only 1 life point left.
What is your favorite piece of software? Is it a Mac, a videogame, or just regular e-mail?
Wednesday, September 10, 2008
Programming Cards using Plaintext 2
I love the plaintext format that I previously talked about. Instead of programming card directly into Java, I just used a text file. This format is great for regular spells like Shock but cards like Cone of Flame that have multiple targets take a little bit more ingenuity.
Cone of Flame has 3 targets, the first target gets 1 damage, the second target gets 2 damage and the third target gets 3 damage.
Cone of Flame
3 R R
Sorcery
Spell
Text: Blah, Blah.
Target: creature or player
Resolve: damage creature or player, 1
Target: creature or player
Resolve: damage creature or player, 2
Target: creature or player
Resolve: damage creature or player, 3
The above description of Cone of Flame is a little long and messy, but the text on the printed card is long also. The challenge with Cone of Flame will be to make sure every target is different.
Orcish Artillery is another great card.
Orcish Artillery
1 R R
Creature Orc Warrior
Activated Ability
Text: tap: Orcish Artillery deals 2 damage to target creature or player and 3 damage to you.
Target: creature or player
Resolve: damage creature or player, 2
Resolve: damage you, 3
Orcish Artillery does two things when its ability resolve, so there are two “Resolve” clauses. Many cards in Magic do effect A and B, so being able to combine effects is very powerful. Aggressive Urge is another great card that does two different things when it resolves.
Aggressive Urge
1 G
Instant
Spell
Text: Target creature gets +1/+1 until end of turn. Draw a card.
Target: creature
Resolve: target creature gets X/X until EOT, 1, 1
Resolve: controller – draw a card
As you may or may not have noticed all of these cards are from 10th Edition. One of my goals for MTG Forge version 2 is to program all of the cards in 10th Edition. And don’t count on me programming Mind Bend. I know it is a “fun little card,” but it does some insane stuff. Mind Bend says, “Change the text of target permanent by replacing all instances of one color word with another or one basic land type with another.” Mind Bend is very complicated and it impresses me that Magic Online can implement this card.
Cone of Flame has 3 targets, the first target gets 1 damage, the second target gets 2 damage and the third target gets 3 damage.
Cone of Flame
3 R R
Sorcery
Spell
Text: Blah, Blah.
Target: creature or player
Resolve: damage creature or player, 1
Target: creature or player
Resolve: damage creature or player, 2
Target: creature or player
Resolve: damage creature or player, 3
The above description of Cone of Flame is a little long and messy, but the text on the printed card is long also. The challenge with Cone of Flame will be to make sure every target is different.
Orcish Artillery is another great card.
Orcish Artillery
1 R R
Creature Orc Warrior
Activated Ability
Text: tap: Orcish Artillery deals 2 damage to target creature or player and 3 damage to you.
Target: creature or player
Resolve: damage creature or player, 2
Resolve: damage you, 3
Orcish Artillery does two things when its ability resolve, so there are two “Resolve” clauses. Many cards in Magic do effect A and B, so being able to combine effects is very powerful. Aggressive Urge is another great card that does two different things when it resolves.
Aggressive Urge
1 G
Instant
Spell
Text: Target creature gets +1/+1 until end of turn. Draw a card.
Target: creature
Resolve: target creature gets X/X until EOT, 1, 1
Resolve: controller – draw a card
As you may or may not have noticed all of these cards are from 10th Edition. One of my goals for MTG Forge version 2 is to program all of the cards in 10th Edition. And don’t count on me programming Mind Bend. I know it is a “fun little card,” but it does some insane stuff. Mind Bend says, “Change the text of target permanent by replacing all instances of one color word with another or one basic land type with another.” Mind Bend is very complicated and it impresses me that Magic Online can implement this card.
Tuesday, September 9, 2008
Bug Reports
I've resisted having a master list of bug reports, but it does seem helpful. I've started three threads on theses forums.
Major Bug Report
The major bug report thread is for any errors that cause MTG Forge to crash or are a major implementation error. Examples would include attacking on your first time with a creature with haste, this will cause MTG Forge to crash, and creatures with shadow being able to block non-shadow creatures.
Minor Bug Report
There will be probably many of these types of errors. Examples of minor bugs include trample not working when there are multiple blockers and if the computer has two planeswalkers in play, you can only attack the one that came into play first.
Card Bug Report
This involves anything that MTG Forge does with a specific card that differs from what the card should be. Some good examples are Bottle Gnomes not having his sacrifice ability and Control Magic being an Sorcery instead of an Enchantment. I have put up a list of all known cards errors in this forum.
Hopefully having a list of bugs will making playing MTG Forge better.
Major Bug Report
The major bug report thread is for any errors that cause MTG Forge to crash or are a major implementation error. Examples would include attacking on your first time with a creature with haste, this will cause MTG Forge to crash, and creatures with shadow being able to block non-shadow creatures.
Minor Bug Report
There will be probably many of these types of errors. Examples of minor bugs include trample not working when there are multiple blockers and if the computer has two planeswalkers in play, you can only attack the one that came into play first.
Card Bug Report
This involves anything that MTG Forge does with a specific card that differs from what the card should be. Some good examples are Bottle Gnomes not having his sacrifice ability and Control Magic being an Sorcery instead of an Enchantment. I have put up a list of all known cards errors in this forum.
Hopefully having a list of bugs will making playing MTG Forge better.
Monday, September 8, 2008
Programming Cards using Plaintext
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
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
Subscribe to:
Posts (Atom)