Wednesday, December 31, 2008

Wizards is Trying to Kill Me

(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




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.

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."

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?"

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.

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?

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, |-)

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.

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 :+)

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.

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

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.

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?

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.

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!!!