As said before, the rules of the games are described in the file mtg.xml in the src/main/resources/tbs directory. You will often search withing this file to get some already written tests, actions or abilities, so let's see the structure of this file.
The mtg.xml starts with the <tbs> element, which stands for "Turn Based Strategy". Some of the attributes specify the XML schema location, the XML namespace, some others specify the name of the game, the version and the author. We also have information about the picture of the back of the cards file.
Magic Project also implements a database management for informations on cards not related to the rules, like the picture of the card, the flavor text or the artist. All these informations can be grabbed automatically from various sites by just providing a well formed XML proxy file.
The <database-properties> element in the mtg.xml file is used to declare the different informations understood by Magic Project. You will find below an extract of this element from the mtg.xml file.
<database-properties> <property name="card.artist-credit" type="java.lang.String" translate="false" /> <property name="card.flavor-text" type="java.lang.String" translate="false" /> <property name="card.sets" type="java.util.List" translate="true" /> <property name="card.text" type="java.lang.String" translate="false" /> <property name="card.id" type="java.lang.String" translate="false" /> <property name="card.set" type="java.lang.String" translate="true" /> <property name="card.version" type="java.lang.String" translate="false" /> </database-properties>
Magic Project dynamically download the mana symbols needed to display the abilities from the Wizards of the Coast website for copyright considerations. The <mana-symbols> element stands for giving Magic Project all the information needed to properly download these symbols.
The element <license> just give a description of the license linked to the game referenced in the mtg.xml file. You will find an extract of this license description below :
<licence> This program is not published, produced or supported by Wizards Of The Coast(TM), Inc. Magic The Gathering(TM) and Wizards Of The Coast(R) Inc. are registered trademarks owned by Wizards Of The Coast(R) Inc., a subsidiary of Hasbro, Inc. </licence>
A bunch of integer registers (like life) are allocated to each player. the elements <registers-first-player> and <registers-first-player> are decaded to the initialisation of these registers. You will find below an extract of theses elements from the mtg.xml file :
<registers-first-player> <register index="life" value="20" /> <register index="maxi-cards-in-hand" value="7" /> <register index="land-remain-to-cast" value="1" /> <register index="hand-vibility-modifiers" value="0" /> <register index="playedland" value="0" /> <register index="mulligan" value="7" /> </registers-first-player> <registers-second-player> <register index="life" value="20" /> <register index="maxi-cards-in-hand" value="7" /> <register index="hand-vibility-modifiers" value="0" /> <register index="playedland" value="0" /> <register index="mulligan" value="7" /> </registers-second-player>
The next element <phases> declare the differents phases of a turn in the implemented game. It also specifies which type of spells are playable during these phases.
For any card in game with a specific state (like summoning sickness), Magic Project interprets the <state-pictures> element to get the picture and the test associated to each state. If the index and state attributes are provided, Magic Project will make a bitwise compare with the index value of card's registers and the given state value. width and height values determines the size of the picture to display on the card. You can make Magic Project positionning automatically the picture (trailing) by setting the x and the y attributes to -1.
In Magic the Gathering game, some actions are linked to a picture. This is true for the action "tap" for example. The element <action-pictures> declares the different pictures associated to actions.
The element <tooltip-filters> informs Magic Project of the amount of informations to show on cards depending on various tests (for example, it is not necessary to show the colors of a land card since all of them are colorless).
The static modifiers are modifications that apply to cards automatically since they verify the associated test. They are declared with the <static-modifiers> element. We will find in this element, for example, the static modifiers that give any basic land type the ability to produce the associated mana by tapping it, the static modifier for a play-using-morph creature or the ability of cards with flash to be cast at any time.
You will find below an example of the static modifier for creatures with the morph ability :
<static-modifier filter-zone="play">
<modifiers>
<register-indirection index="power" value="2" operation="set" />
<register-indirection index="toughness" value="2" operation="set" />
<idcard-modifier idcard="creature" operation="set" />
<property-modifier operation="remove" property="all" />
<property-modifier operation="add" property="morph" />
<color-modifier operation="clear" />
</modifiers>
<while>
<and>
<has-property property="morph" />
<not>
<is-face-up />
</not>
</and>
</while>
</static-modifier>
In the element <abilities>, we can find all the abilities associated directly to the general management of the game.
The element starts with the system abilities (declared with the <system-ability> elements) that allow players to play the attack phase, inits the game, implements the draw and the discard phase, implements the mulligan, manages and initializes the turn, manages the lethal damage or the manaburn, implements the legend rule, implements the enchant world rules or the limitation while playing lands.
These declarations are followed by the replacement abilities, which stand for abilities that trigger on specific actions and replace theses actions dynamically by other actions. They are declared using the <replacement-ability> element. We will find here the replacement abilities that trigger when a token goes to the graveyard (in fact it is put out of the game), that trigger when a card is played using flashback (when the spell resolves, it goes out of the game) or that trigger when a card is played with buyback (when the spell resolves, it goes to its owner's hand).
The layout of the game is also described in the XML file using the <layout> element. Common panels and zones are declared within.
Magic Project is also capable to apply constraints on actions if they match the <action> child elements. These constraints are dynamically appended using the given operation (usually set to "and") to the test associated with the matched action. Theses constraints are declared using the <action-constraints> element. You will find here constraints concerning the ability to equip a creature with an equipment artifact for example (it's impossible to equip a creature if the equipment is also a creature in addition to its artifact type) :
<constraint operation="and">
<test>
<and>
<not>
<has-idcard idcard="creature" card="this" />
</not>
<has-property property="equipment" card="this" />
</and>
</test>
<actions>
<attach name="equip" />
</actions>
</constraint>
<constraint operation="and">
<test>
<and>
<not>
<has-idcard idcard="creature" card="this" />
</not>
<has-property property="equipment" card="this" />
</and>
</test>
<actions>
<pay-mana />
</actions>
</constraint>
Magic Project can manage additional costs using the <additional-costs> element.
The last part of the XML file is dedicated to the objects, which can be considerated as counters (ice, poison, +1/+1, etc.). These are declared using the <objects> element.
As mentioned before, each card in a game such Magic the Gathering can hold its own specific rules. In Magic Project, we have to write one XML file per card to implement. The content of the file describe the rules of the card in the same language than the large XML file of the card game.
The best way to describe the structure of these files is to look at an example, why not coding the card from the Starter edition, Angel of Light ?
This example will make you know what the most important parts of a XML card rules description XML file are. Below you will find a picture of this card :

Let's start by looking at this card code :
<?xml version="1.0" encoding="ISO-8859-1"?> <card xmlns="http://sourceforge.net/projects/magic-project" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://sourceforge.net/projects/magic-project ../../mpvalidator.xsd" name="Angel of Light"> <rules-author-comment>riclas</rules-author-comment> <init> <registers> <register index="white" value="1"/> <register index="colorless" value="4"/> <register index="power" value="3"/> <register index="toughness" value="3"/> </registers> <colors>white</colors> <idcards>creature</idcards> <properties>vigilance flying angel</properties> </init> <abilities> <ability ref="cast-spell"/> </abilities> </card>
The declaration of the card always starts with the <card> element. It must specify the parameters xmlns (the XML namespace of the current file), xmlns:xsi (the XML namespace for the schema related elements and attributes), xsi:schemaLocation (which specify the location of the XML schema used to validate the structure of the file) and the name (which stands for the card's name in English without replacing or deleting any characters).
<card xmlns="http://sourceforge.net/projects/magic-project" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://sourceforge.net/projects/magic-project ../../mpvalidator.xsd" name="Angel of Light">
This is immediately followed by the <rules-author-comment> element which usually holds information about the author of the XML code of the card (which is generally set to its name of pseudo).
<rules-author-comment>riclas</rules-author-comment>
This element can be followed by a comment reminding the Oracle version of the rules of the card if it has been generated by the Oracle to XML tool.
The next element is the <init> element which holds all the static informations of the card. You will find in this element :
In the example, the card costs 4W and it has a power/toughness of 3/3.
<registers> <register index="white" value="1"/> <register index="colorless" value="4"/> <register index="power" value="3"/> <register index="toughness" value="3"/> </registers>
In the example, the card is a white card.
<colors>white</colors>
The example shows that the card is a creature.
<idcards>creature</idcards>
The example shows that the creature is an Angel with Flying and Vigilance (attacking doesn't it to tap) abilities.
<properties>vigilance flying angel</properties>
The next element is dedicated to abilities. The only ability declared is a reference to the cast-spell ability from the mtg.xml file. This ability allows the owner of this card to pay the casting cost of it in order to play it from its hand.
<abilities> <ability ref="cast-spell"/> </abilities>
Now you are aware of the basic structure of a card, it's a good idea to look at example of cards somewhat more complicated to implement.
This card is somewhat complicated to implement : it has interactions with the events concerning movement of cards and it has to check whether two cards share a permanent type. Below you will find a picture of this card :

Let's start by looking at this card code :
<?xml version="1.0" encoding="ISO-8859-1"?>
<card xmlns="http://sourceforge.net/projects/magic-project" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://sourceforge.net/projects/magic-project ../../mpvalidator.xsd"
name="Cloudstone Curio">
<rules-author-comment>Hoani CROSS</rules-author-comment>
<init>
<registers>
<register index="colorless" value="3"/>
</registers>
<idcards>artifact</idcards>
</init>
<abilities>
<ability ref="cast-spell"/>
<triggered-ability zone="play">
<moved-card>
<source-test>
<not>
<in-zone zone="play"/>
</not>
</source-test>
<destination-test>
<and>
<in-zone zone="play"/>
<controller player="you"/>
<not>
<has-idcard idcard="artifact"/>
</not>
</and>
</destination-test>
</moved-card>
<cost>
<choice cancel="true">
<either>
<target type="card" mode="choose" restriction-zone="play" raise-event="false">
<test>
<and>
<controller player="you"/>
<not>
<is target="context.card"/>
</not>
<sup right="0">
<left>
<and>
<left>
<card-types card="context.card"/>
</left>
<right>
<card-types card="tested"/>
</right>
</and>
</left>
</sup>
</and>
</test>
</target>
</either>
</choice>
</cost>
<effects>
<action ref="return-to-hand"/>
</effects>
</triggered-ability>
</abilities>
</card>
The <init> element let us know that this card is an artifact with a mana cost of 3.
<init> <registers> <register index="colorless" value="3"/> </registers> <idcards>artifact</idcards> </init>
Let's observe the abilities of the card because you will find there the most important parts of the card implementation.
The first ability is for sure used to let the owner of this card cast it.
<ability ref="cast-spell"/>
The main ability of the card is a trigerred ability that triggers only when the card is in play :
<triggered-ability zone="play">
The card abily starts with "Whenever a nonartifact permanent comes into play under your control". Thus the ability will trigger if a card is moved from a zone different from the play zone to the play zone and only if the moved card is an non-artifact card that you control.
<moved-card>
<source-test>
<not>
<in-zone zone="play"/>
</not>
</source-test>
<destination-test>
<and>
<in-zone zone="play"/>
<controller player="you"/>
<not>
<has-idcard idcard="artifact"/>
</not>
</and>
</destination-test>
</moved-card>
This ability has a hidden cost : targetting a valid permanent to eventually return to its owner's hand. That's why the next element is a <cost> element :
<cost>
<choice cancel="true">
<either>
<target type="card" mode="choose" restriction-zone="play" raise-event="false">
<test>
<and>
<controller player="you"/>
<not>
<is target="context.card"/>
</not>
<sup right="0">
<left>
<and>
<left>
<card-types card="context.card"/>
</left>
<right>
<card-types card="tested"/>
</right>
</and>
</left>
</sup>
</and>
</test>
</target>
</either>
</choice>
</cost>
The controller of the card has the choice to target or not the permanent, that's why you'll see the following element with the attribute cancel set to true :
<choice cancel="true">
<either>
<target type="card" mode="choose" restriction-zone="play" raise-event="false">
<test>
<and>
<controller player="you"/>
<not>
<is target="context.card"/>
</not>
<sup right="0">
<left>
<and>
<left>
<card-types card="context.card"/>
</left>
<right>
<card-types card="tested"/>
</right>
</and>
</left>
</sup>
</and>
</test>
</target>
</either>
</choice>
Letting the controller of the card target a permanent is done by the following element (the raise-event attribute is set to false because the ability is not targetted) :
<target type="card" mode="choose" restriction-zone="play" raise-event="false">
<test>
<and>
<controller player="you"/>
<not>
<is target="context.card"/>
</not>
<sup right="0">
<left>
<and>
<left>
<card-types card="context.card"/>
</left>
<right>
<card-types card="tested"/>
</right>
</and>
</left>
</sup>
</and>
</test>
</target>
The test must verify that the targeted permanent ("tested") is controlled by you and that it is not the card that triggered this ability ("context.card") and that it shares a card type with the card that triggered this ability :
<and>
<controller player="you"/>
<not>
<is target="context.card"/>
</not>
<sup right="0">
<left>
<and>
<left>
<card-types card="context.card"/>
</left>
<right>
<card-types card="tested"/>
</right>
</and>
</left>
</sup>
</and>
The effects of the triggered ability are declared with the following element :
<effects> <action ref="return-to-hand"/> </effects>
The "return-to-hand" action reference just return the card in the target list to their respective owner's hand.