|
|
||
Richard Bartle's PagesI often get letters or electronic mail from people asking me how to go about writing multi-user adventures. Although I can be vaguely helpful, rarely is there time to give a detailed tutorial. Unfortunately, neither is there anywhere I can point enthusiasts for them to read up on the subject. I'll assume you can guess from the above what the remainder of this article concerns!
The first thing to note is that writing multi-user adventure games isn't really all that difficult, once you've seen one and know roughly what goes on in them. So long as you're a competent programmer and you have enough time, without much trouble you can probably produce something which is, say, 70% as good as the top-notch professional games. That's because in MUAs most of the players' enjoyment comes from their interaction with other players, rather than from the complexities of the puzzles, or game world's carefully-crafted scenery. However, 70% isn't 100%, and merely having a simple 'fun' game is rarely enough. Making up the last 30% is where many first-time MUA programmers hit the limits of their designs, and suddenly realise that they should have done something completely different from the start. Luckily, a lot of these pitfalls can be avoided if programmers are made aware of potential problems, right at the outset. That's what I shall be attempting to do here, and in future articles. Finding out the cruel facts of good MUA-programming on your own might otherwise be a long and painful process (MUD has been written and rewritten from scratch four times over the years!).
All Adventure games can be looked on as database manipulation programs. The rooms, objects and creatures in the game are stored in the database, and the player issues commands which either query (eg. look, examine, inventory) or modify (eg. get, drop, go) that database. Functionally, therefore, Adventure game programs can be split into two parts: the front-end and the database manager. The front-end reads players' commands, and parses them into the formal request language which the database manager is programmed to understand and act upon. Any output is sent back to the front-end to be presented to the player. The first decision that MUA-programmers have to make is not the nature of the request language, but rather the relationship between the front-end and the database manager. There are two alternatives: synchronous and asynchronous. In a synchronous system, the front-end and database manager are separate entities. Players run the front-end simultaneously, in parallel (eg. on their own computers at home, or under a timesharing regime on a single, more powerful computer). When they issue a command, it is parsed and sent to the database manager. The database manager executes commands in the order in which they were received, and it will complete each command in its entirety before going on to the next. In an asynchronous approach, commands are not only parsed in parallel, but they are executed in parallel too. The idea is that most of the time the commands will be updating different parts of the database, so there is normally no interference between them. Only when two or more commands need to reference the same area is it necessary tolock one of them in, so that it has sole access to that section. For example, if two players try to pick up the same object, only one of them should end up carrying it. However, the get command normally comes in at least two parts: ensure that the object is in the room, and change its location from the room to the player who issued the get command. Without a software lock to make the two components of get indivisible, it would be possible for player A's get to check that the object was present, then for player B's get to do the same check and also the location change, and then player A's get to continue and do the location change too. Result: both players think they have the object, but where exactly it's to be found is anyone's guess! Most people writing a MUA for the first time choose the asynchronous method. Its primary advantage is that if one player issues a long command, it doesn't slow the game down for everyone else. For example, the magic spell where treasure might take some considerable time to list all the treasure in the game and report where it is; on a synchronous game there'd be no output for anyone until the search was complete. On an asynchronous game, only the person who issued the processor-intensive command would suffer for it. On the whole, though, the synchronous method is the better choice. Statistics gathered from MUD show that over 50% of the commands issued in a game are basic movement ones, N, NE, E etc. Therefore, so long as these are fast, your problems aren't going to be great. If the database is structured properly, cpu-buster commands can be eliminated entirely - where treasure is nowhere near as slow if an object's descriptor maintains a pointer to where that object is located (rather than having the program search through all the rooms every time someone does a where - that's slow!). Asynchronous implementations also suffer from some disadvantages which are not shared by the synchronous approach. Of these, the main one is that explicit locks in commands are fine only for simple databases: anything remotely complicated soon requires locks all over the place. |
|||
Copyright © 21st January 1999: aclapr89.htm |