The Magic the Gathering game rules file

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 within this file to get some already written tests, actions or abilities, so let's see the structure of this file.

Header

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 name space, 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.

Database management

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>

Mana symbols

Magic Project dynamically download the mana symbols needed to display the abilities from the Wizards of the Coast web site for copyright considerations. The <mana-symbols> element stands for giving Magic Project all the information needed to properly download these symbols.

License

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>

Aliases

Most of the elements of the Magic the Gathering game implementation in Magic Project are referenced by integer values. To make rules readable by a human, we can also use aliases for specific integer values, which are declared within the <aliases> element.

Let's look at the different available aliases.

Global aliases

These aliases are used in many different situations :

Name of the alias
none
all
abortme
abort
destroy
manapool
manacost
threshold

The damage types

All the different types of damage can be tested using this set of available aliases :

Name of the alias
damage-normal
damage-combat
damage-cannot-be-prevented
damage-cannot-be-redirected
damage-cannot-be-regenerated
damage-cannot-be-prevented-redirected
damage-can-prevent

The card positions

The position of a card in a zone can be referenced using these aliases :

Name of the alias
top
bottom

Aliases used in damage prevention

The following aliases are used in damage prevention :

Name of the alias
damage-any
damage-combat-only
damage-combat-can-be-prevented
damage-can-be-prevented
damage-can-be-redirected
damage-can-be-regenerated

Aliases for phase indexes

The following aliases are used for phase indexes :

Name of the alias
precombat-main
eoc.index
postcombat-main

Aliases for game static indexes

The following aliases are used for game static indexes, they are reseted each turn :

Name of the alias
attack-step-index
nb-attacking-group
assignment-configuration
assignment-configuration-int
beginning-of-combat-target-lists
normal-next-player
skipping-turn
turnid
nbattacking

Aliases for registers dedicated to cards or players

The following aliases are used for registers dedicated to cards or players :

Name of the alias
colorless
black
blue
green
red
white
state
damage
combat.assignedto
free0
free1

Aliases for registers dedicated to cards

The following aliases are used for registers dedicated to cards :

Name of the alias
combat.toassign
power
toughness
loyalty
planeswalker-ability
special-abilities

Aliases for registers dedicated to players

The following aliases are used for registers dedicated to players :

Name of the alias
poison
life
mulligan
creatures-moved-in-graveyard-from-play-this-turn
damage-dealt-this-turn
hand-vibility-modifiers
initialized
land-remain-to-cast
maxi-cards-in-hand
playedland

Aliases for card types

The following aliases are used for card types :

Name of the alias
mana-source
permanent
instant
tribal
sorcery

Aliases for permanent types

The following aliases are used for permanent types :

Name of the alias
enchantment
local-enchantment
global-enchantment
land
swamp
island
forest
mountain
plains
creature
artifact
artifact-creature
planeswalker

Aliases for phases

The following aliases are used for phases :

Name of the alias
untap
upkeep
draw
main
declare-attack
declare-attacking
declare-blocking
combat-deals
eoc
eot
cleanup

Aliases for protection types

The following aliases are used for protection types :

Name of the alias
protection-from-idcard
protection-from-enchantments
protection-from-creatures
protection-from-artifacts
protection-from-color
protection-from-black
protection-from-blue
protection-from-green
protection-from-red
protection-from-white
protection-from-property
protection-from-goblins
protection-from-kavu
protection-from-gorgons
protection-from-clerics
protection-from-beasts
protection-from-dragons
protection-from-spirits
protection-from-arcane
protection-from-snow

Aliases for categories of shroud property

The following aliases are used for categories of shroud property :

Name of the alias
untargetable-by-idcard
untargetable-by-creature
untargetable-by-sorcery
untargetable-by-enchant
untargetable-by-artifact
shroud

Aliases for card properties The following aliases are used for card properties :

Name of the alias
double-strike
first-strike
flying
rampage
trample
snow
protection-from-spells
protection-from-abilities
untap-under-condition
basic-land
attacks-if-able
banding
shadow
fear
islandwalk
forestwalk
swampwalk
plainswalk
mountainwalk
reach
vigilance
haste
does-not-untap
wall-can-attack
cannot-attack
cannot-block
artifact-damage-reduced-to-0
spell-damage-reduced-to-0
creature-damage-reduced-to-0
damage-reduced-to-0
sorcery-damage-reduced-to-0
token
defender
indestructible
unblockable
cannot-be-enchanted
enchant-world
desert
lair
locus
equipment
desertwalk
cannot-be-countered
cannot-use-T
sunburst
protection-from-monocolored
protection-from-multicolored
protection-from-all-colors
flash
morph
snow-islandwalk
snow-forestwalk
snow-swampwalk
snow-plainswalk
snow-mountainwalk
nonbasic-landwalk
convoke
may-not-untap
legendary-landwalk
cannot-be-blocked-by-artifacts
cannot-be-blocked-by-walls
phasing
aura
block-as-shadow
block-only-flying
horsemanship
arcane
shrine
legend
changeling
jace
garruk
ajani
liliana
chandra

The creature types

All the declared creatures types available in Magic Project are listed below :

Name of the alias
FIRST_SUB_TYPE
advisor
anemone
angel
anteater
antelope
ape
archer
archon
artificer
assassin
assembly-worker
atog
aurochs
avatar
badger
barbarian
basilisk
bat
bear
beast
beeble
berserker
bird
blinkmoth
boar
bringer
brushwagg
camarid
camel
caribou
carrier
cat
centaur
cephalid
chimera
citizen
cleric
cockatrice
construct
coward
crab
crocodile
cyclops
dauthi
demon
deserter
devil
djinn
dragon
drake
dreadnought
drone
druid
dryad
dwarf
efreet
egg
elder
elemental
elephant
elf
elk
eye
faerie
ferret
fish
flagbearer
fox
frog
fungus
gargoyle
giant
gnome
goat
goblin
golem
gorgon
graveborn
gremlin
griffin
hag
harpy
hellion
hippo
homarid
homunculus
horror
horse
hound
human
hydra
illusion
imp
incarnation
insect
jellyfish
juggernaut
kavu
kirin
kithkin
knight
kobold
kor
kraken
lammasu
leech
leviathan
lhurgoyf
licid
lizard
manticore
masticore
mercenary
merfolk
metathran
minion
minotaur
monger
mongoose
monk
moonfolk
mutant
myr
mystic
nautilus
nephilim
nightmare
nightstalker
ninja
nomad
octopus
ogre
ooze
orb
orc
orgg
ouphe
ox
oyster
pegasus
pentavite
pest
phelddagrif
phoenix
pincher
pirate
plant
prism
rabbit
rat
rebel
reflection
rhino
rigger
rogue
rukh
salamander
samurai
sand
saproling
satyr
scarecrow
scorpion
scout
serf
serpent
shade
shaman
shapeshifter
sheep
skeleton
slith
sliver
slug
snake
soldier
soltari
spawn
specter
spellshaper
sphinx
spider
spike
spirit
splinter
sponge
squid
squirrel
starfish
survivor
tetravite
thalakos
thopter
thrull
treefolk
triskelavite
troll
turtle
unicorn
vampire
vedalken
viashino
volver
wall
warrior
weird
whale
wildebeest
will-o'-the-wisp
witch
wizard
wolf
wolverine
wombat
worm
wraith
wurm
yeti
zombie
zubera
fillette
LAST_SUB_TYPE

Initialization of the players registers

A bunch of integer registers (like life) are allocated to each player. the elements <registers-first-player> and <registers-first-player> are declared to the initialization 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>

Phases declaration

The next element <phases> declare the different phases of a turn in the implemented game. It also specifies which type of spells are playable during these phases.

States pictures

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 positioning automatically the picture (trailing) by setting the x and the y attributes to -1.

Action pictures

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.

Tooltip filters

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).

Static modifiers

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" layer="internal" />
  <register-indirection index="toughness" value="2" operation="set" layer="internal" />
  <idcard-modifier idcard="creature" operation="set" layer="internal" />
  <property-modifier operation="remove" property="all" layer="internal"/>
  <color-modifier operation="clear" />
 </modifiers>
 <while>
  <and>
   <has-property property="morph" />
   <not>
    <is-face-up />
   </not>
  </and>
 </while>
</static-modifier>

Abilities declaration

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, initializes 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).

Game layout

The layout of the game is also described in the XML file using the <layout> element. Common panels and zones are declared within.

References

This is the most important part of the XML file for card rules writers. Identified by the element <references>, it contains a set of tests, actions, abilities or attachments that can be referenced from your card XML code. Warning : Declaration order is important, you cannot refers to an ability or a test that has not previously been declared.

Tests references

These are described within the nested <tests> element. We can find the following references :

Reference nameDescription
has-imprinted-cardReturns true if there is an imprinted card on the current card.
hellbentReturns true if there is no cards in your hand.
once-each-turnHas this "once each turn" ability not been played ?
tested-just-summonedHas the tested card just been summoned ?
just-summonedHas the current card just been summoned ?
before-attackers-declarationIs the current phase your attackers declaration phase ?
during-your-untapIs the current phase your untap phase ?
during-modifier-untapIs the current phase the untap phase of controller of modifier creator ?
during-your-upkeepIs the current phase your upkeep phase ?
during-oppponent-upkeepIs the current phase is an oppponent's upkeep phase ?
during-your-drawIs the current phase your draw phase ?
during-your-precombat-mainIs the current phase your pre-combat main phase ?
during-your-mainIs the current phase one of your main phases ?
during-your-combatIs the current phase your combat phase ?
during-your-eotIs the current phase your end of turn phase ?
thresholdDoes the tested card controller graveyard contain at least an amount of cards greater or equal to the number identified by the threshold register of that card ?
tested-is-attackingIs the tested card attacking ?
first-target-is-attackingIs the first card in the target list attacking ?
is-attackingIs the current card attacking ?
saved-is-attackingIs the saved card attacking ?
tested-is-blockingIs the tested card blocking ?
first-target-is-blockingIs the first card in the target list blocking ?
is-blockingIs the current card blocking ?
tested-is-blockedHas the tested card been blocked ?
is-blockedHas the current card been blocked ?
is-untapped-under-conditionHas the tested card been untapped manually ?
tested-has-combat-damage-to-assignDoes the tested card have combat damage to assign ?
tested-is-unblockedHas the tested card not been blocked ?
is-unblockedHas the current card not been blocked ?
tested-in-combatIs the tested card in combat ?
in-combatIs the current card in combat ?
cantapCan the current card tap ?
can-use-TCan the current card use the {T} ability (in addition to the previous test, this one tests whether the current card is not affected by a limitation that doesn't allow it to tap) ?
has-counterIs there a private card counter ? This counter is not visible for players. Also see init-counter ability.
is-multicoloredIs the tested card a multicolored card (it has at least two colors) ?
this-is-multicoloredIs the current card a multicolored card (it has at least two colors) ?
is-monocoloredIs the tested card a mono-colored card ?
this-is-monocoloredIs the current card a mono-colored card ?
is-coloredIs the tested card a colored card (it has at least one color) ?
this-is-coloredIs the current card a colored card (it has at least one color) ?
is-targetIs the tested card target ?
is-targetable-landIs the tested card a target land ?
is-targetable-spellIs the tested card a target spell ?
valid-damage-sourceThis test must return true to design a valid damage source.
is-targetable-damage-sourceThis test must return true to design a target damage source.
is-targetable-abilityTo have an ability being targeted properly, this test must return true.
is-targetable-activated-abilityTo have an activated ability being targeted properly, this test must return true.
is-targetable-triggered-abilityTo have a triggered ability being targeted properly, this test must return true.
is-targetable-activated-triggered-abilityTo have an activated or triggered ability being targeted properly, this test must return true.
is-targetable-creatureTo have a creature being targeted properly, this test must return true.
is-targetable-artifactTo have an artifact being targeted properly, this test must return true.
is-targetable-tappableTo have an tappable permanent (creature, artifact or land) being targetted properly, this test must return true.
is-basic-landIs the tested card a basic land ?
is-nonbasic-landIs the tested card a non-basic land ?
only-for-artifact-spellTest used to apply restrictions on the use of mana that can only be used to pay artifact spells mana cost (Mishra's Workshop for example).
only-for-colored-spellTest used to apply restrictions on the use of mana that can only be used to pay multicolored spells mana cost.
only-for-cumulative-upkeepTest used to apply restrictions on the use of mana that can only be used to pay cumulative upkeep mana costs. (Mishra's Workshop for example).
valid-blockTo be chosen to block the current attacking, the tested card must verify that this test returns true.
is-targetable-playerTo have a player being targeted properly, this test must return true.
is-targetable-dealtableTo have a dealtable (creature of player) being targeted properly, this test must return true.
is-targetable-artifact-creatureTo have an artifact creature being targeted properly, this test must return true.
is-targetable-enchantmentTo have an enchantment being targeted properly, this test must return true.
is-targetable-local-enchantmentTo have an aura being targeted properly, this test must return true.
can-attackCan the tested card attack ?
valid-enchantTest used for the attachment of an aura to the enchanted permanent.
valid-enchant-landTest used for the attachment of an aura to the enchanted land.
valid-enchant-creatureTest used for the attachment of an aura to the enchanted creature.
valid-enchant-enchantmentTest used for the attachment of an aura to the enchanted artifact creature.
valid-enchant-artifact-creatureTest used for the attachment of an aura to the enchanted artifact creature.
valid-enchant-artifactTest used for the attachment of an aura to the enchanted artefact.
valid-equip-creatureTest used for the attachment of an equipment to the equipped creature.
valid-to-enchantInternal test used to select a valid card to enchant (do not use this directly).
valid-creature-to-enchantTest used to select a valid creature to enchant.
valid-enchantment-to-enchantTest used to select a valid enchantment to enchant.
valid-land-to-enchantTest used to select a valid land to enchant.
valid-permanent-to-enchantTest used to select a valid permanent to enchant.
valid-artifact-creature-to-enchantTest used to select a valid artifact creature to enchant.
valid-artifact-to-enchantTest used to select a valid artifact to enchant.
valid-to-equipInternal test used check the equip stills valid (do not use this directly).
valid-creature-to-equipInternal test used check the equip stills valid for the equiped creature.
valid-equipInternal test used to select a valid card to equip (do not use this directly).
valid-equip-creatureTest used to select a valid creature to equip.
died-cardThis test is used by update-toughness and update-damage abilities.
priv_blocking-tested-counterTest only used by combat-damage assignments ability to check the creatures blocking the super.tested card.
priv_blocked-by-tested-counterTest only used by combat-damage assignments ability to check the creatures blocked by the super.tested card.
priv_currentplayer-has-to-discardTest used during the discard phase to verify if the current player has to discard cards from his hand.
flashback-usedHas the flashback been used ?
buyback-usedHas the buyback been paid for this spell ?
kicker-usedHas the kicker been paid for this spell ?
kicker2-usedHas the second kicker been paid for this spell ?
entwine-usedHas the entwine been paid for this spell ?
has-no-more-fadingReturns true if the current card has no more fading counter on it.
has-no-more-timeReturns true if the current card has no more time counter on it.
can-regenerateCan the creature generate ? This test cannot be used in event test.
is-valid-blocking-creature-for-targeted-attacking?
has-at-least-one-valid-blocking-creature?
valid-creature-equipTest used to select a proper target for an equipment.

Actions references

These are described within the nested <actions> element. Some reference are MACRO([value],[test]), which means that you can dynamically append a test to the referenced action or pass a value to the referenced action (if value is specified in the parenthesis just after MACRO). We can find the following references :

Reference nameDescription
affinityMACRO(counter-test) : Affinity for counter-test. Example : Dross Golem
phase-outPhase out the cards of target list.
counterCounters the spell(s) in the target list.
use-once-each-turnMarks the ability that referenced this action as already been used this turn.
target-permanent-enchantMACRO(test) : allows you to target a valid permanent to enchant.
all-creaturesMACRO(test) : targets all the creatures in play.
creatures-you-controlMACRO(test) : targets all creatures in play that you control.
all-landsMACRO(test) : targets all the lands in play.
all-artifactsMACRO(test) : targets all the artifacts in play.
all-enchantmentsMACRO(test) : targets all the enchantments in play.
target-for-attachmentMACRO(test) : allows you to target a valid permanent to have the current card to be attached to this target (works for equipments and auras).
target-creature-enchantMACRO(test) : allows you to target a valid creature to enchant.
target-land-enchantMACRO(test) : allows you to target a valid land to enchant.
target-artifact-enchantMACRO(test) : allows you to target a valid artifact to enchant.
target-damage-sourceMACRO(test) : allows you to target a valid damage source.
target-local-enchantmentMACRO(test) : allows you to target a valid aura in play.
target-enchantmentMACRO(test) : allows you to target a valid enchantment in play.
target-landMACRO(test) : allows you to target a valid land in play.
target-creatureMACRO(test) : allows you to target a valid creature in play.
target-artifactMACRO(test) : allows you to target a valid artifact in play.
target-artifact-creatureMACRO(test) : allows you to target a valid artifact creature in play.
target-permanentMACRO(test) : allows you to target a valid permanent.
target-noncreature-artifactMACRO(test) : allows you to target a valid non-creature artifact in play.
target-nonartifact-creatureMACRO(test) : allows you to target a valid non-artifact creature in play.
target-tappableMACRO(test) : allows you to target a valid permanent that can be tapped.
target-playerMACRO(test) : allows you to target a valid player.
choose-playerMACRO(test) : allows you to choose a player (no target action).
target-opponentMACRO(test) : allows you to target a valid opponent.
target-dealtableMACRO(test) : allows you to target a valid dealtable (which is either a player or a permanent that can be dealt damage).
target-cardMACRO(test) : allows you to target a valid card in play (equivalent to target-permanent).
target-spellMACRO(test) : allows you to target a valid spell in the stack.
target-abilityMACRO(test) : allows you to target a valid ability in the stack.
target-activated-abilityMACRO(test) : allows you to target a valid activated ability in the stack.
target-triggered-abilityMACRO(test) : allows you to target a valid triggered ability in the stack.
target-activated-triggered-abilityMACRO(test) : allows you to target a valid activated or triggered ability in the stack.
search-lib-up-to-playerMACRO(value,test) : allows the player in the first position of the target list to search within his library up to value cards (he can cancel the operation).
search-lib-up-toMACRO(value,test) : allows you to search within your library up to value cards (you can cancel the operation).
search-libMACRO(test) : allows you to search within your library for one card (you cannot cancel the operation).
search-lib-playerMACRO(value,test) : allows the player in the first position of the target list to search within his library up to value cards (he cannot cancel the operation).
search-lib-revealMACRO(value,test) : allows you to search within your library up to value cards and reveal them (you cannot cancel the operation).
revealReveals the cards in the target list to everyone and wait until the opponent decide to stop looking at your revealed cards.
lookAllows you to look at the cards in the target list and wait until you decide to stop looking at these cards.
look-at-the-topAllows you to look at the top card of your library. The 'face-down' action should be call juste after.
finish-spellMoves the card referencing this action to its owner's graveyard.
shuffle-in-libMoves the cards in the target list to their owner libraries and shuffle the library of owner of the last card.
shuffle-in-libsMoves the cards in the target list to their owner libraries and shuffle all libraries.
prepare-extra-turnPrepares the game to let you play another turn after this one.
TTap the card referencing this action.
remove-from-combatRemoves the cards in the target list from combat.
regenerateAdds to the card referencing this action a replacement ability that triggers when this card is dealt lethal damage and replaces this action by removing this card from combat (if apply) and removing all damages that apply to it. This ability lasts until the end of the turn.
regenerate-targetApply the regenerate action to the last card in the target list.
regenerate-attached-toApply the regenerate action to the card attached to the card referencing this action.
remove-all-damageRemoves all damages that apply to the cards in the target list.
restore-library-visibilityRestores the visibility for you of the libraries of the players in the target list (TODO).
restore-hand-visibilityRestores the visibility of the hands of the players in the target list for the opponent (checks whether the opponent has a special ability to permanently have the right to see your hand).
add-1-1-until-eotCards in the target list get -1/-1 until the end of the turn.
add-2-2-until-eotCards in the target list get -2/-2 until the end of the turn.
add-3-3-until-eotCards in the target list get -3/-3 until the end of the turn.
add-4-4-until-eotCards in the target list get -4/-4 until the end of the turn.
add+1+1-until-eotCards in the target list get +1/+1 until the end of the turn.
add+7+7-until-eotCards in the target list get +7/+7 until the end of the turn.
add+6+6-until-eotCards in the target list get +6/+6 until the end of the turn.
add+1-1-until-eotCards in the target list get +1/-1 until the end of the turn.
add+2-2-until-eotCards in the target list get +2/-2 until the end of the turn.
add+3-3-until-eotCards in the target list get +3/-3 until the end of the turn.
add-2+2-until-eotCards in the target list get -2/+2 until the end of the turn.
add-1+1-until-eotCards in the target list get +1/-1 until the end of the turn.
add+2-1-until-eotCards in the target list get +2/-1 until the end of the turn.
add-1-0-until-eotCards in the target list get -1/-0 until the end of the turn.
add+1+2-until-eotCards in the target list get +1/+2 until the end of the turn.
add+2+2-until-eotCards in the target list get +2/+2 until the end of the turn.
add+3+3-until-eotCards in the target list get +3/+3 until the end of the turn.
add+4+4-until-eotCards in the target list get +4/+4 until the end of the turn.
add+5+5-until-eotCards in the target list get +5/+5 until the end of the turn.
add+2+1-until-eotCards in the target list get +2/+1 until the end of the turn.
add+3+0-until-eotCards in the target list get +3/+0 until the end of the turn.
add+4+0-until-eotCards in the target list get +4/+0 until the end of the turn.
add+2+0-until-eotCards in the target list get +2/+0 until the end of the turn.
add+2+0-until-eocCards in the target list get +2/+0 until the end of the combat.
add+1+0-until-eotCards in the target list get +1/+0 until the end of the turn.
add+0+1-until-eotCards in the target list get +0/+1 until the end of the turn.
add+0+2-until-eotCards in the target list get +0/+2 until the end of the turn.
add+0+3-until-eotCards in the target list get +0/+3 until the end of the turn.
add+0+5-until-eotCards in the target list get +0/+5 until the end of the turn.
add-2-0-until-eotCards in the target list get -2/+0 until the end of the turn. Example : Ivory Charm
gain-1-1-until-eotThe card referencing this action gets -1/-1 until the end of the turn.
gain+1+1-until-eotThe card referencing this action gets +1/+1 until the end of the turn.
gain+1+0-until-eotThe card referencing this action gets +1/+0 until the end of the turn.
gain+2+0-until-eotThe card referencing this action gets +2/+0 until the end of the turn.
gain+0+1-until-eotThe card referencing this action gets +0/+1 until the end of the turn.
gain+0+2-until-eotThe card referencing this action gets +0/+2 until the end of the turn.
gain+2+2-until-eotThe card referencing this action gets +2/+2 until the end of the turn.
gain+3+3-until-eotThe card referencing this action gets +3/+3 until the end of the turn.
gain+1+2-until-eotThe card referencing this action gets +1/+2 until the end of the turn.
gain+1-1-until-eotThe card referencing this action gets +1/-1 until the end of the turn.
unblockable-until-eotCards in the target list become unblockable until the end of the turn.
flying-until-eotCards in the target list gain flying until the end of the turn. Example : Raka Disciple
changeling-until-eotCards in the target list gain flying until the end of the turn. Example : Blades of Velis Vel
fear-until-eotCards in the target list gain fear until the end of the turn (they are unblockable except by black or artifact creatures).
shadow-until-eotCards in the target list gain shadow until the end of the turn (they can bloc or be blocked only by creatures with shadow).
wall-can-attack-until-eotCards in the target list are allowed to attack this turn (if possible) even if they have defender.
haste-until-eotCards in the target list gain haste until the end of the turn (they can attack the turn they came into play).
trample-until-eotCards in the target list gain trample until the end of the turn.
banding-until-eotCards in the target list gain banding until the end of the turn.
first-strike-until-eotCards in the target list gain first strike until the end of the turn.
double-strike-until-eotCards in the target list gain double strike until the end of the turn.
vigilance-until-eotCards in the target list gain vigilance until the end of the turn (attacking does not cause them to tap).
shroud-until-eotCards in the target list can't be the target of spells of abilities until the end of the turn.
reach-until-eotCards in the target list can block as if they had flying until the end of the turn.
attacks-if-able-until-eotCards in the target list attack if able until the end of the turn.
cannot-block-until-eotCards in the target list cannot block until the end of the turn.
cannot-attack-until-eotCards in the target list cannot attack until the end of the turn.
forestwalk-until-eotCards in the target list gain forestwalk until the end of the turn.
islandwalk-until-eotCards in the target list gain islandwalk until the end of the turn.
protection-from-red-until-eotCards in the target list gain protection from red until the end of the turn.
protection-from-black-until-eotCards in the target list gain protection from black until the end of the turn.
does-not-untap-next-untapCards in the target list don't untap during their controller's next untap step.
return-to-handReturns the cards in the target list to their owner's hand.
move-library-topMoves the cards in the target list to the top of their owner's library.
move-library-bottomMoves the cards in the target list to the bottom of their owner's library.
remove-from-gameRemoves the cards in the target list from the game (they are moved to the side zone, [TODO] creating a dedicated zone for such cards should be considered).
put-in-graveyardPuts the cards in the target list in their owner's graveyard.
mill-a-card
Déplace la carte du dessus de la bibliothèque du dernier joueur ciblé dans son cimetière.
Puts the top card of target player's library to his graveyard.
draw-a-cardMakes the players in the target list draw a card. Example : Bandage
remove-a-card-from-libraryMakes the players in the target list removes the top card of their library from the game. The target list is cleared after this operation.
remove-a-card-from-graveyardAllows the players in the target list to choose a card from their graveyard to be removed from the game. The target list is cleared after this operation.
draw-a-card-next-upkeepMakes you draw a card during the next turn upkeep. Example : Heal
opponent-draw-a-card-next-upkeepMakes the opponent draw a card during the next turn upkeep.
pay-lifeMACRO(value) : makes the controller of the card referencing this action pay value points of life. Beware, a test must be used to check whether the player have enough life to play this action (check mtg.xml for more information).
gain-lifeMACRO(value) : makes the controller of the card referencing this action gain value points of life.
gain-life-targetMACRO(value) : makes the targets of the card referencing this action gain value points of life.
lose-lifeMACRO(value) : makes the controller of the card referencing this action loose value points of life.
lose-life-targetMACRO(value) : makes the players in the target list loose value points of life.
discardMACRO(value,test) : makes you choose value cards from your hand and discard them.
discard-randomMACRO(value,test) : makes you discard value cards at random from your hand.
opponent-discardsMACRO(value,test) : makes the opponent choose value cards from his hand and discard them.
discard-a-playerMACRO(value,test) : makes you choose value cards from the hand of the players in the target list and discard them.
player-discardMACRO(value,test) : makes the player in the first position in the target list choose value cards from his hand and discard them.
player-discard-randomMACRO(value,test) : makes the player in the first position in the target list discard value cards from his hand at random.
player-discard-up-toMACRO(value,test) : makes the player in the first position in the target list choose up to value cards from his hand and discard them.
discard-cards_nonameMoves the cards in the target list to their owner's graveyard (this action is not named).
discard-cardsMoves the cards in the target list to their owner's graveyard.
destroyDestroys the cards in the target-list.
buryDestroys the cards in the target-list. The destroyed card cannot be regenerated.
destroy-target-eotDestroys the first card of the target-list at the end of turn.
destroy-target-eocDestroys the first card of the target-list at the end of combat.
remove-from-game-target-eotRemoves from game the first card of the target-list at the end of turn.
return-to-play-target-eotReturns to play the first card of the target-list at the end of turn.
sacrifice-thisSacrifices this card (Move the card into the graveyard of his/her owner).
sacrifice-a-creatureMACRO(test) : Sacrifices value chosen creatures.
sacrifice-any-creatureMACRO(value,test) : Sacrifice sany chosen creatures.
sacrifice-a-permanentMACRO(value,test) : Sacrifices value chosen permanents.
opponent-sacrifice-a-permanentMACRO(value,test) : Makes the opponent sacrifice value chosen permanents.
opponent-sacrifice-a-creatureMACRO(value,test) : Makes the opponent sacrifices value chosen creatures.
sacrifice-an-artifactMACRO(value,test) : Sacrifices value chosen artifacts.
sacrifice-an-enchantmentMACRO(value,test) : Sacrifices value chosen enchantments.
opponent-sacrifice-an-enchantmentMACRO(value,test) : Makes the opponent sacrifice value chosen enchantments.
opponent-sacrifice-an-artifactMACRO(value,test) : Makes the opponent sacrifice value chosen artifacts.
sacrifice-a-landMACRO(value,test) : Sacrifices value chosen lands.
opponent-sacrifice-a-landMACRO(value,test) : Makes the opponent sacrifices value chosen lands.
sacrificeSacrifices the cards of the target-list.
redirect-all-to-thisRedirects the all damage from first target to this card until end of turn.
redirect-1-from-thisRedirects the next 1 damage from this to the first target until end of turn. Example : Nomads en-Kor
redirect-2-from-thisRedirects the next 2 damage from this to the first target until end of turn.
redirect-3-from-thisRedirects the next 3 damage from this to the first target until end of turn.
redirect-all-from-thisRedirects all damage from this to the first target until end of turn.
redirect-allRedirects the all damage from first target to the second target until end of turn.
redirect-1Redirects the next 1 damage from first target to the second target until end of turn.
redirect-2Redirects the next 2 damage from first target to the second target until end of turn.
redirect-3Redirects the next 3 damage from first target to the second target until end of turn.
redirect-1-to-thisRedirects the next 1 damage from first target to this card until end of turn. Example : Daughter of Autumn
redirect-2-to-thisRedirects the next 2 damage from first target to this card until end of turn.
redirect-3-to-thisRedirects the next 3 damage from first target to this card until end of turn.
prevent-1-on-thisPrevents the next 1 damage dealt to this card until end of turn. Example : Ordruun Commando
prevent-all-on-thisPrevents all damages dealt to this card until end of turn. Example : Deftblade Elite
prevent-all-from-thisPrevents all damages dealt by this card until end of turn. Example : Deftblade Elite
prevent-1Prevents the next 1 damage dealt to the last target card until end of turn. Example : Heal, Samite Healer
prevent-2Prevents the next 2 damage dealt to the last target card until end of turn. Example : Elvish Healer
prevent-3Prevents the next 3 damage dealt to the last target card until end of turn. Example : Healing Salve
prevent-4Prevents the next 4 damage dealt to the last target card until end of turn. Example : Hallowed Healer
prevent-5Prevents the next 5 damage dealt to the last target card until end of turn. Example : Abuna's Chant
prevent-6Prevents the next 6 damage dealt to the last target card until end of turn. Example : Recuperate
prevent-xPrevents the next X damage dealt to the last target card until end of turn. Example : Alabaster Potion
prevent-allPrevents all damage dealt to the last target card until end of turn. Example : Circle of Protection: Black
prevent-all-combat-on-targetPrevents all combat damage dealt to the last target card until end of turn.
prevent-all-fromPrevents all damages dealt by the last target card until end of turn.
prevent-all-combat-damagePrevents all combat damage this turn. Example : Moment's Peace
deals-no-combat-damagePrevents all the combat damages that would be assigned by the first target this turn.
put-in-playPut in play this card under owner's control.
move-to-playMove target cards to play under owner's control.
choose-damage-sourceChooses a card that could damage something. Example : Circle of Protection: Black
buybackActive the buyback option for the current spell. Example : Constant Mists
flashbackActive the flashback option for the current spell. Example : Moment's Peace
kickerActive the first kicker option for the current spell. Example : Duskwalker
kicker2Active the first kicker option for the current spell. Example : Cetavolver
entwineActive the first entwine option for the current spell. Example : Dream's Grip
planeswalker-ability-usedchange the planeswalker index to used. Example : Jace Beleren
skip-next-turnMakes the owner of the current card skip his next turn.
target-equipable-creatureTargets a creature could be equiped by the current card. Example : Grifter's Blade
equipEquips the last target with the current card (that should be an equipment).
radianceRadiance option implementation. Example : Rally the Righteous
morphMorph ability implementation : face up the card. Example : Aphetto Alchemist
imprint-cardThis imprints the last target of target list into the card owning this action. The imprinted card is stored as 'private-object' component in the card.
load-imprinted-cardLoad the imprinted card into the target list. If there is no imprinted card, an error is thrown. Use the 'has-imprinted-card' test.
pay-xPay colorless X manas. Example : Fireball
pay-xxPay colorless XX manas. Example : Decree of Justice
blocks-this-if-ableForces the last target to block the current card during the next combat if able.
amplifyAmplify MACRO([value]) action. Example : Daru Stinger
clash501.10. Clash 501.10a To clash, a player reveals the top card of his or her library. That player may then put that card on the bottom of his or her library. 501.10b "Clash with an opponent" means "Choose an opponent. You and that opponent each clash." 501.10c A player wins a clash if that player revealed a card with a higher converted mana cost than all other cards revealed in that clash. the Macro actions are the actions that occur if you win the clash. MACRO([actions]) Example : Adder-Staff Boggart

Abilities references

These are described within the nested <abilities> element. Using these references is the best way to accelerate card developement and maintenance since repetitive code are place in this place. So if you find some abilities appearing often in cards, this is the right place to add a reference to share with the community of card rules developers. The project team will make infinite effort to add this ability detection in our card generator for the Oracle. Some abilities work as macro by accepting one or two actions lists. We can find the following references :

Reference nameDescription
suspendTrigerred ability relative to the management of the suspend ability. It is used by the cast-suspend ability. The ability triggers at the beginning of your upkeep and remove one time mark from the card that reference this ability then if there is no more time mark on this card, it is put into play. TODO : the card must be considered to have been played during the turn when the card has been put into play and not during the turn when the suspend ability has been cast, this information is relevant for all cards that use the storm ability. An example of the use of this ability is available throught the Lotus Bloom card.
cast-suspendMACRO(actions, actions) : this activated ability must be referenced by any card using the suspend ability. It allows the owner of the card to cast the spell associated through the suspension mode and dynamically add to the removed from the game card the suspend trigerred ability. The first <actions> macro is used to specify the cost of the suspend ability. The second <actions> is called after removing the card from the game and allows you to implement the addition of time marks to the card removed from the game. An example of the use of this ability is available through the Lotus Bloom card.
provokeProvoke trigger implementation.
graftGraft trigger implementation. Moves a +1/+1 counter from this to a card coming into play.
modularModular trigger implementation. Moves counters from this card to target artifact creature
soulshift1502.39. Soulshift 502.39a Soulshift is a triggered ability. "Soulshift N" means "When this permanent is put into a graveyard from play, you may return target Spirit card with converted mana cost N or less from your graveyard to your hand." 502.39b If a permanent has multiple instances of soulshift, each triggers separately.
madnessMadness implementation. "If you discard this card, you may play it for its madness cost instead of putting it into your graveyard." The way it is implemented it may be bugged with "samurai of the pale curtain" or "leyline of the void" in play. It may have problems with "Teferi" when it is created and with "Storm" ability counter. It needs an action for the madness cost on parameter and another action for the spell effect.
cyclingMoves the card referencing this action to its owner's graveyard, and allows the card's owner to draw a card from its library. This ability is a macro, an actions list must be provided as parameter. Example : Sunfire Balm
evokeEvoke is an alternative cost. Playing a creature by paying its evoke cost rather than its mana cost causes that creature to be sacrificed when it comes into play. Example : AEthersnipe
evoke-flashEvoke is an alternative cost. Playing a creature by paying its evoke cost rather than its mana cost causes that creature to be sacrificed when it comes into play. Example : AEthersnipe
forecastForecast {macro actions} : {macro actions}.
tap-add-B{T} : add one black mana to your mana pool.
tap-add-U{T} : add one blue mana to your mana pool.
tap-add-G{T} : add one green mana to your mana pool.
tap-add-R{T} : add one red mana to your mana pool.
tap-add-W{T} : add one white mana to your mana pool.
tap-add-C{T} : add one colorless mana to your mana pool.
cast-enchant{T} : to put a local enchantment into play, attached to a valid permanent.
cast-enchant-flash{T} : to put a local enchantment with flash into play, attached to a valid permanent.
cast-spell{T} : to put in play a permanent, paying it's manacost.
morphUse morph ability.
cast-morph{T} : to put in play a morph card, paying 3.
cast-flash{T} : to put in play a permanent using flash ability, paying it's manacost.
cast-land{T} : to play a land.
echoMACRO([action]) The echo ability. This reference accept as macro an action to substitute the default pay-mana action.
prevent-all-on-thisPrevents all damages dealt to this card.
prevent-all-on-attachedtoPrevents all damages dealt to attached card.
deals-no-combat-damageThe saved card deals no combat damage.
bloodthirst1Bloodthirst 1 implementation. Example : Bloodscale Prowler
bloodthirst2Bloodthirst 2 implementation. Example : Scab-Clan Mauler
bloodthirst3Bloodthirst 3 implementation. Example : Ghor-Clan Savage
dredge1Dredge 1 implementation. Example : Grave-Shell Scarab
dredge2Dredge 2 implementation.
dredge3Dredge 3 implementation. Example : Darkblast
dredge4Dredge 5 implementation.
dredge5Dredge 5 implementation.
dredge6Dredge 6 implementation.
transmuteTransmute implementation. Example : Perplex
rampage1Rampage 1 implementation. Example : Balduvian War-Makers
rampage2Rampage 2 implementation. Example : Balduvian War-Makers
rampage3Rampage 3 implementation. Example : Craw Giant
rampage4Rampage 4 implementation. Example : Teeka's Dragon
eot-sacrificeAt end of turn, sacrifice this card. Example : Dragon Whelp
regenerateRegenerate the saved card if possible. This ability should appear directly within the card abilities but used with create-ability action.
shapeshifter-abilityWhenever a creature comes into play, THIS becomes a copy of that creature and gains this ability. Example : Unstable Shapeshifter
lifelinkwhenever THIS (context creature) deals damage, you gain that much life. Example: Kjeldoran Gargoyle, Exalted Angel
deathtouchwhenever THIS (context creature) deals damage to a creature, destroy that creature. Example: Moonglove Winnower
cast-spell-kicker{T} : to put in play a permanent, paying it's manacost and a kicker. This macro works only for single paid kicker. There are two <actions> nodes for this macro, respectivly corresponding to the kicker's cost and the associated effect.
cast-spell-kicker2{T} : to put in play a permanent, paying it's manacost and the second kicker. This macro works only for single paid kicker. There are two <actions> nodes for this macro, respectivly corresponding to the kicker's cost and the associated effect.
cast-spell-kicker12{T} : to put in play a permanent, paying it's manacost and the first and second kicker. This macro works only for two paid kickers. There are four <actions> nodes for this macro, respectivly corresponding to the first, then the second kicker's cost and the associated effect of respectivly first and second kicker.
amplify-1Amplify 1 ability. Example : Daru Stinger
amplify-2Amplify 2 ability. Example : Daru Stinger
amplify-3Amplify 3 ability. Example : Daru Stinger

Attachment references

These are described within the nested <attachments> element. We can find the following references :

Reference nameDescription
enchant-creatureUse this reference to attach 'enchant: creature' auras to a valid creature to enchant.

Action constraints

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>

Additional costs

Magic Project can manage additional costs using the <additional-costs> element.

Objects

The last part of the XML file is dedicated to the objects, which can be considered as counters (ice, poison, +1/+1, etc.). These are declared using the <objects> element.

The Magic the Gathering cards rules files

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.

Card rules XML file description

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/firemox"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://sourceforge.net/projects/firemox ../../validator.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/firemox"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://sourceforge.net/projects/firemox ../../validator.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 :

  • The <registers> element which is used to set some initial registers for the card. This element contains <register> elements usually with two attributes : index for the logical name of the register (in fact this is an integer index, thus the logical name used must be declared in the <aliases> element of the XML file mtg.xml) and value for the assigned value. Please note that the value or the index can be nested has elements. We usually use these register indexes for cards :
    • white for the amount of white mana in the casting cost,
    • blue for the amount of blue mana in the casting cost,
    • black for the amount of black mana in the casting cost,
    • green for the amount of green mana in the casting cost,
    • red for the amount of red mana in the casting cost,
    • colorless for the amount of colorless mana in the casting cost,
    • power for the power of the creature if this card is a creature,
    • toughness for the toughness of the creature if this card is a creature,

    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>
    
  • The <colors> element is used to add colors to the card. It can contains up to the five color aliases, seperated by a white space.

    In the example, the card is a white card.

    <colors>white</colors>
    
  • The <idcards> element is used to specify the main types of a card, it can hold the following values :
    • plains for plains,
    • island for an island,
    • swamp for a swamp,
    • forest for a forest,
    • mountain for a mountain,
    • land for a non-basic land,
    • creature for a creature,
    • artifact for an artifact,
    • local-enchantment for an aura,
    • global-enchantment for an enchantment,
    • instant for an instant,
    • sorcery for a sorcery.

    The example shows that the card is a creature.

    <idcards>creature</idcards>
    
  • The <properties> element holds the sub-types of the card like creatures types and also additional abilities like first strike. You should look at the XML file mtg.xml for the possible values by searching for the string "<!-- properties -->".

    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>

Other examples

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.

Cloudstone Curio

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/firemox" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://sourceforge.net/projects/firemox ../../validator.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">