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.

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?

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.

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.

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.

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?

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.

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.

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

Friday, September 5, 2008

New Beta Version

I uploaded a new beta version of MTG Forge. Basically it lets you import and export constructed decks. When you export a deck, it is saved to a file and other people can download that file and import it. I also fixed the error that sometimes you would draw more than one card. (I love static variables.)

I don’t know the best place to upload and download decks. MTG Forge does have a its own forum at http://www.slightlymagic.net/forum/viewforum.php?f=26

I hope I’m not releasing too many versions of MTG Forge.

p.s.
Checkout the new planeswalker from the next set. You can see more spoiled cards at mtgsalvation.com

Wednesday, September 3, 2008

Programming Cards is Hard

The main problem with trying to make a computerized representation of Magic is this: how do you program the cards? How do you code Wrath of God or Giant Growth? As I see it, you have three options.

1. Program each card directly into the programming language.
2. Use text or XML.
3. Combine options one and two. First you use option two and then you generate the source code from the text or XML.

Let me explain each option in more detail. I use option one in MTG Forge. I write out the functionality of each Magic card directly in Java. This option is the most inflexible because you can’t easily change cards.

Option two is the most flexible and I use it in the cards.txt file. I can easily add creatures that only need a few keywords. I’ll show you a sample of cards.txt in case you have never seen it.

Serra Angel
3 W W
Creature Angel
no text
4/4
Flying
Vigilance

Option three is complicated. In essence you are adding another step every time you compile. First the source code is generated and then you compile everything. I include it here strictly as a theoretical option.

Now for the summary. I’m going to get technical so it is ok to skip this part. Option 1 creates cards at compile time while option 2 creates cards at runtime. As a programmer we all know that runtime is generally good. The trick is how do you condense a Magic card into reusable parts that can be written as text?

p.s.
Everywhere I say text I mean plaintext but I didn’t want to confuse people. Does the average person know what plaintext means?

p.p.s. The Firemox project uses XML for all of its cards.

p.p.p.s.
The other main problem when trying to program Magic is how to layout the screen. Even the folks at Wizards are having a tough time with that.

Here is an example of option one, a card hard coded in Java. This is the actual code for Stone Rain (2R, sorcery, destroy target land) taken from MTG Forge. I stripped out the AI routines, but they are pretty good. If you have 2 Forest and 1 Mountain in play, the AI will target the Mountain.
if(cardName.equals("Stone Rain") )
{
SpellAbility spell = new Spell(card)
{
public void resolve()
{
//is target card in play?
if(AllZone.GameAction.isCardInPlay(getTargetCard()))
AllZone.GameAction.destroy(getTargetCard());
}

};//end - SpellAbility

spell.setBeforePayMana(CardFactoryUtil.input_targetType(spell, "Land"));

card.addSpellAbility(spell);
return card;
}//end Stone Rain

Monday, September 1, 2008

New Version, New Gui

The new version of MTG Forge has so many new features I’m not sure where to start at. For starters it has 100 new cards, mostly pump creatures and spells like Looming Shade. I’ve fixed a ton of small things that were wrong with the beta. I also included a brief history of Magic’s creation and early beginnings that I really enjoyed reading.

The user interface has been updated and now shows a miniature picture of the card instead of those ugly text boxes. The card pictures also “tap” so MTG Forge looks like a real game of Magic.

The deck editor has 2 new options. The “New Deck – Generate Constructed Deck” creates a random two color deck. This uses the same code as the “Generate Deck” on the New Game screen.

The second new option is “New Deck – Generate Random Constructed Cardpool”. This is similar to sealed and it gives you 75 random cards from all of the cards available. Unfortunately after you save you deck and try to edit it later, your old cardpool is erased and you are shown all of the cards. My idea for this option was to let players use cards that they don’t usually use, like to play with less powerful cards. Everyone should use Ebony Rhino sometime in their life. (costs 7, 4/5, trample) He may not be the best but at least he is fun.

I added a new keyword that cards.txt recognizes, it looks like this Pump U: 1/1 The mana cost has to be a single character and the numbers to pump the attack and defense have to be single characters also. Here are some other examples, Pump 2: 0/1, Pump 6: 2/2, Pump: B 1/2. I’ve probably all of the creatures that have pump.

I wanted to thank all the users that sent me their improvements. Nantuko updated the user interface. Rob Cashwalker coded 70 or so cards, including some of my favorites like Vampire Bats and Carrion Ants. Another reader cured MTG Forge so it doesn’t slow and have to be restarted. He fixed the Phase object and I am very impressed with his work.

You can download the new version of MTG Forge from here. To save your decks, copy the file "all-decks2"

Hopefully MTG Forge doesn’t have any major bugs but it still has many small ones.