The really hard part about version 2.0 isn’t really just the cards. It already has such great cards like Iridescent Angel, Dark Ritual, Hypnotic Specter, Loxodon Warhammer, and enchantments like Spirit Link. The hard part is all of the other stuff that supports the cards like the user interface, combat, reading and writing files for the deck builder, and handling mouse input.
When adding cards to version 1.0, I only have to think about the card functionality. Does the card have a target? Does the card do something weird? Does it have an effect that ends at end of turn? I can conveniently forget about all the other code except the 100 or so lines that make up a specific card.
After not looking at MTG Forge’s source code for a week or two it is hard to understand everything that is going on. For truly bad source code see InputControl’s getInput method. It is 120 lines long and is hard to read and understand. It selects the next phase like Declare Attackers or the first Main phase.
Thankfully most of my other code isn’t so bad, but it is still hard to for other people to understand. I tried very hard making the Java code for each card readable. The code below is the Mirrodin card Tanglebloom and it is taken from the current version of MTG Forge. You can compare and contrast this article with my previous essay “Programming Magic Cards is Hard.”
//taken from CardFactory.getCard()
//Tanglebloom is an artifact that costs 1 and has an ability “1, tap: You gain 1 life.”
//1 is the mana cost for the ability
final SpellAbility sp = new Ability_Tap(card, "1")
//the computer will only play the ability during his second main phase
public boolean canPlayAI()
public void resolve()
//the text that is on the card
sp.setDescription("1, tap: You gain 1 life.");
//the text that is shown when on the stack
sp.setStackDescription("Tanglebloom - " +card.getController() +" gains 1 life.");
//the Input class handles all input
//Input_PayManaCost extends Input and lets the user pay the mana cost