Friday, October 30, 2009

Open Letter to Wizards of the Coast

This is directed toward Wizards of the Coast. I enjoy Magic and I also understand that you own Magic and can do whatever you want to do with it. I also understand that you have been burnt by other computer programs such as Apprentice and Magic Workstation. I also realize that you want to close down websites such as magic-league.com

My program Forge has about 2,000 cards and is a casual player's dream. Some of these cards are on your restricted list and will never be printed again like Tithe, Sapphire Mox, Timetwister and Wheel of Fortune. Other cards are out-of-print powerhouses like Flamtongue Kavu and Kiki-Jiki, Mirror Breaker. Forge has a few cards that are in Standard such as planeswalkers, Lightning Bolt and a variety of creatures with a few "vanilla" abilities.

You are not loosing money when people download this program. I officially want to wave the white flag of peace and would enjoy talking to you on the phone. Anyone from a wizards e-mail address can contact me at (mtgrares yahoo com) and I will give you my phone number.

Wednesday, October 28, 2009

Why Programming AI is Hard - Part 1

One of the most common questions that I get asked is "Why is the AI so bad?" and I understand where people are coming from. When you play a game of Magic in real life you expect a certain level of sophistication from your opponent. A human opponent will attack and block intelligently and play cards that improve his chance of winning. MTG Forge's AI often doesn't attack or block intelligently and sometimes shoots itself in the foot with cards like Ambition's Cost (3B, Sorcery, You draw three cards and you lose 3 life).

The computer has been known to play Ambition's Cost when it only has 2 life, thus losing the game. This situation can be improved by programming the computer NOT to play Ambition's Cost when it has 3 or less life but this doesn't improve the situation very much because currently MTG Forge's AI cannot determine whether the cards in his hand are good or not and thus randomly plays Ambition's Cost like a drunken sailor. (Sing with me, What-would-you-do-with-a-drunken-sailor, What-would-you-do-with-a-drunken-sailor, What-would-you-do-with-a-drunken-sailor, Early-in-the-morning, ha.)

One common AI algorithm that is suitable for two player games likes chess and Magic is min-max, also called minimax or alpha-beta (which is an optimized version of min-max). Min-max is named after the conflicting goals of the two players, you want to maximize your chance of winning and your opponent wants to minimize it. In order to use the min-max algorithm you have to be able to generate possible moves for both players.

OK, take a breath **whoooo**. I know we are just scratching the surface but you've digested some difficult stuff and hopefully you feel smarter without having to listen to boring classical music. (I like classical music, just not the screeching violins. Please leave a comment if you actually do play violin.)

Stay tuned for more info, this is a four (or five) part series and yes I do get more technical.

p.s. This is the first time that a web page has mentioned both drunken sailors and the min-max algorithm, my highschool English teacher would be proud. :--)

Monday, October 26, 2009

MagicWars - Player versus Player

MTG Forge has been a very successful "small Magic program" so I try to inform my readers of other Magic projects. MagicWars is a great new program which lets you play against another person on the Internet and enforces all of the rules. The program was written by nantuko84 and you can post questions to the MagicWars forum. It has a nice shiny user interface with lots of eye-candy (unlike MTG Forge) and currently has 450 cards.

MagicWars has 100 cards from Zendikar as well as all 145 cards from Alara Reborn, which includes cards with cascade. Implementing a whole set, even a small one, is phenomenal. MagicWars has many decks that are currently running around in Standard such as Time Sieve, RW Reveillark, UB Faeries, and Cascade-Swans, which makes MagicWars appealing to players that want to playtest current decks.

I have previously written about why a good user interface is very important and MagicWars doesn't disappoint in this area. The user interface is very nice with pretty little icons that appear next to cards that have abilities such as flying and deathtouch. MagicWars also supports such advance features as transparent windows and changeable backgrounds.

The project is written in Java and is open source, so anyone can contribute. Nantuko84 also writes a blog.

(Warning Will Robinson, MTG Forge users should put on sunglasses before viewing screenshots with this much eye-candy.)

Screenshot 1 - game in progress
Screenshot 2 - deck editor

Download MagicWars

In order to host a game you have to manually type in your IP address. Below is taken from the wiki.

Just unpack archive and run bat file. If you need to host a server, change address in MagicWars.properties file

address=localhost to address=

and in jndi.properties (I will find out later how to set jndi on a fly from java) jnp://localhsot:1099 to jnp://your IP:1099

That's it! Have fun ;)

Wednesday, October 21, 2009

MTG Forge - The Beginning - Part 2

When I was working at Rhino Video Games (which was bought out by GameStop) they had a few 8th Edition Starter decks. I bought a few of them and really enjoyed the game. At that time I thought that trading card games were a gift brought down by the gods. After I explored a few other trading card games I understood that Magic: The Gathering was the first and the best TCG game around. Other TCG games are interesting but nothing has the depth of Magic.

The first TCG videogame that I was exposed to was Yu-Gi-Oh on Gameboy Advance and I absolutely fell in love with it. The game enforced all of the rules and it was phenomenal. At the beginning, MTG Forge was actually an implementation of Yu-Gi-Oh and later I learned of Magic and converted my project. Later I found Magic Online and through my experience I learned the rules of Magic well enough in order to program MTG Forge.

MTG Forge to me is a very personal project and I'm very glad that other people have fallen in love with my program. And although MTG Forge was started as a one man project, currently there are a few people who help out. The forums have really been a great help. I personally coded MTG Forge's first 1,200 cards but other people have contributed all of the other cards past that point.

p.s.
The worst videogame TCG that I played was the awful "Marvel/DC Vs." game for PC, if you clicked on a card you HAD to play it, the program didn't have a cancel button. Playing the videogame was dreadful for a beginner because I would accidentally click on a card like "Giant Growth" and the computer would make me use it. I still admire the VS TCG since it has comic book characters and interesting mechanics, no land cards.

p.s.s.
MTG Forge was also greatly influenced by the Microprose PC game Duels Of The Planeswalkers, which people informally called Shandalar. I love creating decks using all of the cards but drafting, even with those horrible old sets, really sucked me in and I wanted to draft more. One of my biggest pet peeves was annoying draft cards that were either too powerful or too wimpy, so that is why I allow the user to easily add or remove cards from the draft set. (Just remove the card name from one of the files: common.txt, uncommon.txt, or rare.txt)

Monday, October 19, 2009

MTG Forge - The Beginning

When I started programming MTG Forge, I didn't know if the program would ever be good enough for someone else to play and enjoy, there are MANY half-written programming projects on the Internet. MTG Forge was created on a very old computer (700 MHz CPU, 128 MB) with an old version of Java 1.2, now Java is up to 1.6 or something.

Even though I had graduated with a bachelor's degree in computers the longest program that I'd ever written for college was in Cobol. It was a 500 line monstrosity that could have been easily written in 100 lines of Java. The longest Java program that I ever wrote for college was probably around 70 lines. Yes I enjoyed programming but that doesn't mean that I was necessarily good at it.

I had about three "false starts" with MTG Forge. A "false start" is when the program was sufficiently large and was actually doing something but when I added more stuff to it, it would just brake and the program could not be fixed.

This meant that the architecture wasn't correct, so I would use some of the "good stuff" like the Card and SpellAbility classes and then try to write a better foundation the program wouldn't "brake" in the future.

Wednesday, October 14, 2009

Publicity (aka advertising)

In the beginning no one downloaded MTG Forge because no one knew about it, so I began my publicity campaign (which I think of as advertising). The first public thing I did was to begin this blog. Starting out was difficult and I was only getting 2 or 3 views a day which was abysmal. I even thought about closing it down.

After I really understood what people wanted, just Magic and computer programming, I was able to focus and write articles that people enjoyed. I limited myself to only posting twice a week (for my sanity) and keeping the articles relatively short, 150-300 words.

The obvious first place to advertise is on Magic forums. So I posted some stuff on StarCityGames.com and was banned because I "advertised" too much. Now I understood that I need to advertise but in a gentle fashion, "Oh have you heard about this program that lets you play against the computer?" Another good place to advertise is the Wikipedia article on Magic: The Gathering. One day I casually added a paragraph about MTG Forge and I still get about 1/3 of my hits from Wikipedia.

Recently I advertised on cubedrafting.com. MTG Forge isn't really a cube but I posted about it anyways and 256 people read my post. (A cube is a special collection of cards that is specifically designed for drafting.)

Currently my blog gets around 150 views a day while is absolutely phenomenal but I still advertise a little in order to increase the number of people that know (and love) MTG Forge. :^)

p.s.
StarCityGames.com did forgive me and they let me write an article about MTG Forge and recently Abe Sargent also wrote about MTG Forge (thanks for the advertising).

Monday, October 12, 2009

User Interfaces Are 90% of a Program

MTG Forge has progressed from being "merely ok" to "totally fantastic". When I started MTG Forge from scratch I was very nervous and questions like "How good can you write a user interface?" and "Exactly which cards can and cannot be supported?" and "How good with the AI be?" haunted my mind. It is really tough to convince yourself that it will be ok and to start the project anyways.

In the beginning MTG Forge didn't use any card pictures, it only showed colored boxes with the cards name and the mana cost. Then I figured out that I could show the card picture in the panel on the right and later someone figured out how to resize the picture and show it for cards in play.

In the beginning I really wanted to resize the card picture and put them "in play" or on the battlefield but I didn't know how to rotate a card picture 90 degrees. Someone sent me come code which rotated the card picture in ONE LINE. All it takes is one magical line that I couldn't figure out.

At the beginning I received many e-mail complaining about the user interface but after a few changes I stopped hearing about it. From this I learned the first law of programming for the public: "User interfaces are the single most important part of a computer program." The second law is that "Once X is good enough, you will stop hearing complaints about X." MTG Forge's user interface isn't perfect, but it certainly seems "good enough" for most people.

If something is bad you will definitely hear about it. If something is good you might hear about it, lol.

Wednesday, October 7, 2009

How MTG Forge Uses the Mouse for Targeting

I couldn't think of a shorter title. Today I'm going to talk about how MTG Forge uses the state pattern to handle all of the mouse input. I'm afraid this is going to be a little bit technical and boring, so feel free to stop at any time. This is probably most interesting to those few people who actual want to program Magic or another card game from scratch.

I'm going to try to explain my idea but fundamentally it all comes down to using the state pattern. The state pattern lets you change the behavior of an object. Let me show you an example in Java.

interface Mouse
{
void clickCard(Card c, Zone z);
}

class MouseControl
{
private Mouse m;

public void setMouse (Mouse mouse)
{
m = mouse;
}

public void clickCard(Card c, Zone z)
{
m.clickCard(c, z);
}
}
MouseControl really doesn't do much and just passes along the information to the Mouse object. The Mouse object overrides clickCard() and does the really "work." To select a target for Giant Growth you would override Mouse.clickCard() to only allow the player to target a creature. The pseudo-code would look like this.

class GiantGrowth implements Mouse
{
public void clickCard(Card c, Zone z)
{
if(Zone.equals("Battlefield") && c.isCreature())
{
//process and go to the next Input
//if you read below, this is where you would call stop()
}
}//clickCard()
}
In MTG Forge I don't have a Mouse interface, I call it Input, and MouseClick is renamed InputControl. (Really Input is just an Adapter class, an interface with methods that don't do anything.) The Input class also has methods to click on a player, so you can target a player. The user interface only uses InputControl and doesn't care which specific Input object is currently being used.

The Input and InputControl classes can become very complicated especially when you consider the rare situations where Inputs can be "stacked" such as if you have a Keiga, the Tide Star in play and you play another one. Both cards go to the graveyard because they are legendary and the player will get to gain control of two creatures. Currently MTG Forge does not "stack" Inputs and doesn't correctly handle the above example with Keiga, the Tide Star.

Hopefully now you understand the power of the state pattern. In MTG Forge all of the phases are implemented as Inputs. Input objects are used for mulligans at the beginning of the game and to pay for mana costs. When I programmed MTG Forge I took many shortcuts in order to get finished, but this is one area which works beautifully and is one of the cornerstones of MTG Forge's success.

p.s.
Below is the Input class from MTG Forge which has many more methods. While handling mouse inputs is nice, really I want to tie the text of a card such as "Target Creature" or "Target Player" with the mouse so the Input class shows text to the user using showMessage(). Whenever InputControl switches to a another Input, it calls the showMessage() method first, so the user will know what is going on.

The Input class also handles if the user clicks on one of the two buttons. Typically the buttons show the text "OK" and "Cancel" so the Input methods are named selectButtonOK() and selectButtonCancel(). The ok and cancel buttons can display different text such as "yes" or "no" and one or both buttons can be disabled.

Whenever an Input object gets done executing, usually when the user clicked on a creature, the stop() method lets InputControl know that it can go on to the next Input. The next Input is typically an Input that represents a phase such as Main 1 or Declare Attackers. When a spell or ability is on the stack, an Input is also used in that situation.

For a card like Giant Growth the user chooses a target creature then pays for the card. In the targeting code, which is an Input, after the user has click on a creature the Input would call the method stopSetNext(Input in) which stops the current Input and allows the argument to be next. So in the Input used to choose the target creature, after the user has clicked on a creature it would called the method stopSetNext(new PayManaCostInput()) so the user can pay the mana cost.

I know this is a lot of information but if you are serious about programming a game like Magic, you really need to use the state pattern to handle the mouse. More information about MTG Forge Input's can be found on the forum here.

public class Input 
{
//showMessage() is always the first method called
public void showMessage() {AllZone.Display.showMessage("Blank Input");}

public void selectCard(Card c, PlayerZone zone) {}
public void selectPlayer(String player) {}
public void selectButtonOK() {}
public void selectButtonCancel() {}

public void stop()
{
//this lets the InputControl know that it can go on
//to the next Input
//this method works like exit()
}

public void stopPayCost(SpellAbility sa)
{
AllZone.GameAction.playSpellAbility(sa);
}

//exits the "current" Input and sets the next Input
public void stopSetNext(Input in) {stop(); AllZone.InputControl.setInput(in);}
}

Monday, October 5, 2009

My Review of Zendikar

Well the new Zendikar spoiler is out and everyone and their grandma are writing reviews, so I thought I would through my opinion into mix. I don't usually review Magic sets since I think my Magic skills are merely average but if I'm an average player then my opinion is very important, since the biggest group of Magic players are "average".

The visual look of the cards don't seem that exciting and although I do like the few cards that feature "hedrons", floating land masses, 99% of the cards look very average. Usually every Magic set looks different and has its own distinct style, but this set seems very common and unexciting.

The 16 trap cards stand out in my opinion because they feel very new and fresh. The last time I felt this twinge of excitement is when I saw the new planeswalker cards in Lorwyn. The cards seem like a real "trap" because if your opponent fulfills the trap's condition, the card can be played for a cheaper cost. Most of the trap cards are uncommon and shouldn't be too hard to get. The trap cards are very useful and can definitely be added to any casual deck.

Inferno Trap regularly costs 3R but it only costs R if you are damaged by two of more creatures this turn. Some of the trap cards are designed to thwart specific type of decks, Needlebite Trap dislikes decks that gain life and Summoning Trap targets blue control. Needlebite Trap has a printed cost of 5BB but can be cast for just one black mana if you opponent gained life during this turn. Summoning Trap can be cast for 0 if your creature spell is countered.

Personally I have no idea how good Zendikar is to draft. Wizards of the Coast tries very hard to makes set draft friendly, so I presume that Zendikar drafts well. There are no multi-colored cards, so you can go back to drafting normal 2 or 3 color draft decks.

And I forgot to say it but the basic lands are my favorite cards. They look great and I think Wizards should do basic lands like this for ALL of their sets. I'm tired of basic lands looking crappy.

Friday, October 2, 2009

Zendikar Tokens

Here are the 11 Zendikar tokens. Sometimes I forget the Wizards even makes tokens but they look pretty good. I got these tokens from the Magic card picture collection CCHQ forum here.