MUD on Urbit

Mapping & Navigation

research Doc 13

A comprehensive reference on how MUDs represent space, help players navigate it, and how client-side mappers render it. Covers everything from room graph fundamentals to pathfinding algorithms to Aardwolf’s continent coordinate system.


1. Room-Based vs Coordinate-Based Geography

1.1 Traditional Room Graph

The classic MUD spatial model treats the world as a directed graph where each node is a “room” and edges are exits. Rooms have no inherent position in space – they exist only by virtue of their connections.

Structure:

  • Each room has a unique ID (vnum), a name, a description, and a set of exits
  • Exits map a direction keyword (n/s/e/w/u/d, plus custom exits) to a destination room ID
  • No coordinates required; rooms are connected purely by logical links
  • The world is essentially a web of interconnected nodes, analogous to hyperlinked web pages

Characteristics:

  • No consistent scale: One room might represent a closet, another an entire forest. Two “plains” areas might abut geographically but have no connecting exits between their interiors
  • Flexible topology: Rooms can connect in non-Euclidean ways (a hallway that loops back on itself, a door that leads somewhere “impossible”)
  • Simple to build: Builders create rooms and link exits without worrying about coordinate collisions
  • Hard to map visually: Without coordinates, client-side mappers must infer positions from movement directions, leading to overlapping rooms

Pros:

  • Extremely flexible – any topology is possible
  • Easy for builders to create and modify areas
  • Low memory overhead per room
  • Natural for indoor/dungeon environments where strict geometry doesn’t matter

Cons:

  • No inherent sense of distance or direction between non-adjacent rooms
  • Client automappers struggle with overlap and non-Euclidean connections
  • Wilderness/overworld areas feel artificial as discrete rooms
  • Pathfinding must operate on the raw graph (no heuristic shortcuts like A*)

1.2 Coordinate/Grid Systems

Some MUDs assign every room an (x, y) or (x, y, z) coordinate, placing the world on an explicit spatial grid.

Structure:

  • Each room has coordinates local to its area or global to the world
  • Movement in a cardinal direction changes coordinates predictably (north = y+1, east = x+1, etc.)
  • Rooms can be generated procedurally from a heightmap or terrain function
  • Exits are often implicit: if a room exists at the adjacent coordinate, you can move there

Characteristics:

  • Consistent scale: Each grid cell represents the same spatial unit
  • Natural for wilderness: Open terrain, oceans, and overworld maps work well on grids
  • Enables spatial queries: “What’s within 5 tiles of me?” is trivial with coordinates
  • Supports line-of-sight, range, and area-of-effect calculations

Approaches:

  • Pure function terrain: A function takes coordinates as input and returns terrain type (using Perlin noise, fractals, etc.). No need to store every room explicitly
  • Height-mapped 3D: A z-level variable per tile allows vertical structures. Tiles above the base level default to empty/air unless specified. One byte per tile for height data keeps memory minimal
  • Tile iteration: Rather than calculating movement/LOS from coordinates alone, iterate over tiles between source and destination, allowing complex vertical geometry (cliffs, towers)

Pros:

  • Realistic spatial relationships; great for ranged combat, archery, area effects
  • Client mappers can render accurately with no guesswork
  • Supports procedural generation of large wilderness areas
  • Enables A* pathfinding with coordinate-based heuristics

Cons:

  • Less flexible topology – non-Euclidean spaces require special handling
  • Grid artifacts: diagonal movement is longer than cardinal (unless hex grid)
  • Large open worlds consume more memory if every cell is stored
  • Builders must respect coordinate constraints

1.3 Wilderness / Overworld Systems

A common hybrid where the main world map uses coordinates but interior areas (dungeons, cities) use room graphs.

Evennia’s Wilderness Contrib:

  • Provides a wilderness map without creating actual room objects in the database
  • As you move, you re-enter the same room object but its description changes based on your coordinates
  • Enables huge areas with minimal database footprint
  • Works well when rooms are relatively similar (terrain variations, not unique locations)

Typical Implementation:

  • Overworld stored as a 2D array or generated from a terrain function
  • Each cell has a terrain type determining description, movement cost, encounters
  • Entrances to instanced areas (dungeons, towns) are placed at specific coordinates
  • Players see a minimap of surrounding terrain when on the overworld

1.4 Hybrid Approaches

Most modern MUDs use some combination:

  • Aardwolf: Room-based graph with continent coordinates overlaid. Each room has a vnum (graph node) plus (x, y, continent_id) coordinates for mapper positioning. Interior areas may lack coordinates (returning -1 values)
  • Ranvier: Rooms support optional 3D coordinates [x, y, z] local to their area. The getExits() method returns both explicitly defined exits and exits inferred from adjacent coordinates
  • Evennia XYZGrid: Maps drawn as ASCII art are parsed into room graphs with coordinates. Pathfinding uses Dijkstra within each map. Transitions between maps (z-levels) handled via special teleport nodes

Design considerations for hybrid systems:

  • Coordinate rooms should have consistent scale; graph rooms can vary
  • Need clear transitions between coordinate space and graph space
  • Client mappers need to handle both modes (GMCP coordinate data vs. inferred positions)
  • Pathfinding may need different algorithms for each space type

2. Automapping Systems

2.1 Mudlet Mapper

The most widely-used modern MUD mapper. Renders a 2D graphical map in a panel alongside the text output.

GMCP Integration (IRE Mapping Script):

The mapper consumes GMCP Room.Info data to build maps automatically. Required fields:

FieldPurpose
Room.Info.numUnique room ID; used as the mapper’s internal room identifier
Room.Info.nameRoom name displayed on hover
Room.Info.areaArea name; rooms auto-assigned to mapper areas
Room.Info.environmentEnvironment/terrain type; determines room color on the map
Room.Info.exitsTable of {direction: destination_room_id}; builds exit links

Key Lua API Functions:

Room management:

  • addRoom(roomID) – Create a room
  • setRoomName(roomID, name) – Set display name
  • setRoomCoordinates(roomID, x, y, z) – Position on the map canvas
  • setRoomArea(roomID, areaID) – Assign to an area
  • setRoomEnv(roomID, envID) – Set environment (determines color)
  • setRoomWeight(roomID, weight) – Pathfinding cost (higher = avoided)
  • lockRoom(roomID, locked) – Exclude from pathfinding entirely
  • setRoomUserData(roomID, key, value) – Store arbitrary metadata

Exit management:

  • setExit(fromID, toID, direction) – Create a standard exit
  • addSpecialExit(fromID, toID, command) – Create a custom/special exit
  • getRoomExits(roomID) – Returns {direction: destination_id} table
  • getSpecialExits(roomID) – Returns custom exits separately

Navigation:

  • getPath(fromID, toID) – Calculate shortest path; populates speedWalkDir (directions) and speedWalkPath (room IDs)
  • speedwalk(fromID, toID, delay, reverse) – Execute the walk

Map storage:

  • Maps stored as binary files (.dat) in the Mudlet profile directory
  • One map file per profile; contains all rooms, areas, and metadata
  • Can be shared between users for pre-built maps

The IRE Mapping Script was developed for Iron Realms Entertainment games but can be adapted to any GMCP-capable MUD by implementing the required Room.Info fields.

2.2 MUSHclient Mapper

Nick Gammon’s generic graphical mapper module for MUSHclient.

Architecture:

  • Callback-based design: the mapper module is MUD-neutral
  • A calling plugin provides room data through a get_room() callback function
  • The callback returns: room UID, name, area, exit mappings, visual properties (border color, fill color, pen styles), hover messages

Rendering:

  • Uses breadth-first traversal from the current room outward
  • Draws rooms at fixed screen distances per direction
  • Arrows indicate one-way exits
  • When multiple rooms map to the same screen position, the closest (first-discovered) room wins
  • Performance: ~400 rooms rendered in ~0.07 seconds; ~100 rooms in ~0.01 seconds

Features:

  • Left-click speedwalking to any visible room via shortest route
  • Room search with configurable conditions
  • Individual room coloring for terrain types, shops, trainers, etc.
  • Hover tooltips with room info

GMCP Mapper Plugin:

  • Processes room.info GMCP data: num, name, zone, terrain, exits, coordinates
  • Maps rooms as you explore; pre-loaded maps available for some MUDs (Aardwolf ships with continent maps)

2.3 TinTin++ Mapping

Terminal-based mapper with extensive command-line controls. No GUI – renders ASCII maps directly in the terminal.

Map Creation:

  • #map create <size> – Initialize map (default 50,000 rooms)
  • #map dig <exit> [new|<vnum>] – Create exits and rooms
  • #map link <direction> <room> [both] – Connect existing rooms
  • #map insert <direction> [roomflag] – Insert room between two connected rooms

Room Properties:

  • Room flags: avoid, block, hide, invis, leave, noglobal, void, static
  • avoid – Pathfinder routes around this room
  • block – Automapper won’t move through this room
  • hide – Map display stops at this room
  • void – Spacing room for visual layout (not a real room)
  • static – Disables automatic exit creation when moving
  • Exit flags via #map exitflag: AVOID, BLOCK, HIDE, INVIS

Navigation:

  • #map find <name> [filters] – Calculate shortest path (stored in #path)
  • #map run <room> [delay] – Pathfind and auto-walk
  • #map goto <vnum|name> – Teleport to a room on the map
  • #map explore <exit> – Follow a direction until intersection or dead end
  • #map travel <direction> <delay> – Walk in one direction with delay between steps

Display Modes:

  • #map map <rows> <cols> – Render ASCII map to output
  • asciigraphics flag – Detailed display with diagonal exits
  • symbolgraphics flag – Compact 1x1 symbol display
  • vtgraphics flag – Uses terminal line-drawing characters
  • vtmap flag – Persistent map in top split-screen panel
  • pancake flag – Shows stacked vertical layers

Terrain System:

  • #map terrain <name> <symbol> [flags] – Define terrain types with density/spread options
  • Custom terrain rendering affects map display symbols and colors

File Operations:

  • #map read/write <filename> – Load/save maps
  • #map sync <filename> – Merge maps without overwriting

2.4 Required Server Data for Automapping

For any automapper to work, the server must provide:

Minimum viable:

  • Room identifier (unique ID or hash of name+exits)
  • Exit directions and destinations
  • Reliable movement confirmation (so the mapper knows when you’ve actually moved)

Ideal (GMCP):

  • Unique room ID number
  • Room name
  • Area/zone name
  • Terrain/environment type
  • Exit table with destination IDs
  • Coordinates (x, y, z or equivalent)
  • Room flags (no-magic, no-mob, death trap, etc.)

Without GMCP, mappers must parse room names and exits from text output using triggers, which is fragile and error-prone.


3. In-Game Map Commands

3.1 ASCII Minimap Generation

Many MUDs provide a server-side map command that generates an ASCII representation of nearby rooms.

Evennia’s Algorithm (Recursive DFS):

  1. Start at the player’s current room
  2. A “worm” walks outward in each cardinal direction, drawing rooms as it goes
  3. Track position with (curX, curY) coordinates on a 2D character grid
  4. worm_has_mapped dictionary prevents revisiting rooms
  5. Stop after reaching max distance (calculated as (min(width, height) - 1) / 2)
  6. Grid dimensions must be odd numbers to ensure a center point exists

Symbol conventions:

SymbolMeaning
[@]Player’s current position
[ ] or [.]Standard room
-East-west connection
|North-south connection
/ \Diagonal connection
[#]Blocked/wall
[$]Shop
[!]Quest NPC
@Player location (Discworld style)
*Room (Discworld)
+Door (Discworld)
$Room with living things (Discworld)

3.2 Discworld MUD Map Command

One of the most polished in-game map implementations:

Syntax variants:

  • map – Default display (configurable between ASCII and text)
  • map ascii – Force ASCII art map
  • map text – Text-based directions
  • map door text – Shows objects in line of sight

Map contexts:

  • City maps: Show immediate surroundings with rooms, exits, and doors
  • Terrain maps: Display wilderness areas where walk and journey commands apply

Display options:

  • options output map plain=on – Disable color
  • options output map mxp=on – Enable clickable MXP room links
  • options output map look/lookcity – Auto-show map on entering rooms
  • options output map reversecolour=on – Swap foreground/background colors

3.3 Aardwolf Map Command

Displays an overhead minimap of current room and surroundings:

  • Shows nearby mobs, doors, and shops
  • Indicates exit directions
  • Integrates with the GMCP mapper for client-side rendering

3.4 Implementation Considerations

Generating ASCII maps server-side:

  • BFS or DFS from the player’s room, limited by depth
  • Map each discovered room to a position on a character grid
  • Handle overlapping rooms (first-discovered wins, or skip conflicting positions)
  • Only cardinal directions produce clean maps; diagonals and custom exits complicate layout
  • Custom fonts with embedded symbols (trees, water) can enhance display but require client-side font installation

Map integration with room display:

  • Can be shown automatically above room descriptions on look
  • Or invoked explicitly with a map command
  • Configurable size (3x3, 5x5, 9x9 tiles, etc.)

4. Navigation Aids

4.1 Speedwalking

Automated movement through a sequence of rooms.

Syntax formats:

  • Shorthand: 3n2e4s = north 3 times, east 2 times, south 4 times
  • Verbose: IN N 3W 2U W = in, north, west 3 times, up 2 times, west
  • Client-specific: Mudlet’s speedwalk() function, TinTin++’s #map run

Key features:

  • Configurable delay between moves (to avoid server-side spam protection)
  • Route recording: record a path manually, replay it by name later
  • Mudlet stores routes in speedWalkDir (directions) and speedWalkPath (room IDs) tables
  • Room weights influence pathfinding: higher weight = less preferred route
  • Locked rooms excluded from pathfinding entirely

Risks:

  • If interrupted mid-walk (by a mob, closed door, or lag), the player ends up lost
  • Some MUDs penalize rapid movement or have anti-speedwalk timers
  • One-way exits can strand a player if the path is reversed naively

4.2 Recall and Teleport

Recall:

  • Classic Diku/Merc mechanic: instantly return to a designated “hometown” room
  • Typically available as a spell, scroll, or potion
  • Common restrictions: can’t recall from combat, can’t recall from no-recall rooms, lag/delay before teleport (e.g., 5-second cast time with re-check for combat)
  • Some MUDs confuse the player for 2 rounds before teleporting to allow PvP counterplay

Teleport:

  • Higher-level spell to teleport to a random or targeted room
  • Portal spells create temporary two-way links between rooms
  • Summon spells pull another player to your location

Hometown/Bind points:

  • Players set their recall destination (hometown, guild hall, etc.)
  • Some MUDs allow multiple bind points

4.3 Portals

  • Permanent portals: fixed links between distant rooms (connecting continents, linking hub cities)
  • Temporary portals: player-created, time-limited passages
  • Quest portals: appear only under certain conditions
  • Portal rooms: dedicated rooms that serve as transit hubs with multiple portal destinations

4.4 Hunt and Track

Hunt:

  • Locates a specific mob or player within the area
  • Returns the direction to move toward the target
  • Aardwolf’s hunt trick: hunt 1.<target>, hunt 2.<target>, etc. to enumerate instances, then use the count with where to find the specific room

Track:

  • Skill that shows a trail of footprints leading toward a target
  • May have a chance of failure based on skill level
  • Some rooms flagged NOTRACK prevent tracking through them

Scan:

  • Shows creatures/players in adjacent rooms (typically 2-3 rooms in each direction)
  • scan <direction> to scan a specific direction
  • Doors flagged noscan block scanning

4.5 Where and Area Finding

  • where – Lists visible players/mobs in the current area with their room names
  • where <target> – Locates a specific target within the area
  • areas / area list – Shows all areas with level ranges and continent locations
  • Mapper-based: mapper areas (Aardwolf) finds area exits within search depth
  • mapper find <name> – Searches for rooms by name within configurable depth
  • mapper quest / mapper shops – Locates quest NPCs and shops

5. Aardwolf’s Mapping System

5.1 GMCP Mapper

Aardwolf’s GMCP mapper was authored by Nick Gammon and modified for GMCP compatibility by Lasher. Originally a MUSHclient plugin, now also implemented for Mudlet.

GMCP room.info Data:

{
  "num": 32418,
  "name": "The Grand City of Aylor",
  "zone": "aylor",
  "terrain": "city",
  "details": "",
  "exits": { "n": 32419, "e": 32420, "s": 32415, "w": 32611 },
  "coord": { "id": 0, "x": 37, "y": 19, "cont": 0 }
}

Key fields:

  • num: Unique room vnum
  • exits: Only standard directions (n/e/s/w/u/d); custom exits omitted for mapping purposes
  • coord.id: Continent ID (0-6)
  • coord.x, coord.y: Position on the continent map
  • coord.cont: Binary flag – 1 if the room is on a continent, 0 if inside an area
  • Inside mazes, room IDs are hidden – only direction names appear in exits

Non-mappable rooms (clan halls, etc.) return -1 for num, coord.id, x, and y with empty exits.

5.2 The Seven Continents

The world of Andolor:

IDContinentDescription
0MesolarCentral civilization hub. Great cities, trade routes, alliances. Safest and most populated.
1Southern Ocean (Iridian Sea)Island societies, rumored underwater civilizations
2GelidusFrozen north. Permanently away from the sun, covered in ice and ancient glaciers
3AbendThe Dark Continent. West of Mesolar across the Banalog Ocean. Perpetual twilight, dangerous
4AlaghThe Blood Continent. East of Mesolar across the Aphasian Ocean. Deserts, jungles, centuries of warfare
5Uncharted OceansVast unexplored waters with occasional islands
6VidblainRumored fifth continent (“ever dark”), unverified

World properties:

  • Andolor orbits a single sun but does not rotate; three moons create rapid day-night cycles
  • The world is mostly circular: traveling far enough in any direction returns you near your starting point
  • Over 30,000 unique rooms across all continents

5.3 Mapper Features

  • Pre-loaded with continent maps and lower-level area maps
  • Each square on the mapper represents a single room
  • Current location highlighted in pink
  • Unvisited rooms shown with dotted lines
  • Diagonal lines indicate up/down exits
  • Half-lines indicate one-way passages
  • Recently traveled paths display as bolder lines
  • Hover tooltips show room names and exit destinations

Mapper commands:

  • mapper find <name> – Search rooms (default 50-room depth, adjustable)
  • mapper goto <room_num> – Navigate to a room by vnum
  • mapper where <room> – Display directions to a room
  • mapper areas – List area exits within search depth
  • mapper quest / mapper shops – Locate quest NPCs and shops
  • Bookmarking system via right-click on rooms

5.4 Gaardian Map Archives

Community resource at maps.gaardian.com:

  • 264 publicly available area maps, automatically generated from dynamic content
  • Maps update within seconds of area changes
  • Show room names, connections, portals (marked with link icons), locked doors (hover details)
  • Searchable by room name
  • Screen-reader-friendly VI index for accessibility
  • Copyleft licensing; community sharing with attribution

5.5 Navigation Commands

  • exits – Shows all exits; parenthesized exits are doors that must be opened; “other” exits are custom exits entered by keyword
  • scan – Shows creatures/players in adjacent rooms (3-room range per direction)
  • hunt <target> – Direction toward a mob/player
  • where <target> – In-area room location of a mob/player
  • map – Overhead minimap of surroundings

6. Spatial Design Patterns

6.1 Hub-and-Spoke

A central hub room (city square, guild hall, crossroads) connects to multiple destination areas radiating outward.

Applications:

  • Hub cities: A central city with exits leading to surrounding wilderness areas, dungeons, and other zones. Midgaard in CircleMUD, Aylor in Aardwolf
  • Portal hubs: A room with multiple portals to different continents or planes
  • Guild halls: Central location with exits to training rooms, shops, quest boards

Design principles:

  • Hub should be memorable and easy to find (recall target, portal destination)
  • Spoke areas should have clear thematic identity
  • Consider multiple hubs at different scales (world hubs, continent hubs, area hubs)

6.2 Maze Design

Intentionally confusing areas that challenge navigation.

Techniques:

  • Identical room descriptions: Every room looks the same, forcing players to map carefully
  • One-way exits: Entering a room from the north doesn’t mean going south returns you
  • Randomized exits: Exits shuffle periodically or on each visit
  • Loops: Paths that circle back on themselves
  • Dead ends: Force backtracking
  • Hidden exits: Critical paths concealed behind search/examine commands

Aardwolf approach: Inside mazes, GMCP room IDs are hidden in exit data (only directions shown), deliberately complicating automapping.

Best practices:

  • Mazes should reward exploration, not just punish it (treasure, shortcuts, secrets)
  • Provide hints in room descriptions for observant players
  • Limit maze size; enormous mazes are tedious, not challenging
  • Consider making mazes optional rather than required for progression

6.3 Vertical Space

Standard vertical exits:

  • up and down directions in the room graph
  • Sector types: UNDERWATER (below water surface), FLYING (requires flight ability)
  • CircleMUD sector types: WATER_SWIM (6), WATER_NOSWIM (7), UNDERWATER (8), FLYING (9)

Height-mapped tiles:

  • Z-level variable per tile for multi-story structures
  • Default: tiles above ground level are empty/air unless specified
  • Enables towers, cliffs, multi-floor buildings, caves beneath the surface

Evennia XYZGrid approach:

  • Each z-level is a separate 2D map
  • u/d link characters in the ASCII map definition connect levels
  • Special fly/dive commands for vertical movement
  • Pathfinding operates within each map only; cross-map (vertical) transit not included in auto-walk

Design considerations:

  • Vertical movement should feel distinct from horizontal (climbing, flying, diving, falling)
  • Consider movement cost differences (climbing takes more effort)
  • Falling damage for uncontrolled descent
  • Flight/swim requirements gate access to vertical areas

6.4 Water and Underwater

  • Surface water: Requires swimming ability or a boat; higher movement cost
  • Deep water: Boat required, no swimming
  • Underwater: Requires water breathing ability; may have different exit rules, limited visibility
  • Currents: One-way exits representing river flow; rooms that push players downstream

6.5 Flying and Aerial

  • Rooms with sector type FLYING require flight ability to enter
  • Can create multi-layer maps (ground level, treetop level, sky level)
  • Flying creatures can traverse flying rooms as shortcuts over ground obstacles
  • Consider: can players see ground-level rooms from the air? (vertical scan)

6.6 Area Transitions

How areas connect to each other:

  • Direct exits: A room in area A has an exit leading to a room in area B
  • Portal/teleport transitions: Magical transport between distant areas
  • Overworld entry points: Walk to a coordinate on the overworld map to enter an area
  • Level-gated transitions: Area entrances that require minimum level or quest completion
  • One-way entries: Enter an area through a chute/fall but must find an alternate exit

CircleMUD zone design:

  • Each zone is a geographically coherent region, typically under 100 rooms
  • Large regions subdivided into multiple zones (e.g., Midgaard city + residential area)
  • Zones can define their own mobs, objects, shops, and reset behaviors

6.7 Secret and Hidden Exits

Types:

  • Hidden doors: Don’t appear in exit list; require search or examine to discover
  • Keyword doors: Require knowing the exact keyword (no abbreviations) to open
  • Lever/chain doors: Opened by interacting with an object in the room
  • Timed doors: Open based on in-game time, season, or moon phase
  • Spell-opened doors: Require casting a specific spell (knock, passwall)
  • Quest-gated exits: Appear only after completing a quest

Aardwolf exit flags:

  • hidden – Completely invisible, requires full keyword to interact
  • noscan – Invisible to scan command
  • nopass – Negates pass-through-door effects
  • pickproof – Cannot be picked or bashed open
  • Custom exits support custom enter/exit/char messages and up to 5 alternate command keywords

7. Technical Implementation

7.1 Room Data Structures

CircleMUD Room Definition (C struct):

room_index_data:
  - next_room pointer
  - people (character list)
  - contents (object list)
  - extra_descriptions
  - area pointer
  - exits[6] (one per direction: N/E/S/W/U/D)
  - name (string)
  - description (string)
  - vnum (integer)
  - room_flags (bitvector)
  - light_level (integer)
  - sector_type (integer 0-9)

CircleMUD Room File Format:

#<vnum>
<room name>~
<description>
~
<zone> <room_flags_bitvector> <sector_type>
D<direction 0-5>
<exit description>
~
<door keyword>~
<door_flag> <key_vnum> <destination_vnum>
E
<extra desc keywords>~
<extra description>
~
S

Room Flags (CircleMUD):

ValueFlagEffect
1DARKRoom is dark; requires light source
2DEATHDeath trap; character dies on entry
4NOMOBNPCs cannot enter
8INDOORSIndoor room
16PEACEFULNo violence allowed
32SOUNDPROOFShouts/gossips not heard
64NOTRACKTrack skill can’t path through
128NOMAGICAll magic fails
256TUNNELOne player at a time
512PRIVATENo teleport if 2+ people present
1024GODROOMImmortal-only access

Sector Types:

IDTypeNotes
0INSIDELow movement cost
1CITYStreets
2FIELDOpen terrain
3FORESTDense forest
4HILLSFoothills
5MOUNTAINSteep terrain, high movement cost
6WATER_SWIMSwimmable water
7WATER_NOSWIMRequires boat
8UNDERWATERRequires water breathing
9FLYINGRequires flight

Ranvier Room Definition (YAML):

- id: "entrance"
  title: "Cave Entrance"
  description: "A dark cave stretches before you."
  coordinates: [0, 0, 0]    # Optional [x, y, z]
  script: "entrance-script"  # Optional behavior script
  metadata:
    terrain: "underground"
  npcs:
    - id: "myarea:goblin"
      respawnChance: 50
      maxLoad: 3
  items:
    - id: "myarea:torch"
  exits:
    - direction: "north"
      roomId: "myarea:deep-cave"
      leaveMessage: "crawls northward into the darkness"
  doors:
    "myarea:outside":
      lockedBy: "myarea:rusty-key"
      locked: true
      closed: true

Key design insight from Ranvier: Exits can be both explicitly defined and inferred from coordinates. Room.getExits() returns both types, letting builders use whichever approach fits the area.

7.2 Pathfinding

BFS (Breadth-First Search):

  • Finds shortest path by hop count (unweighted)
  • Ideal when all exits have equal movement cost
  • Explores all rooms at distance N before distance N+1
  • Time complexity: O(V + E) where V = rooms, E = exits
  • Simple to implement; natural fit for room graphs

Dijkstra’s Algorithm:

  • Finds shortest path by total weight (weighted graph)
  • Required when rooms or exits have different movement costs (terrain, danger, preferences)
  • Uses a priority queue; always expands the cheapest unexplored node
  • Time complexity: O((V + E) log V) with a binary heap
  • Mudlet mapper and Evennia XYZGrid both use Dijkstra
  • Room weights in Mudlet: setRoomWeight(roomID, weight) – higher = more costly
  • Evennia: link weights default to 1; long visual link chains are averaged so #-# costs the same as #----#

A (A-Star):*

  • Dijkstra + heuristic estimate to goal
  • Only works if rooms have spatial coordinates (for distance estimation)
  • Faster than Dijkstra for coordinate-based worlds
  • Not applicable to pure room graphs without coordinates

Practical MUD pathfinding considerations:

  • Most MUDs use BFS or Dijkstra; A* is rare because many areas lack coordinates
  • Room flags affect pathfinding: AVOID rooms get high weights, BLOCK rooms are excluded
  • Special exits (portals, custom commands) must be included in the graph
  • One-way exits create directed edges; the reverse path may not exist
  • Locked doors may or may not be traversable depending on implementation
  • Performance: Evennia reports 500-step paths over 20,000 rooms in under 0.1 seconds with Dijkstra + caching

7.3 One-Way Exits

  • Created by defining an exit from room A to room B without a reciprocal exit from B to A
  • Common uses: chutes, falls, slides, river currents, trap doors, maze connections
  • Aardwolf mapper displays one-way passages as half-lines
  • TinTin++ #map link <direction> <room> (without both flag) creates one-way links
  • Pathfinding must treat the graph as directed; BFS/Dijkstra handle this natively
  • Client mappers need visual indicators so players know they can’t go back

7.4 Dynamic and Temporary Rooms

Dynamic rooms:

  • Rooms whose properties change based on game state (time of day, weather, quest progress)
  • Description, exits, or flags may change without the room being destroyed/recreated
  • Server-side scripts can modify room attributes on events

Temporary rooms:

  • Created at runtime and destroyed when no longer needed
  • Use cases: player housing, summoned pocket dimensions, combat arenas
  • Must be excluded from persistent maps or handled with volatile map markers
  • Client mappers need to handle rooms that may not exist on reconnect

7.5 Instanced Areas

Areas where each player or group gets their own private copy:

  • Same area definition, multiple simultaneous instances
  • Prevents player conflicts in quest areas
  • Room IDs must be dynamically generated or namespaced per instance
  • GMCP must communicate instance-specific room IDs to mappers
  • Procedural Realms uses automatic GMCP mapping with instanced zones and terrain-based room styling
  • After the instance closes, rooms are cleaned up and map data becomes stale

Implementation approaches:

  • Template area with prototype rooms; spawn copies with unique IDs per instance
  • Namespace room IDs: instance_42:room_301
  • Track instance lifecycle (creation, active, cleanup)
  • Coordinate with mapper: either don’t map instances, or use volatile/temporary map layers

7.6 Evennia XYZGrid – A Complete Reference Implementation

Worth studying as a modern, well-documented approach:

ASCII map definition:

+ 0 1 2 3 4
4 #-#---#
      |   |
3     #   #
      |
2 #-#-#
  |
1 #   #-#
  |     |
0 #-#---#
+ 0 1 2 3 4

Legend characters:

  • # – Room node
  • - | – Two-way horizontal/vertical links
  • / \ – Diagonal links
  • > < ^ v – One-way directional links
  • u d – Up/down links
  • t – Same-map teleporter (paired)
  • T – Cross-map transition node
  • I – Interrupt node (pathfinding checkpoint)
  • b – Blocked link (pathfinder avoids, exit still exists)
  • o – Router link (non-orthogonal connections)

Coordinate system:

  • Origin (0,0) at bottom-left
  • Each coordinate position occupies every-other character in the ASCII string
  • Half-coordinates (x.5) describe link positions between nodes
  • Z-coordinate is the map name/identifier

Performance:

  • Dijkstra pathfinding with cached results (pickled to disk)
  • 500-step paths across 20,000 rooms: < 0.1 seconds
  • Rerunning spawn updates existing rooms safely without duplicating

Sources

Room-Based vs Coordinate Systems

Automapping

Aardwolf

MUD Design and Implementation

Evennia

Discworld MUD

Other