Monday, July 2, 2012

EPI #7: Maps, part 1

Three days, zero showers later, and I'm back in business!  And just in time, too, because I was about to run out of clean clothes.  Hygiene jokes aside, I did indeed manage to work through the power outage.

I've made it pretty clear thus far in the blog that I believe maps are a major component of RPGs.  It should come as no surprise to anyone, then, that I chose maps as a starting point for writing code.  I chose to build off the classes I outlined last time and write a class for rendering maps to the screen.

However, before I started writing code, I needed a way to describe the maps that will eventually become my input.  XML is a natural choice for what I'm trying to do, since it is both human- and machine-readable.  Although a more complicated scheme might lead to performance or space optimizations, I have no interest in pursuing one since it would just be harder to make sense of while debugging.  Also, I'm not operating under any particular performance or space constraints.

An XML map specification consists of three main parts: the tileset description, the map data, and any special events that apply to the map.  There's also a tag for a default location, which is where the map places any characters who aren't explicitly given a coordinate location.  XML for a simple map might look like this:


<map name='my_map'>
     <default x='1' y='1' />
     <tileset res_x='32' res_y='32'>
          <tile id='0' passability='0'>./content/test/tiles/test_0.png</tile>
          <tile id='1' passability='1'>./content/test/tiles/test_1.png</tile>
     </tileset>
     <data>
          <row>1,1,1,1,1,1</row>
          <row>1,0,0,0,0,1</row>
          <row>1,0,1,1,0,1</row>
          <row>1,0,1,1,0,1</row>
          <row>1,0,0,0,0,1</row>
          <row>1,1,1,1,0,1</row>
     </data>
     <special x='0' y='2'>GO TO my_map_2</special>
</map>


This is pretty straightforward.  The res_x and res_y attributes of the tileset element indicate the x and y resolutions of all the tiles therein.  A Map has exactly one tileset, and all tiles must share the same resolution.  The tiles do not, however, have to be square.  A tile element has id and passability attributes, and also specifies a file path.  I explained how passability works in a previous post, I'll get to id later when I talk about the data element, and the path identifies the location of the tile's image relative to the engine script.  Ids must be integers.  The data element consists of one or more rows, which each contain comma-separated tile ids.  Computerized color-by-numbers is a really good way to think of this.  The tileset section tells the engine which "colors" (really, images) go with which numbers, and the data section tells the computer what pattern to arrange them in.  Each row has to be the same size, but the map doesn't have to be square.  Finally, each special element identifies a (zero-indexed) map coordinate and specifies an special effect that happens there.  These are basically stubs at this point, since I haven't fleshed out the special effects system yet.

Two related thoughts come immediately to mind about this schema.  First, it's really easy for humans to read.  It makes intuitive sense.  Second, the data section is going to be an enormous pain in the ass to create by hand for maps that are tens or hundreds of rows or columns large.  This is probably a good time to mention that, although an editor application would be relatively straightforward to implement, I don't have any plans to write one right now.  My hands are full enough with game engine as it is.

One nice thing about XML is that since it's all text-based, which means it compresses really well.  One optimization I might be able to make to the engine later could be to enable it to deal directly with compressed files, thus reducing the size of scenarios.

Speaking of scenarios, this is only one part.  I haven't finalized the scenario hierarchy yet, but my thinking so far runs like so:  The root scenario directory, .../scenario_name, contains exactly one global.xml file, which describes various universal properties of the scenario, and many subdirectories, one for each distinct map in the scenario.  scenario_name/map_subdirectory will contain a map specification (which I described in this post), as well as NPC, item, and monster specifications, a subdirectory for audio resources (such as music and sound effects), and a subdirectory for graphical resources.

No comments:

Post a Comment