I’m going to discuss the current software architecture that MTG Forge uses. In order to explain some of the quirks I have to remind you MTG Forge was built one piece at a time and I did very little overall architecture planning. I explain various other details in readme-compile.htm that comes in the MTG Forge zip file.
The main classes are GameAction, Card, CardFactory, Input, Phase, and AllZone. GameAction implements such methods as destroy(Card) and newGame(). The Card class has many actions associated with a physical card such as getName() and getAttack(). Since I knew that creating cards was going to be a complicated process, CardFactory’s goal is just to create new Card objects.
Phase’s most important methods are getPhase() and nextPhase(), which advances to the next phase such as Main1 to Declare Attackers. The Input class handles all of the mouse input and uses the State software pattern. AllZone holds all of the zones in Magic such as the player’s hand or the in play zone and is a global variable, public static, because so many different parts of the program need to access the various zones.
Observers also play an important part in MTG Forge. The user interface, gui, observes all of the zones and each zone observes all of the cards in that zone. The Phase object is also observed and whenever Phase.nextPhase() is called, the user interface gets the correct Input class. The Input class for the Main1 phase would let you play any card, while the Input object representing the “Declare Attackers” phase lets you decide which creatures to attack with.
Many of the card drawing problems that MTG Forge has with Black Vise and cards that generate upkeep effects are due to Phase.nextPhase(). To fix these problems in version 2 I have slightly altered the observer code to work in a more predictable way. I’ll try to explain this in more detail next time. :)