I just put together a little TADS3/adv3 module for generating very simple random maps. It’s now available here: simpleRandomMap github repo.
The map generation uses the same basic algorithm used in the random map example I included in routeTable module: All maps are square, 10x10 by default. If a room is along the north edge of the map, it gets an exit to the east. If a room is along the east edge, it gets an exit to the north. If the room is along neither the north nor east edge it randomly gets either an exit to the north or an exit to the east. All exits are reciprocal, so when room #1 gets an east exit to room #2, room #2 automagically gets a west exit back to room #1. This algorithm guarantees that a path exists between any two arbitrary rooms.
The maps generated this way are really not suitable for any IF game written after about 1984. But it’s not intended for generating content for games to be published, it’s intended to generate test cases for pathfinding, NPC scripting, and so on.
Usage is trivial. By default the module just looks for an declared instance of the SimpleRandomMapGenerator
class and generates a map using the instance for configuration options. To use all the defaults you just have to include a line like:
myMap: SimpleRandomMapGenerator;
…somewhere in the project source. This will create a random 10x10 map (100 total rooms) and place the player (as defined by gameMain.initialPlayerChar
) into the first room (the southwest corner).
Optional properties on SimpleRandomMapGenerator
are:
mapWidth
specifies the width of the map. Default is10
, which makes a 10x10 map. Note: no bounds checking is done on this valueplacePlayer
is a flag. If booleantrue
, the player will be moved to the first room of the generated map after map generation. The default istrue
player
the player object to place ifplacePlayer
istrue
. By default this isgameMain.initialPlayerChar
, but this can be set to be something else if you want to (for example) dump an NPC into the generated map instead
Multiple map instances are theoretically supported, but the builtin behaviors all assume that you’ll only be generating one map at a time (and so you’ll have to do subclassing to make multiple simultaneous generated maps work).
Everything in the module is wrapped in preprocessor conditionals, so everything can be enabled or disabled by twiddling the -D SIMPLE_RANDOM_MAP
flag at compile time.
There’s also a -D SIMPLE_RANDOM_MAP_GRID
flag, which will tell the generator to make a regularly-connected grid of rooms (every room gets north, south, east, and west exits except at the edges of the map) instead of a random one.
Finally, compiling with -D __DEBUG_SIMPLE_RANDOM_MAP
enables the debugging commands. At the moment there’s just one: you can use >M
to display a simple ASCII map of the surrounding area:
>m
Showing (1, 2) - (5, 6)
.............................................
...[_]======[_]======[_]======[_]======[_]===
......................|.................|....
......................|.................|....
...[_]======[_]======[_]......[_]======[_]...
....|...................................|....
....|...................................|....
...[_]......[_]======[*]======[_]======[_]...
....|........|.................|........|....
....|........|.................|........|....
...[_]......[_]......[_]======[_]......[_]...
.............|..........................|....
.............|..........................|....
...[_]======[_]......[_]======[_]======[_]...
.............|...............................
The map will auto-center around the player (except at map edges), and the player’s position is indicated by the asterisk.
This will obviously only work if you’re using a proportional font. And it doesn’t work with screen readers (I’m open to suggestions for how to make this sort of thing more accessible).
Not sure how useful this sort of thing will be to general IF authors, but I’d previously written a version of this code for testing pathfinding in the routeTable
module and then I found myself re-writing it for testing some NPC behaviour stuff. And whenever I find myself writing the same thing twice that tells me it’s probably time to turn it into a library, so that’s what I did.