[page=Introduction to XML Data]
One of the major design goals of WeiNGINE was to make it easy for developers to create playable material with a minimum of fuss, and without the need for several specialized "editors" to create game content. Instead, almost everything which represents on-screen or behind-the-scenes gamecode is stored in a plaintext XML data file. For Planewalker Games itself, it means that we do not have to spend valuable development time creating and then maintaining a raft of individual file editors, and our designers can create Broken Hourglass material on virtually any computer with access to a common text editor.
This is also of particular interest to modders because it eliminates what in the past has been a learning curve that can take years to overcome. Most game engines optimize their data files for compactness and speed in processing, rendering them machine-readable only. To understand the contents of the data files, one either needed access to development documentation (which many developers are reluctant to provide), or to reverse-engineer the data files and develop browser and editor programs specially suited to translating the game bytecode into human-readable text.
This difference is significant. In the old world, a developer interested in assigning vital statistics in six major categories to a character in another system might need to know that statistics start at offset 0x200 in the character file, and know that Power is first, followed by Looks, Charm, Quickness, Guile, and Concentration. So a character creation tool might then place a hexadecimal sequence such as
in order to give the character 16 in Looks, 10 in Charm, 18 in Quickness, and so on.
In WeiNGINE, however, creating a character file is very different, and requires no special editor or understanding of hex codes. In the field, one would rarely have cause to create a character file from scratch--the game itself has a front-end for new character creation, but we use characters here as an easily accessible example. To make a new character without the aid of the engine's front-end, all one needs to do is load up a text editor and write something which looks like this:
<character> <Name value="Ioanna"/> <Portrait value="ioanna"/> <Strength value="10"/> <Agility value="17"/> <Toughness value="22"/> <Judgment value="14"/> </character>
The character tags represent the start and finish of a special-purpose XML block--in this case, the creation of a WeiNGINE character file. Each individual element inside the XML block represents a different attribute of a character. The Name, naturally, is the on-screen name of the character. The Portrait attribute refers to the filename of an image file (PNG or JPG) known to the engine--in this case, ioanna.png. Strength, Agility, Toughness, and Judgment are the four primary statistics of a WeiNGINE character, and they have been given (decimal) values here.
To be a fully-playable character, Ioanna would need a few other attributes set--notably an Appearance, which defines the name of the sprite to be used as her on-screen avatar, as well as a Soundset. These could be defined by hand, but we have another technique at our disposal. Let's say that we wanted Ioanna's character file to be very similar to another character file representing Isolde. We can tell Ioanna to inherit Isolde's character file as a template, then override that template with our new values. For instance, we can make Ioanna's character file read instead as:
<character> <template value="isolde.CHARACTER"/> <Name value="Ioanna"/> <Portrait value="ioanna"/> <Strength value="10"/> <Judgment value="14"/> </character>
Notice that we aren't assigning Agility or Toughness here--that value, along with any other unspecified value, will be inherited instead from the Isolde character. So if Isolde has 15 Strength and 15 Agility, Ioanna will have 15 Agility (because we inherit that value from Isolde) but just 10 Strength (because the Ioanna character file explicitly calls for 10 Strength, and that explicit instruction overrides the inherited Isolde template.)
Templates are one quick way to assemble gamecode. Another shortcut is the table file, which can be used to quickly create several new game resources in one single .xml file, or augment several existing files in the same manner. The below table example operates on a number of CHARANIM resources (which represent sprites used by characters and creatures in the game) and gives each of them an on-screen name, as well as specifies if they can be selected for use by a player character--0 indicates false while 1 means true.
<table> <head> CHARANIM Player_Can_Choose Name </head> <body> maleguard1 0 ~Male Guard~ specopf 0 ~Special Ops Female~ specopm 0 ~Special Ops Male~ zohero11 1 ~Female Hero #11~ zohero12 1 ~Female Hero #12~ zohero15 1 ~Female Hero #15~ </body> </table>
Strictly speaking, tables are not necessary. We could have achieved the same result by adding
<name value=~Male Guard~/> <Player_Can_Choose value="0"/>
to the maleguard1 charanim file, then doing the same for each and every other sprite file in the game. But this table makes it easier to browse the list of available chararnims all at one time, instead of having to hunt through game resources to find which are selectable and which are not. It also represents another key feature of WeiNGINE. A single game resource, be it a creature file or a sprite definition, can be "built" and modified from several different sources: stand-alone XML data files, tables such as the above example, and so forth.
Careful readers may be wondering at this point why we keep saying that "almost everything" is governed by these XML files, without actually explaining which gameplay elements are not stored and modified with XML files. The most obvious (but least interesting) category is audiovisual media--we use standard formats such as PNG for graphics and Ogg Vorbis for audio. Although their use inside the game is governed by XML data files, the media themselves are stored in conventional format.
The most substantial exception involves files which govern certain aspects of navigation inside on-screen areas. Data which represents the solidity of an area (which coordinates on a map are walkable, which block movement but can be seen or shot over, and which are totally solid and opaque walls) as well as data which represents objects which should appear "in front of" characters on the map (known as occluding objects, or "occlusion") are precompiled into novel bytecode formats, to avoid excessively long load times when entering a new area. We will discuss area creation in a later installment of this column, but suffice it to say that the creation of the solidity map is a simple process for area artists and the binary data is created directly by the engine, while the creation of the occlusion map involves one of the very few external tools necessary for WeiNGINE development.
(This tutorial was originally posted on the Planewalker Games website on 10-23-06.)