Imaginary Realities Imaginary Realities About Search Glossary
What's new? Index :)
Select issue:
Join a discussion Resources
     

All Mudlists Are Not Created Equal
- Andrew Cowan
Who are you?
- Michael A. Hartman (Aristotle@Threshold)
Level vs Non-Level
- Zane T. Insane
Wilderness Systems for Muds
- Alex Kallend
Distance tells
- Amanda Carlston
So, you want to code a mud?
- John Patrick

Letters to the editor

Enter your email to be informed when this site is updated.


Comment on articles

Letter 1
Contact editors

   

Wilderness Systems for Muds

by Alex Kallend

Most muds use a room-based world system. This works fine for a static world, but has a few drawbacks. I write this article from a Diku background, but the concepts should hold for any room-based world.

First, in any level-based mud, the use of a static room-based world will lead to growing pains as the mud adds areas. If the mud never adds new areas, the areas can be placed so that players can access the lower level zones without needing to travel through high level zones to get there. But, as new zones are added, you run into the situation where new low-level zones will only fit behind existing high level zones. This means those zones will not be played. Low level characters will die to the high level mobs en-route, and high level players who can get there will find that the zones hold nothing for them.
Wilderness area

A nice mountain wilderness area. Can you see the quest?

Secondly, there is a lack of realism. While there may be a large forest of 100 rooms, what if the players choose to walk off the path. What, other than mechanics, stops a player from venturing across the great desert?

In order to address these issues, the idea of a wilderness system originated. The wilderness is generally a large grid of rooms, to which the other zones of the mud are linked. If done correctly, this will alleviate both the above problems, but there are a number of technical difficulties introduced by such a system.

Before attempting to implement a wilderness system, a firm grasp of the goals of the system should exist. The wilderness is not primarily intended as a place to explore, or adventure. It is going to serve as a connection board, where zones can be placed. It isn't going to be an example of excellent writing. To write the number of rooms that a wilderness will occupy would take far too much time, compared to how long players will ideally spend in it. That doesn't mean it won't add detail to the game, but the detail is added on a much larger scale. The wilderness should, ideally, have a minimal impact on game resource consumption. It should also be large enough to impart a believable game scale on the world. It should be fairly transparent, both to the code design, and the players on the mud. (This doesn't mean that players should not know they're in the wilderness, but they should not lose the ability to use most commands that work in other places)

Starting with these goals, the first conclusion is that the wilderness should consist of dynamically created rooms. Trying to create the millions of rooms utilized by a believable wilderness (a 1000x1000 square will result in one million rooms) in a static form will consume far more memory that most muds want to consider. To create rooms dynamically requires that you know something about the rooms to be created. I've found that knowing the terrain type, and whether there is a road or river present suffices.

This can easily be represented with one byte-per-room, using the low-order nibble for the terrain type (allowing up to 16), and the high order nibble for flags, such as road, river, giving 4 terrain modifiers. The one million rooms now can be generated from one megabyte of data. This can be read in from a file that defines a portion of the wilderness in terms of sectors.

With 'F' meaning forest, 'D' meaning desert, 'H' meaning hill, 'M' as mountain, and lowercase letters meaning there is a road present, the following block shows how a section of wilderness can be defined in a file:

FFFHHMMmhdDDD
FFFFHmmHHDddd
FFFhhHMMHDDDD
FFfDHMMMHHDDD
FfFFHMMHHDDDD
fFFFHHHMMDDDD

Partioning the files into smaller-than-the-whole-world segments does wonders for file access time, and allows you to cache the world map in memory to reduce the memory overhead even further (I fit 12 million rooms of data into 40k run-time memory.)

The next two questions to address are how to generate and destroy the rooms, and when to generate and destroy the rooms.

The most obvious answer dealing with when to generate the rooms is when someone goes there, but I've found that there are a number of things that most muds like to know about the rooms surrounding the one the player is currently in. Putting a wrapper function on the access of exits to a room handles this well. For any mud where exits are displayed upon a character entering a room, this means that 4 rooms are generated for each move. Destroying rooms should be a function of when the rooms were last used. Keeping a time stamp on the rooms indicating when they were last accessed will allow the least-recently-used room to be destroyed when a new room is needed. I use a dynamically sized array of rooms that grows if more people are needing wilderness rooms, to make sure that there is no risk of removing a room that is occupied.

This leaves the question of how to generate rooms. Each room in the wilderness should have a coordinate. The room generation can be broken down into four stages.

First is generating the description for the room. A room description can be either text based, or an ASCII map (or a text-based description with a map command). For a text description, features and terrain types should be emphasized. The most important feature in the wilderness is the proximity of zones linked nearby, so these should definitely be described. The terrain type that makes up the room being described should be described, and terrains that differ from it should be mentioned. This, if scanning 2 or 3 rooms out in each direction, will lead to descriptions between 2 and 5 lines in length. A sample, based on the center of the above file might be:

You are on a mountain. A desert lies to the east. Some hills lie nearby to the west. A forest stands in the distance to the west.

These descriptions aren't going to compete with anything a human builder may write, but adequately describe the room on a macro scale, and give a consistent look to a mud that uses text descriptions. As players may use the text descriptions of an area as landmarks, introducing random factors into text generation is not wise. Rather than use a random generator, generate a value based on the coordinates of the room, so that the same coordinate room always looks the same.

In addition, the use of dynamic tags to alter a few key sentences (as described in last month's article 'Dynamic Room Descriptions') will add another level of detail to these generated rooms.

ASCII maps are easier to generate than text descriptions, as you can essentially choose one symbol per terrain type, and overlay any roads. Determining the best ASCII symbol for a particular subsection of the wilderness can prove challenging however, as can adding visibility ratings based on weather and terrain heights, but that's another matter.

A sample ASCII map (that looks better colorized):

       "         -------KEY-------
    """""""      | * A City/Area |
   ---""""""     | . Plains      |
   """|--|""     | O Water       |
   """"""|""     | " Swamp       |
  """""X"|"""    | + Road/River  |
   """"*""\"     | X You         |
   """*""""\     -----------------
   """""""""
    """""""
       "

After generating the text/map for the room, it needs exits to access the surrounding wilderness rooms. As each room has a coordinate, the coordinates of the surrounding rooms are easy to generate. Expanding the exit structure to allow for exits leading to specific wilderness coordinates will handle this, and is also useful in linking areas into the wilderness. As the wilderness rooms are generated as exits that lead to them are accessed, this fits well into the overall scheme.

Adding random inhabitants to the wilderness, and checking any persistent information are the final two stages. Random inhabitants should be somewhat rare (the wilderness is not intended for leveling in), and of relatively low level (because we want the wilderness to be useful for adding new zones without worrying about access to them being blocked by high level inhabitants). When a room is destroyed, its contents can be stored to disk, based on the coordinates of the room, for later retrieval. This information is read from disk and put in the rooms when they are recreated. Neither of these two steps are truly necessary, but serve to flesh out the world.

Linking zones into the wilderness is a matter of assigning the zone a coordinate. When a wilderness room is generated, it scans the area list for any areas located within its visual range, and includes them in the descriptions and exits.

Some potential problems with this system include:

Overuse

If you use a fixed number of rooms, you can encounter thrashing, as too many rooms need to be generated each pulse. This can happen if you have mobs in the wilderness trying to move around. While it decreases the realism of the wilderness, I disallow any NPC's to move through a wilderness exit of their own volition. Likewise, any path-completion algorithms will likely need to account for the wilderness, as they will certainly access many rooms in a very short period of time. (tracking through the wilderness is either not allowed, or based on coordinates)

Size and Navigability

A large wilderness may be difficult for players to traverse. Without some idea of which direction them must travel to arrive at a given destination, a large grid is far too encompassing to be traveled easily. Adding some form of navigation skill which gives the general direction to a named area solves this.

Saving/Loading

Some method of making sure the rooms that players save from are present when they log back on, and are maintained as present, even if not occupied, while the player types their password, and does other login stuff.

Some ambiguities

A zone may have multiple exits that lead into the wilderness, and yet only one entrance from any given direction. This can lead to some exits not returning to where they came from. To avoid this, using only one exit from a zone will work, but will result in the inability to walk off the path at any location. This is sort of a compromise in the system that must be made.

Some other benefits and uses that can be derived from a wilderness system:

Quests

Automated quests into the wilderness, with the task of defeating a mobile only found there, or finding an item placed there, can be more challenging than a similar quest in a defined zone.

Raw Materials

The wilderness can be used as a source of raw materials for player run economies. Mining, lumber jacking, and farming come to mind.

Defined World

With the wilderness map, you are actually drawing a full map, not creating a path of rooms. This leads to a much better world definition, where players know how far inland a town is, and have a consistent scale to measure distances in.

The wilderness system Lensmoor uses consists of 3000x2000 ground rooms, plus the air over each, that wraps from west to east, thereby making a cylindrical world of twelve million rooms. Certain enterprising players have made it their goal to map the world, and one has successfully circumnavigated the world. Besides being used to link areas, it fuels the resource generation for the player crafts.