Fall Semester 2002


RMI Notes Extra: A Multi-User Domain

1. A Multi-User Domain, or MUD, is a program (a server) that allows multiple people (clients) to interact with each other and with a shared virtual environment. The environment is typically a series of rooms or places linked to each other by various exits. Each room or place has a textual description that serves as the backdrop and sets the tone for the interactions between users. Many early MUDs were set in dungeons, with place descriptions reflecting the dark, underground nature of that imaginary environment. In fact, the MUD acronym originally stood for "Multi-User Dungeon". Some MUDs serve primarily as chat rooms for their clients, while others have more of the flavor of old-style adventure games, where the focus is on exploring the environment and problem solving. Others are exercises in creativity and group dynamics, allowing users to add new places and items to the MUD.

The next 5 examples show classes and interfaces used to define a simple user-extensible MUD system. A program like this MUD example clearly demonstrates how the RMI programming paradigm transcends the client/server model. As we'll see. MudServer and MudPlace are server objects that create the MUD environment within which users interact. But at the same time, each user within the MUD is represented by a MudPerson remote object that acts as a server when interacting with other users. Rather than having a single server and a set of clients, then, this system is really a distributed network of remote objects, all communicating with each other. Which objects are servers and which are clients really depends on your point of view.

In order to understand the MUD system, an overview of its architecture is useful. The MudServer class is a simple remote object (and standalone server program) that defines the entrance to a MUD and keeps track of the names of all places within a MUD. Despite its name, the MudServer object does not provide the services that that most users think of as "the MUD". That is the job of the MudPlace class.

Each MudPlace object represents a single place within the MUD. Each place has a name, a description, and lists of the items in the place, all of the people (users) currently in that place, all of the exits from the place, and the other places to which those exits lead. An exit may lead to an adjoining MudPlace on the same server, or it may lead to a MudPlace object in a different MUD on a different server altogether. Thus, the MUD environment that a user interacts with is really a network of MudPlace objects. It is the descriptions of places and items, and the complexity of the linkages between places, that give the MUD the richness that make it interesting to a user.

The users, or people, in a MUD are represented by MudPerson objects. MudPerson is a remote object that defines two methods. One method returns a description of the person (i.e., what other people see when they look at this person) and the other method delivers a message to the person (or to the user that the MudPerson represents). These methods allow users to look at each other and to talk to each other. When two users run into each other in a given MudPlace and begin to talk to each other, the MudPlace and the server on which the MUD is running are no longer relevant - the two MudPerson objects can communicate directly with each other through the power of RMI.

The examples that follow are long and somewhat complex, but are worth studying carefully. Given the complexity of the MUD system being developed, however, the classes and interfaces defined below are actually surprisingly simple. As you'll see, remote method invocation techniques are very powerful in systems like this one.

2. Remote MUD Interfaces

Example One (Mud.java) is a Mud class that serves as a placeholder for nested classes and interfaces (and one constant) used by the rest of the MUD system. Most importantly, Mud defines three Remote interfaces: RemoteMudServer, RemoteMudPerson, and RemoteMudPlace. These define the remote methods that are implemented by the MudServer, MudPerson, and MudPlace objects, respectively.

3. The MUD Server

Example Two (MudServer.java) shows the MudServer class. This class is a standalone program that starts a MUD running; it also provides the implementation of the RemoteMudServer interface. As noted above, a MudServer object merely serves as the entrance to a MUD: it is not the MUD itself. Therefore, this is a fairly simple class. One of its most interesting features is the use of the serialization classes of java.io and the compression classes of java.util.zip to save the state of the MUD so it can be restored later.

4. The MUDPlace class

Example Three (MudPlace.java) is the MudPlace class that implements the RemoteMudPlace interface and acts as a server for a single place or room within the MUD. It is this class that holds the description of a place and maintains the lists of the people and items in a place and the exits from a place. This is a long class (and so is A348) but many of the remote methods it defines have simple or even trivial implementations. The go(), createPlace(), and linkTo() methods are among the more complex and interesting methods; they manage the network of connections between MudPlace objects.

Note that the MudPlace is Serializable, so that a MudPlace (and all places it is connected to) can be serialized along with the MudServer that refers to them. However, the names and people fields are declared transient, so they are not serialized along with the place.

4. The MUDPerson class

Example Four (MudPerson.java) shows the MudPerson class. This is the simplest of the remote objects in the MUD system. It implements the two remote methods defined by the RemoteMudPerson interface and also defines a few non-remote methods used by the MudClient class of Example Five (following shortly). The remote methods are quite simple: one simply returns a description string to the caller and the other writes a message to a stream where the user can see it.

5. A MUD Client

Example Five (MudClient.java) is a client program for the MUD system we've developed in the previous examples. It uses the Naming.lookup() method to look up the RemoteMudServer object that represents a named MUD on a specified host. The program then calls getEntrance() or getNamedPlace() method of this RemoteMudServer object to obtain an initial MudPlace into which to insert the user. Next, the program asks the user for a name and description of the MudPerson that will represent her in the MUD, creates a MudPerson object with that name and description, and then places it in the initial RemoteMudPlace. Finally, the program enters a loop that prompts the user to enter a command and processes the command. Most of the commands that this client supports simply invoke one of the remote methods of the RemoteMudPlace that represents the user's current location in the MUD. The end of the command loop consists of a number of catch clauses that handle the large number of things that can go wrong.

6. Summary

Here's how you compile and start the MUD server:

frilled.cs.indiana.edu%pwd
/nfs/grouchy/home/user2/www/classes/a348-dger/fall2002/notes/mud
frilled.cs.indiana.edu%ls -l
total 55
-rw-r--r--   1 dgerman  faculty      7346 Dec  5 00:30 Mud.java
-rw-r--r--   1 dgerman  faculty     20816 Dec  5 00:31 MudClient.java
-rw-r--r--   1 dgerman  faculty      1665 Dec  5 00:31 MudPerson.java
-rw-r--r--   1 dgerman  faculty     18322 Dec  5 00:32 MudPlace.java
-rw-r--r--   1 dgerman  faculty      6009 Dec  5 00:32 MudServer.java
frilled.cs.indiana.edu%javac -d . *.java
frilled.cs.indiana.edu%ls -l 
total 56
-rw-r--r--   1 dgerman  faculty      7346 Dec  5 00:30 Mud.java
-rw-r--r--   1 dgerman  faculty     20816 Dec  5 00:31 MudClient.java
-rw-r--r--   1 dgerman  faculty      1665 Dec  5 00:31 MudPerson.java
-rw-r--r--   1 dgerman  faculty     18322 Dec  5 00:32 MudPlace.java
-rw-r--r--   1 dgerman  faculty      6009 Dec  5 00:32 MudServer.java
drwx------   3 dgerman  faculty       512 Dec  5 11:08 a348
frilled.cs.indiana.edu%du -a a348
1	a348/mudExample/Mud$RemoteMudServer.class
1	a348/mudExample/Mud$RemoteMudPerson.class
3	a348/mudExample/Mud$RemoteMudPlace.class
1	a348/mudExample/Mud$MudException.class
1	a348/mudExample/Mud$NotThere.class
1	a348/mudExample/Mud$AlreadyThere.class
1	a348/mudExample/Mud$NoSuchThing.class
1	a348/mudExample/Mud$NoSuchPerson.class
1	a348/mudExample/Mud$NoSuchExit.class
1	a348/mudExample/Mud$NoSuchPlace.class
1	a348/mudExample/Mud$ExitAlreadyExists.class
1	a348/mudExample/Mud$PlaceAlreadyExists.class
1	a348/mudExample/Mud$LinkFailed.class
1	a348/mudExample/Mud$BadPassword.class
2	a348/mudExample/Mud.class
10	a348/mudExample/MudClient.class
2	a348/mudExample/MudPerson.class
2	a348/mudExample/MudPlace$1.class
8	a348/mudExample/MudPlace.class
4	a348/mudExample/MudServer.class
45	a348/mudExample
46	a348
frilled.cs.indiana.edu%rmic a348.mudExample.MudPerson
frilled.cs.indiana.edu%rmic a348.mudExample.MudPlace
frilled.cs.indiana.edu%rmic a348.mudExample.MudServer
frilled.cs.indiana.edu%hostname
frilled.cs.indiana.edu
frilled.cs.indiana.edu%rmiregistry &
[3] 17188
frilled.cs.indiana.edu%java a348.mudExample.MudServer
java.lang.ArrayIndexOutOfBoundsException: 0
Usage: java MudServer 
   or: java MudServer    
frilled.cs.indiana.edu%java a348.mudExample.MudServer "Lindley Hall" a348AG LH102 "lecture hall with 102 seats and a projector"
java.net.MalformedURLException: invalid URL string: a348.mudExample.Mud.Lindley Hall
Usage: java MudServer 
   or: java MudServer    
frilled.cs.indiana.edu%java a348.mudExample.MudServer "Lindley_Hall" a348AG LH102 "lecture hall with 102 seats and a projector" 


So now the server is running.

In class we will show how one can connect to the server and play.

tucotuco.cs.indiana.edu% cd /l/www/classes/a348
cdtucotuco.cs.indiana.edu%  fall2002
tucotuco.cs.indiana.edu% cd notes
tucotuco.cs.indiana.edu% cd mud
tucotuco.cs.indiana.edu% java a348.mudExample.MudClient frilled.cs.indiana.edu "Lindley_Hall"
Welcome to Lindley_Hall
Enter your name: Larry Bird
Please describe what people see when they look at you:
You can enter multiple lines.  End with a '.' on a line by itself.
Or enter a '<<' followed by a filename
A man with with a suitcase.                   
. 
You are in: LH102 of the Mud: Lindley_Hall
lecture hall with 102 seats and a projector
Things here: 
People here: Larry Bird
Exits are: 
Lindley_Hall.LH102> help  
Commands are:
look: Look around
examine <thing>: examine the named thing in more detail
describe <person>: describe the named person
go <direction>: go in the named direction (i.e. a named exit)
say <message>: say something to everyone
do <message>: tell everyone that you are doing something
talk <person>: talk to one person.  Will prompt for message
change: change how you are described.  Will prompt for input
create <thing>: create a new thing.  Prompts for description 
destroy <thing>: destroy a thing.
open <direction>: create an adjoining place. Prompts for input
close <direction>: close an exit from this place.
link <direction>: create an exit to an existing place,
     perhaps on another server.  Will prompt for input.
dump <filename>: save server state.  Prompts for password
quit: leave the Mud
help: display this message
Lindley_Hall.LH102> 
Any number of concurrent users are allowed.


Last updated: Dec 4, 2002 by Adrian German for A348/A548