title: Representing Retro Grid Maps tags: maps, goldbox, retro description: Thinking through some requirements around Gold Box style maps. category: coding
Modern computer RPGs have complicated, detailed, three-dimensional maps, but it was not always thus. Back in the 80s, as they were first crawling from table to monitor, the capabilities of the PCs of the era were better suited to the more spare graph paper maps of old AD&D modules.
I have a fair bit of nostalgia for many of the games from that period, in particular the Gold Box series. If you tease apart the Gold Box file format[^1], there are eleven bits of information associated with each grid square:
If I wanted to store a map with information like that, I could do worse than using a JSON representation. Something like:
{
[
"x": 12,
"y": 5,
"backdrop": "sky",
"zone": "shopping district",
"event": "none",
"wall_north": "none",
"wall_east": "rock wall",
"wall_south": "none",
"wall_west": "storefront door",
"move_north": "open",
"move_east": "blocked",
"move_south": "open",
"move_west": "unlocked door"
],
...
}
And that might be fine if you're making something purely
machine-written and machine-read. It's essentially a much more verbose
form of the old format, with x
and y
map coordinates explicit
rather than position-based. But if you're making something only for
machine consumption, then you don't need to be that explicit in the
first place.
I'm interested in what a human-centric map file format might look like.
Let's make a few assumptions. First, for example, most walls are going to be walls on both sides (one-way walls or one-way doors are representable based on the above, but it's hard to make sense of a map unless they're in the minority). Further, walls (and their absence) and doors will, in most cases, imply the navigability (that is, if there's a wall, you can't go that way, etc). I also imagine that many maps are going to use one wall and door type primarily. Likewise, I assume that "event" squares are the exception, not the rule. Finally, for the moment, I'm going to ignore "zone" and "background" (don't worry, I'll pick them back up later).
That brings us from eleven down to four bits of information for each cell: in each direction, is there a wall, door, or nothing?
Here's one take[^2]:
+---------+-+-+-+-+-+-----+-----+
| | D D | | D | |
| +D----+ +-+ +-+D+D+ +---+-----+
| | D D D | | | |
| | +---+ + + | +D--+-----+
| | | D D | | |
| | | +-+-----+ +D+ +-----+
| | | | | |
| +D+ +D+ +-----+ | +-----+
| D D D | | |
+--S--+ | +---+ +-------+ +-----+
| | | D D | D D |
+-+ +-+ | +D+-+ +---+-+ +-----+
| | | | D | D | | |
+-+ +-+ +D+--D+ +-----+ +-----+
| D | D | |
+-+ +-+ | + | +----D--+ +-+ +-+
| | | | | | | | | | | D |
+-+ +-+ | +--D+ | | +---+ +D+ +-+
| D | D | D | | |
+D+ +D+ | | | +-+-+ +D+D+ +--D+
| | | | | | | D D | | | | |
| +D+ +-+---+ +-+-+ +-+-+ +---+
| D | | D | |
+D+ +D+ +D+ +-+ +-+D+ +-+ +-+ +-+
| | | | | | | D D | | | | |
| +-+ | | | | | +D---D+-+ | | | |
| | | | | | | | | | | | |
+-----+ +-+ +-+ +--D+-+ | | | |
| D | | D |
+-----+-------------------+-+-+-+
That's fairly readable. A D
indicates a door, there, while |
and
-
are walls. The +
are walls, too. Well, corners.
Well, actually, that's a bit of a thing: the +
are used for
intersections, but looking back at what we're tracking, there's no
mention of intersections. It's a grid, after all--if your grid cell
has walls on adjacent cardinal directions, it's an
intersection. Otherwise, no. So the +
are visually helpful, but
convey nothing useful about the map from the machine's perspective.
In fact, there's quite a lot of useless visual help there. Each cell is taking up nine characters across three lines. Sure, there's overlap in the cell information, but that's still bulky for four pieces of information.
As a purely aesthetic aside, theoretically that map is 16x16, but it looks much longer north/south than east/west. That's a side effect of the aspect ratio of our text characters, but it would be nice if the representation looked a bit more proportional. Human-readability is part of the point, after all.
Between that aesthetic concern, and the fact that we have so much visual padding, that sparks a bit of a brainstorm. Let's try something a little different.
_________________________________
| _______ |_| |_|_|_| ____|_____|
| | ____| | | | |___|_____|
| | | |_|_____| ___ |_____|
| |_| ___ ______| | ______|
|______ | |____ |_______| |_____|
|__ __| | |_|_| ____|_| ______|
|_| |__ |_|___| |_____| |_____|
|__ __| | | | _________ ___ __|
|_| |__ | |___| | | ____| |_| |_|
|__ __| | | | |_|_| _____ ____|
| |_| |_|___| |_|_| |_|_| |___|
|__ ___ ___ ___ |_|_| |_| ___ __|
| |_| | | | | | ______|_| | | | |
|_____| |_| |_| |___|_| | | | |
|_____|___________________|_|_|_|
I'm ignoring doors for the moment, just for this proof of concept, but that looks nice and clean and much closer to square.
There's still redundant information, mind you, but it's much more compact. Each grid square is down to six characters across two lines. And we're making efficient use of the overlap: instead of 33 lines for a 16-length north/south, we only have 17. Our first line is just the northern wall, then each row handles the east, west, and south walls of each grid cell.
We're still using 33 columns, but, again, that ends up looking closer to square.
If we look at an random grid cell, the four bits of information are in
one character of one line, then three characters of the following
line. That does leave useless extra _
. If we eliminated those, it
might look like this:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
| _ _ _ |_| |_|_|_| _ _|_ _ _|
| | _ _| | | | |_ _|_ _ _|
| | | |_|_ _ _| _ |_ _ _|
| |_| _ _ _ _| | _ _ _|
|_ _ _ | |_ _ |_ _ _ _| |_ _ _|
|_ _| | |_|_| _ _|_| _ _ _|
|_| |_ |_|_ _| |_ _ _| |_ _ _|
|_ _| | | | _ _ _ _ _ _|
|_| |_ | |_ _| | | _ _| |_| |_|
|_ _| | | | |_|_| _ _ _ _|
| |_| |_|_ _| |_|_| |_|_| |_ _|
|_ _ _ _ |_|_| |_| _ _|
| |_| | | | | | _ _ _|_| | | | |
|_ _ _| |_| |_| |_ _|_| | | | |
|_ _ _|_ _ _ _ _ _ _ _ _ _|_|_|_|
Most of those extra _
are in spots that might otherwise have east or
west walls, so we couldn't just delete them. Instead, we replaced them
with spaces. I have to say, it still seems pretty readable to me. This
seems like the sort of thing that could come down to personal
preference, and since the contents of those spaces aren't going to be
used in the map, that's probably fine.
Personally, I prefer the more-connected walls. Let's go back to that, and add doors while we're at it.
Roguelikes have been using +
to represent doors for decades, so
let's start with that, at least for the doors to the east and
west. They're not going to line up as well with the southern
walls. I'm going to try .
for those.
_________________________________
| _._____ |_+ +_|.|.+ ____|_____|
| | ____+ + + | |.__+_____|
| | | +_+_____| _._ |_____|
| |.| _._ ______| | ______|
|__.___ + +____ +_______| |_____|
|__ __+ | +.+_| ____+_+ ______|
|_| |__ |.|__.| +_____| |_____|
|__ __+ | + | _____.___ ___ __|
|_| |__ | |__.| | | ____| |.| +_|
|._ _.+ | + | +_|_| _._._ ___.|
| |.| |_|___| |_+_+ |_|_| |___|
|._ _._ _._ ___ +_|.| +_| ___ __|
| |_| | | | | + _.___.+_| | | | |
|_____| |_| |_| |__.|_| | | | |
|_____+___________________|_|_+_|
Adding the doors definitely makes it a fair bit busier, but I still find it readable. I think the placecs with the most possible confusion are where there are a bunch of doors adjacent to each other--the training hall in the center of the north edge is a good example.
Overall, I like this. It seems reasonable to have a map file consist of a grid like the above, then a bunch of additional data below for all the exceptions.
I promised I'd get to the concepts of "backdrop" and "zone", and I will, but not in this entry. Stay tuned.
[^1]:
Which turns out to be a bit tricky. The file formats can differ
slightly between games, are all stored in a janky compression
format, and don't include information about the file contents.
Bits were expensive way back when, and if you knew that the map of
the civilized quarter was in the third block of the `GEO4.DAX`
archive file, there was no need to label it. Of course, that
starts falling apart when your dev team gets bigger, or if you
want to make the functionality more general.
[^2]: Savvy readers may notice this is the map of the civilized section of Phlan from the first Gold Box game: Pool of Radiance.