(This was one of the most interesting papers I saw, not only for the thought put into it but also for topicality. In it, RJ discusses what would happen were a programming language created to model Magic. Of course, programs that can play Magic exist, such as Modo or Duels of the Planeswalker. All of these, however, implement Magic using java (such as Forge), potentially with the card info in XML format (such as Wagic). You can see a couple different approaches in a great series of posts over at mtgrares, but RJ offers another look at how it might be done)
I’ve been especially impressed this quarter with my class on compilers – a system that initially seems so simple can easily reveal many layers of complication underneath. Magic is no different, it is a game whose basic rules can be explained in a matter of minutes (as shown in class) but the deep technique and strategy is much more far-reaching and deep. Thus, given these two systems, each of which is far more complicated than it seems, it was only natural that I wanted to combine them both somehow for this project. Unfortunately, compiling magic is rather useless without a language to compile, so I began to wonder what designing a programming language explicitly for magic would take. This paper discusses a possible approach to creating a programming language representative of Magic.
There is no shortage of programming systems in existence today that model magic. Some are rather basic, in order to accomplish a specific task (such as the example Kevin presented in class), whereas others attempt to model the entire game. In every case, the game is modeled using an existing programming language, such as C++, Java, or XML (for data representation). These are not simple representations. For example, consider cards that fundamentally alter the rules of gameplay (Necropotence, anyone?). How is it simple to change the rules of the engine that runs the game? Creating and battling creatures is simple enough, but when spells with complicated or unusual abilities are played, it’s difficult to alter the engine running the game.
So, if we’re to design a language, let’s start with the basics. The important objects will have to be cards, which can be objects as in any other modern object-oriented language. Decklists will serve as input to the program, as these allow a game to be run between two players, but since the game is part of the language itself, there is no need to model the game playing engine at all. The game is run by the compiler, which when given two decklists as programs can compile an executable that simulates a game.
Since cards themselves fall into a limited number of basic categories, these can serve as the keywords for each object. An initial list of creature, instant, sorcery, land, enchantment, and equipment will suffice for now. Creatures will contain two attributes: power and toughness. These can be set as integer values directly, or in the case of certain cards whose power and toughness change depending on the state of the game, methods which calculate the power and toughness appropriately. Creatures can also have zero or more attributes, such as Flying, Vigilance, Shroud, etc. Again, since these are language components, there is no need to write any additional code to handle these abilities, unlike existing systems.
Perhaps the most interesting aspect of any permanent, including creatures, lands, and enchantments, would be the abilities. This is a list of activated and triggered abilities, which will act like the attributes on each card object. Most abilities have two components: The cost or reason for why the ability would be activated, and then the result or action of the ability. Given the appropriate encoding, any ability could be added in this way, since the environment is created and managed by the compiler for the language.
For other spells, a more advanced system would be needed. Lands are relatively simple, only requiring an abilities list in the same way creatures do. Enchantments only require what they enchant: for example, a regular enchantment is just a permanent, but other enchantments can attach to other permanents. Equipment will contain a unique field that specifies the cost to equip the item to a card, then just an abilities list. Instants and sorceries are similar, but different, as they contain a single ability that is the result of the action.
This establishes the basic structure for all the types of cards in the system, but it does not establish the most fundamental part, which is the encoding of abilities. The critical feature here is that abilities can alter fundamental rules of the game, and the game needs to continue to operate correctly. Given that there are virtually an unlimited number of abilities that could be encoded, it is impossible to describe all of them here. Some of the potential options will be described, but given that there are almost ten thousand cards in existence, it would be unfeasible to try to describe all the potential cards that have been created.
First, consider a common ability keyword: target. This keyword is found almost everywhere in Magic, and provides for the ability to direct the effects of a card to a specific location or group. For example, “target player” selects a single player, “target creature” selects a creature. If an ability is targeted, we can introduce a keyword to carry out its effect. The language of the game will likely grow to include hundreds of keywords to specify all the potential abilities, but this is one critical item. Other critical encodings would be life totals, players, and permanent typing, which could be accomplished via the card type system described earlier.
I deliberately avoid offering the encodings for cards, as the vastness of the game necessitates that each card could require a new keyword for the ability it specifies. For instance, consider the landfall ability introduced in Zendikar. When implementing a compiler, the designer has a choice as to whether to include this keyword in the language, or to introduce a new keyword, or to encode the ability using the existing framework (trigger land battlefield). Thus, given an appropriate set of triggers and a large enough language, there would be no need to encode new abilities as keywords in the language, or if they were, it would be trivially simple to add a new dictionary of these to lookup.
There is no correct or best way to describe Magic programmatically, however these are some key decisions required when creating such a system. The idea is that it becomes simpler to model if the game is abstracted away from the programmer, who is given a language powerful enough to create an entire game. With this ability, Magic can clearly grow as a game, as the compiler for this new language is generic and extensible enough to allow for the creation of new features and attributes without fundamentally changing the language itself.
Appendix – includes example of what it might look like