# How can I build a graphical map for my MUD engine?

I am working on a text-based game totally from scratch and one thing I am not sure how to do is the map system.

In my mud engine totally writen in Javascript (that will be executed in a Node.js environment), I use that kind of data to design an area and the links between rooms.

/**
*       [003]-[004]
*         |     |
* [001]-[002] [007]
*         |     |
*       [005]-[006]
**/
var map = {
"001" : {
"Id" : "001",
"Name" : "Room 001",
"Directions" : {
"N" : "",
"S" : "",
"E" : "002",
"W" : ""
}
},
"002" : {
"Id" : "002",
"Name" : "Room 002",
"Directions" : {
"N" : "003",
"S" : "005",
"E" : "",
"W" : "001"
}
},
"003" : {
"Id" : "003",
"Name" : "Room 003",
"Directions" : {
"N" : "",
"S" : "002",
"E" : "004",
"W" : ""
}
},
"004" : {
"Id" : "004",
"Name" : "Room 004",
"Directions" : {
"N" : "",
"S" : "007",
"E" : "",
"W" : "003"
}
},
"005" : {
"Id" : "005",
"Name" : "Room 005",
"Directions" : {
"N" : "002",
"S" : "",
"E" : "006",
"W" : ""
}
},
"006" : {
"Id" : "006",
"Name" : "Room 006",
"Directions" : {
"N" : "007",
"S" : "",
"E" : "",
"W" : "005"
}
},
"007" : {
"Id" : "007",
"Name" : "Room 007",
"Directions" : {
"N" : "004",
"S" : "006",
"E" : "",
"W" : ""
}
}
};


On the MUD game I am actually playing, the mud command display something like this:

I would like to know in pseudo-code the way to do this in the most efficient way.

Please note that it has a maximum character length for each lines and that the map is centered around You (@).

• Note that most MUD developers/designers type out those maps by hand, rather than auto-generating them. This is because the map rarely adheres to a perfect grid. – Kylotan Oct 31 '11 at 11:22

If your room layout is consistent enough (all connections are the same length and can be traversed in both directions, and no rooms overlap), this is a simple exercise in recursion. Here's a quick piece of code that should do it:

var offsets = {
"N": [0, -1],
"E": [+1, 0],
"S": [0, +1],
"W": [-1, 0]
};

// recursively plot the locations of the rooms on a grid:

function drawMap ( map, room, grid, x, y ) {
var loc = x + "," + y;
if ( loc in grid ) {
if ( grid[loc] !== room ) {
// inconsistency detected
}
return;
}
grid[loc] = room;

if ( x < grid.minx ) grid.minx = x;
if ( x > grid.maxx ) grid.maxx = x;
if ( y < grid.miny ) grid.miny = y;
if ( y > grid.maxy ) grid.maxy = y;

var neighbors = map[room].Directions;
for ( dir in neighbors ) {
if ( dir in offsets && neighbors[dir] !== "" ) {
var off = offsets[dir];
drawMap( map, neighbors[dir], grid, x + off[0], y + off[1] );
}
// else handle unknown direction
}
}

var grid = { "minx" : 0, "maxx" : 0, "miny" : 0, "maxy" : 0 };
drawMap( map, "001", grid, 0, 0 );

// draw the grid in pretty ASCII art:

var mapString = "";
for ( var y = grid.miny; y <= grid.maxy; y++ ) {
var line1 = "";
var line2 = "";
for ( var x = grid.minx; x <= grid.maxx; x++ ) {
var loc = x + "," + y;
if ( loc in grid ) {
var neighbors = map[ grid[loc] ].Directions;
line1 += ( neighbors.E !== "" ? "+-" : "+ " );
line2 += ( neighbors.S !== "" ? "| " : "  " );
} else {
line1 += "  ";
line2 += "  ";
}
}
mapString += line1 + "\n" + line2 + "\n";
}

// document.write( "<pre>" + mapString + "</pre>" );


Some possible improvements left as exercises include:

• Drawing different rooms and connections differently, and generally making the output fancier.
• Support for diagonal connections.
• Handling one-way connections correctly.
• Allowing variable (integer) connection lengths.
• Detecting situations where a room seems to appear more than once on the map (e.g. where a room is connect to itself), which can cause the code above to recurse forever. (This is fairly easy, just maintain a separate list of mapped rooms.)
• Automatically resolving situations where two rooms seem to appear in the same location (e.g. where going S,E,N,W gets you into a room other than the one you started in).

The last exercise is a difficult one, since it potentially gets you all the way into the complex realm of arbitrary graph layout algorithms.