XML Level Editor

The XML Level Editor (AKA Platypus Editor) was developed in parallel with A Platypus Tale by myself and another programmer on the team.

This project was important for several reasons. First – it was something to show to the professors while the game framework was being developed (at a time when we had nothing to “show” besides the code itself). Second, it forced us to sit down and make some decisions about the layout and rendering. We decided on a system of game layers (9, to be exact). The ordering of the layers provided a z-index, e.g. closer layers are drawn last (that is, on top of) farther layers to give the game the illusion of depth. The farthest back layer – the background – would also scroll at a different speed than the foreground layers to add a parallax effect.

The main character sprite (Cooper) would be drawn in the “physical” layer – and thus would only interact with other objects in the physical layer. This split collision checking into two types – rectangular for (most of the) terrain (more on that later) and pixel-perfect for physical objects. Many of the layers were simply decoration to give the environment a more immersive feel.

Here is a screenshot of the editor in action. I’ve created a small level using an early version of the game assets:

WPF was a good choice for such a project. With WPF, many of the things we needed to do were already supported, and didn’t require anything fancy or some roundabout method. Take for example the listbox on the right, which required a custom list item comprised of an image box and text field displaying the tile size of the object. This is very easily accomplished using the WPF XML-style layout. Also, the ability to easily tie the slider to the zoom of the level area was invaluable – just a couple lines of code to implement, and the productivity of the level designers increased dramatically!

The listbox/tab area on the right is completely dynamic. That is, whatever subfolders are located within the ASSETS directory will be used as the tabs (and folder names will be used as tab titles). Whatever images are in the subfolders are then used to generate the list items. That way, we didn’t have to touch the editor code every time the artists revised a game asset.

The tabs are tied to specific layers in the game level grid. Selecting a tab doubles as selecting the current layer, and the designer can only add to, or erase from the currently selected layer.

Each time an asset is added, the game world object is updated to include a 64×64 pixel partition of the original image, and if the partitioned images do not already exist in the special folder “GeneratedAssets”, the image is cut into tile sizes and named with a numerical suffix to indicate with portion of the original image it came from (e.g. image_0_0, image_0_1).

Finally, what would the level editor be without the ability to save, load, or merge levels? The XML format is simple, consisting of a root element and 9 layer sections. Within these are tiles, which indicate the coordinate, and which generated asset belongs in that spot. For example,

<?xml version="1.0" encoding="utf-8"?><root>
<Layer LayerNumber="1" xSize="64" ySize="64">
	<Tile Coordinate="8,48">Decoration-hugecrystal_0_1.png</Tile>
	<Tile Coordinate="8,49">Decoration-hugecrystal_0_0.png</Tile>
	<Tile Coordinate="9,48">Decoration-hugecrystal_1_1.png</Tile>
	<Tile Coordinate="9,49">Decoration-hugecrystal_1_0.png</Tile>

Each “page” in the editor provides a square of 64×64 tiles. So, if a designer wishes to make a wider level (i.e. 256 tiles wide by 64 tiles high), they may use the Merge feature, which iteratively joins and re-numbers coordinates with respect to the full map.

Check out some Merged levels below – fully zoomed out, cropped, and glued together with some Photoshop magic. (Note: these omit the background image, as the backgrounds do not stretch, but rather scroll more slowly than the foreground).

It’s interesting – many of the maps turned out to look like tree branches, which seems appropriate, as levels 1, 2, and 3 take place in a forest!