|  | @@ -0,0 +1,262 @@
 | 
											
												
													
														|  | 
 |  | +---
 | 
											
												
													
														|  | 
 |  | +title: Representing Retro Grid Maps
 | 
											
												
													
														|  | 
 |  | +tags: maps, goldbox, retro
 | 
											
												
													
														|  | 
 |  | +description: Thinking through some requirements around Gold Box style maps.
 | 
											
												
													
														|  | 
 |  | +category: coding
 | 
											
												
													
														|  | 
 |  | +date: 2023-09-22
 | 
											
												
													
														|  | 
 |  | +---
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +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](https://en.wikipedia.org/wiki/Gold_Box). If you tease apart
 | 
											
												
													
														|  | 
 |  | +the Gold Box file format[^1], there are eleven bits of information
 | 
											
												
													
														|  | 
 |  | +associated with each grid square:
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  - what wall graphic (if any) for each of the four cardinal directions
 | 
											
												
													
														|  | 
 |  | +  - mobility for each of the four cardinal directions (e.g. if there's
 | 
											
												
													
														|  | 
 |  | +    a wall, or door, or locked door, or whatnot)
 | 
											
												
													
														|  | 
 |  | +  - the "backdrop"--an image which is used to, for example,
 | 
											
												
													
														|  | 
 |  | +    distinguish indoor and outdoor locations)
 | 
											
												
													
														|  | 
 |  | +  - the "zone"--what, if any, environmental subdivision of the map the
 | 
											
												
													
														|  | 
 |  | +    grid square is part of. This is used to have different lists of
 | 
											
												
													
														|  | 
 |  | +    random encounters, designate places safe for resting, stuff like
 | 
											
												
													
														|  | 
 |  | +    that.
 | 
											
												
													
														|  | 
 |  | +  - and an event, if any, that occurse in that square. Events cover
 | 
											
												
													
														|  | 
 |  | +    everything from stores, to NPC interactions, to fixed-location
 | 
											
												
													
														|  | 
 |  | +    battles.
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +If I wanted to store a map with information like that, I could do
 | 
											
												
													
														|  | 
 |  | +worse than using a JSON representation. Something like:
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +~~~ {.json}
 | 
											
												
													
														|  | 
 |  | +{
 | 
											
												
													
														|  | 
 |  | +  [
 | 
											
												
													
														|  | 
 |  | +    "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]:
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +~~~ {.text}
 | 
											
												
													
														|  | 
 |  | ++---------+-+-+-+-+-+-----+-----+
 | 
											
												
													
														|  | 
 |  | +|         | 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](https://www.mobygames.com/game/502/pool-of-radiance/).
 | 
											
												
													
														|  | 
 |  | +
 |