Ainulindale and I have recently been discussing in the IRC channel what we might do for representing piece and property data in V4. I’d like to present some of it here, in order to get comments and criticism. Please give this a read through and consider whether it covers the kinds of cases you’re likely to encounter in module construction.
First, a few notes:
-
I’m purposely omitting anything to do with piece behavior, and being vague about how piece faces are connected to images in order to let us focus on one part of the problem, namely representing piece properties.
-
I’m presenting elements in dependency order, so that in each example, all elements other than the one being defined have already been defined themselves. The structure will become clearer as you go.
-
I’m not intending for the average module designer to look at the XML; for those users, it’s important that the XML support the kind of structure we want to expose in the module editor. But there will be users who want to manipulate the XML directly or with scripts, or will need to look at it for troubleshooting purposes, and for those users I want the XML to be readable, while still making complex things possible.
-
What’s below is derived from what Ainulindale came up with two weeks ago, but he hasn’t seen my proposed templating system, so don’t assume he’s endorsing it.
Now for the proposal:
Enumerations:
<enum id="direction">
<item>north</item>
<item>south</item>
<item>east</item>
<item>west</item>
</enum>
An enum element has an id which names it, and contains zero or more item elements which indicate the values contained in the enumeration. (If you’re familiar with C, C++, or Java, this is intended to have the same meaning as enums in those languages.) The purpose of an enum is to define a type with a limited range of values.
Properties:
<stringProperty id="name" value="101 Airborne"/>
<intProperty id="movement" value="4"/>
<floatProperty id="angle" value="60.0"/>
<enumProperty id="direction" value="north"/>
Each property element has an id attribute which names the property and a value attribute which provides the value of the property. The type of the value is encoded in the name of the property element. E.g., intProperty is intended for holding integers, stringProperty for holding strings, and so on. The permissible range of values for an enumProperty is the same as the items in the enum named by the enumProperty’s id attribute. (Question: Would it make more sense to have an “enum” attribute for enumProperty, so that the enum referred to need not have the same name as the enumProperty?) This isn’t intended to be an exhaustive list of property elements. (Question: What other types might we want? E.g., other numeric types—such as bool, or unsigned types, or maybe numeric types range-limited in other ways—or dates, or a refProperty which takes an id reference as a value.)
Faces:
<face img="101 Abn front">
... properties ...
</face>
A face element has an img attribute which refers to the image to be used for that face. Face elements may contain any number of property elements as children.
Pieces:
<piece id="101 Airborne">
<intProperty id="movement" value="4"/>
...
<face img="">
...
</face>
...
</piece>
A piece may have any number of properties and any number of faces.
Templates:
Now for something abstract. A template establishes a pattern to be reused elsewhere. Here’s an example:
<template id="infantry">
<body>
<enumProperty id="type" value="infantry"/>
<intProperty id="movement allowance" value="4"/>
</body>
</template>
<piece id="10/1/1">
<use template="infantry"/>
</piece>
The template element establishes a named block of XML which can be inserted elsewhere by reference. The use element indicates the location where the body of template it refers to should be inserted. Effectively, the above is equivalent to:
<piece id="10/1/1">
<enumProperty id="type" value="infantry"/>
<intProperty id="movement allowance" value="4"/>
</piece>
Old hands will recognize this as a V3 piece prototype. The templates I’m proposing here generalize prototypes somewhat, by accepting named parameters:
<template id="infantry">
<parameter id="MOVE"/>
<body>
<enumProperty id="type" value="infantry"/>
<intProperty id="movement allowance" value="{MOVE}"/>
</body>
</template>
<piece id="10/1/1">
<use template="infantry">
<parameter id="MOVE" value="4"/>
</use>
</piece>
I’ve added three things here: First, there is a parameter element in the template. The intent of this is to signal that the template expects to be called with a parameter named “MOVE”. Second, the use element now has a parameter element as a child with “MOVE” as its id (to match the parameter name in the template) and “4” as its value. Third, if you look into the template body, you can see “{MOVE}” as the value of the “movement allowance” property. This signals where the value of MOVE will be inserted when the template is expanded. This second template example is intended to define a piece equivalent to the one which the first example does.
Furthermore, it might be convenient for templates to specify default values for their parameters, like so:
<template id="infantry">
<parameter id="MOVE" default="4"/>
<body>
<enumProperty id="type" value="infantry"/>
<intProperty id="movement allowance" value="{MOVE}"/>
</body>
</template>
This way, if the “infantry” template is used without a value for MOVE, MOVE will default to “4”.
More complex things are possible: A template may have multiple parameters. More than one parameter may be substituted into an attribute value (e.g., name="{OWNER} {SIZE} {TYPE}"). Templates may be nested. This:
<template id="foo">
<parameter id="X"/>
<body>
<intProperty id="x" value="{X}"/>
</body>
</template>
<template id="bar">
<parameter id="Y"/>
<body>
<use template="foo">
<parameter id="X" value="{Y}"/>
</use>
</body>
</template>
<use template="bar">
<parameter id="Y" value="1"/>
</use>
is equivalent to this:
<intProperty id="x" value="1"/>
I’m not recommending that you write a simple property in such a complex way; rather this is an example showing one way one might compose templates.
The scope of template parameters is the entirety of body of the template where they are defined. Template parameter values are not inherited by templates used within other templates. If you’re familiar with C++ templates, you might be thinking this looks rather familiar. You’d be right, as I modeled this on C++ templates. (NB: The body element in templates could be dispensed with. I don’t see an obvious need for it right now.)
So, some questions:
Does this look sufficiently powerful to capture what we want to represent for pieces?
For those of you who might work with this by hand or with scripts, does this look like something you’d want to use?
Can you think of improvements to the syntax?
I’ve attached an example using the pieces from the game Battle for Moscow, to give you a sense of how this might look in practice.