Adventurers Club Ltd. Member's Dossier, June, 1987 Hat

Richard Bartle's Pages

Since this is a double issue, and I am thus allowed to rant on for twice the recommended dose, I thought I'd say something constructive on the sobject of Multi-User Adventures, namely how to write them. Now before you plug in your Commodore 64 and poise yourself for action, I'd better warn you that this isn't going to be down at the nitty-gritty level of the "Create Your own Adventures" series, otherwise I'd need two hundred pages rather than the two I've got. Rather,it'll be at a more abstract level, going through some of the possible architectures.

The first thing to note is that you don't write ANY adventure these days in a normal programming language such as BASIC (hmm, did I say normal?) or C. What you do is design a language specifically for writing MUAs - MUD's is called MUDDLE. You then write an interpreter for your language. The reason you do it this way is so that if you want to transfer the system to another machine, you "merely" have to rewrite the interpreter, not the whole program. Also, if you decide to write other adventures, then you automatically get usable versions for free on all the machines for which you have an interpreter for your language. If the interpreter is writtenin something reasonably portable, you may be able to port over the whole system in a couple of days!

The interpreter can be split into two parts, the front-end/parser, and the database management system. The former reads in user input, parses it into a command format, which the latter uses to modify the state of the world and pass a message back to the front-end, which can then print it out at the user.

What kind of hardware does such a system need? Obviously the user must have some hardware in order to access the game, so as a first possibility we could say that all processing is to be done on the users' machines. That won't work for two reasons: the telephone lines are too slow for the massive amount of communication necessary, and it's too easy for malicious users to wreck the whole system (eg. by writing programs that send false data to other players).

The next option is to have the parsing done on the user's machine, with the database residing on a remote system. Users type a command, which their own machine parses, and up the telephone line is sent the database update request (which is much more succinct than English, and thus is transmitted quicker). This is an interesting option, but it has its disadvantages. The main one is that you need to have a parser written for all machines likely to be used, which means investing some effort. The second is that the home computer would need access to the vocabulary. In MUAs, this changes all the time, eg. when a new object is added. Even if the main vocabulary were available on disc, there would still be a fair amount of traffic on the comms line whenever a new player joined the game. This architecture remains fairly attractive, however, not in the least because you can make more money by selling the front-end packages to prospective new players!

The safest approach is to manage all the game yourself. Users send the whole of their command using normal comms protocols to the host system, where the parsing and command interpretation is carried out. That way, the risk of malevolent havoc-wreaking is reduced, and vocabulary changes can be carried out painlessly. There are a number of possible ways of arranging even this scenario, though: autonomous micros; master/slave micros; asynchronous single machine; synchronous single machine.

Autonomous micros is where you link a heap of processors together on a network. All input ports are tied to a machine (although some machines may be able to handle several players). A user's commands are parsed on the micro to which they have been assigned. All micros store parts of the game, and manage those chunks themselves. This is a neat idea, but is messy. Parsing commands in parallel is qood, it speeds the game up, but the changes to the database happen so rapidly that micros would spend much of their time telling each other about the modifications to their particular section (whether a geographical area, or a particular class of commands, eg. spells). The system is also vulnerable to hardware errors - if one machine goes down, the whole game collapses. There are ways to cover this, but they require massive redundancy of information. It is also hard to keep coherent logs of play for good management purposes.

The master/slave architecture is probably the ideal one if you're thinking of setting up a MUA yourself. Here, one micro (or mini) handles the database task, the others just parse. Parsing is computationally expensive, but this isn't significant if it can be done on several machines at once. Users are assigned a micro on the network when they dial in, which does all their front-end processing. It communicates with the database machine over the network, and this takes queues of update requests, executes them, and informs the relevant micros of any appropriate output. The system is comparatively inexpensive, modular, and can be extended as and when necessary.

Rather than buying all this equipment, though, the cheapest solution is to find someone who has it already and doesn't use it at the times you want to (this is the solution employed by MUD). This will invariably be a mini or a mainframe, stand-alone, so the game must be written to run under a timesharing operating system. In an asynchronous approach, there is one shared segment of memory and the parser and database processes are combined. When the parser has parsed a command, it makes changes to the database in shared memory. The system doesn't screw up because any code which could possibly cause this is "locked". This means that database tasks hang about until some other player's database task which was doing some game updating has finished the tricky bit and allowed others to use it. MUD1 uses this approach, and it works reasonably well most of the time. In particular, since database updates can go on simultaneously it means commands that need lots of processing, eg. WHERE ALL, will not slow the game down for someone else. The disavantage is that if the program crashes in the wrong place, the whole game can freeze up

MUD2 uses a synchronous approach. Here, the database update task sits about all the time on its own. Players are assigned a front-end process, which parses their commands and then tells the database manager what to do. It keeps a queue of requests and handles them one at a time so there is no danger of one player's command interfering with another's, although slow commands will affect the game's whole performance. The main reason for doing it this way is that it's fairly easy to transfer it to a master/slave architecture if desired, and since the database language doesn't need locking primitives, the programmer needn't worry about it.

So these are the architectures available to MUAs. A lot more can be said on the subject, but not here! This is one of the few aspects of MUAs which I have actually written up as an academic paper, and if you're sufficiently interested I can send you a copy if you write to me at the Dept. of Computing Science, Essex University, CO4 3SQ and ask for one.


Copyright © Richard A. Bartle (richard@mud.co.uk)
21st January 1999: acljun87.htm