-
Notifications
You must be signed in to change notification settings - Fork 782
Project Overview
MAGE consists of 11 main projects:
-
Mage - contains main logic (entities)
-
Mage.Server - RMI server, maintains tables & games, sends updates to clients, and receives client events
-
Mage.Client - Swing UI, displays game state, and sends player events to the server
-
Mage.Common - elements shared between the client and the server
-
Mage.Sets - contains card sets and cards
-
Mage.Verify - MTGJSON data verification
-
Mage.Tests - testing API
-
Mage.Tournament - tournament-related logic (full list below)
-
Mage.Game - game-related logic (full list below)
-
Mage.Deck - deck-related validators (full list below)
-
Mage.Player - player and AI-related logic (full list below)
There are also currently many server plug-in projects:
- Mage.Deck.{Constructed,Limited} - deck validator for decks
- Mage.Game.{Brawl{Duel,FreeForAll},CanadianHighlanderDuel,Commander{Duel,FreeForAll},FreeForAll, FreeformCommander{Duel,FreeForAll},FreeformUnlimitedCommander,Momir{Duel,Game},Oathbreaker{Duel,FreeForAll},DreadfruitCommanderFreeForAll,TinyLeadersDuel,TwoPlayerDuel}
- Mage.Player.{AI.{Draftbot,MA,MCTS,Minimax},Human}
- Mage.Plugins.Counter
- Mage.Tournament.{BoosterDraft,Constructed,Sealed}
The primary source of requirements and rules is the Comprehensive Rules guide.
Wherever possible, the exact meaning of the guide should be implemented. Class and property names should reflect the entities that the guide refers to. Avoid shortcuts, workarounds, and hacks because these will almost inevitably cause issues or bugs.
Throughout the code there are comments with the following format:
//20091005 - 704.5a/704.5b/704.5c
These refer to sections of the Comprehensive Rules guide. The first number represents the date the rules guide was published, followed by a list of section numbers that apply to the code that follows the comment. There may be sections of code that apply to a specific section of the rules guide, but that aren't commented. This is most likely an oversight; feel free to update the code with the appropriate comment.
One of the primary design goals of MAGE was to decouple the game display logic from the game play logic. This required that MAGE adopt a client/server model. This has the added bonus of allowing clients to be created for a variety of platforms.
One of the principles that was adopted was that of not trusting the client. No privileged data should be sent to the client at any time. This prevents a person from modifying or creating a client that would give them an unfair advantage.
Another design goal was server modularity. The server loads several different types of plug-ins at run-time. These plug-ins control what types of games are available on the server, what types of players are allowed, and what types of decks can be used. Servers can be configured via XML configuration files without having to rebuild. Hopefully, a variety of deck types, game types, and several different levels of AI players will become available over time.
The Mage project contains all common game logic. The primary classes of interest are:
- mage.game.GameImpl - entry point for a game, contains logic common to all game types
- mage.game.GameState - holds the current game state
- mage.players.PlayerImpl - contains logic common to all player types
- mage.cards.CardImpl - contains logic common to all card types
- mage.game.permanent.PermanentImpl - contains logic common to all permanents
- mage.abilities.AbilityImpl - contains logic common to all abilities
- mage.abilities.effects.EffectImpl - contains logic common to all effects
The mage.game.GameState class holds the current game state. Game state consists a list of all players in the game, the current turn, the spell stack, exiled cards, the battlefield, continuous effects, triggered abilities, etc. A property of mage.game.GameImpl called gameStates holds a list of all past game states in order. A particular game state can be bookmarked and the state of the game can be rolled back to that bookmarked state if an illegal action occurs. Bookmarked states are stored in a property of mage.game.GameImpl called savedStates. savedStates is a stack of pointers into the gameStates collection.
Data is passed to the client using views. A view is a simplified version of the game state for the purposes of rendering. All views can be found in the mage.view package.
In order to facilitate server callbacks without requiring an extra RMI connection and port, a callback method on the server is continuously called by the client. The server blocks until there is data to send back to the client, at which point a return value is supplied to the pending client call. The classes that perform this functionality are found in the mage.interfaces.callback package.
The Mage.Client project consists of two main parts: an RMI Client that sends messages/requests to the server and a Swing user interface.
The Mage.Server project manages clients, players, games, tables, and chat rooms.