"Java-MOO" Project Planning Document
The broad outlines of the project are to write an initial specification document for the re-implemention of the LambdaMOO environment under the following constraints:
1. Must be implemented in Java
2. MOO server
- backward compatible to earlier LambdaMOO databases
- online extensibility
- distributed (synchronized)
3. Code Control, version tracking
4. Development environment
- robust API
- tools for content engineers
- server-side interface specification capability
5. Instructor Support
6. A local-area network solution (authentication)
There are five units in the MUD specification:
Client: A Java applet which connects to the server and graphically represents the user's view of the simulated world.
Server: A Java application which is the engine that runs the simulated world, and communicates with the clients.
Object Library: An archive (JAR) of Java class definitions for all possible objects in the simulation. This is the "Physics" of the simulated universe. The JavaMOO package would come with a standard set of objects (Room, Exit, Player, etc.), which the developer would then extend.
Object Database: A database of all the objects that exist in the simulation. This is the "Matter" of the universe.
Resource Directory: A directory of media (art, music, movies, etc.) for use by the objects in the universe.
The client and resource directory should be made accessible to the general public via an http or ftp server, or some equivalent.
Development Procedure
One of the consequences of this design is that the MOO developer will no longer be able to define objects or change their definitions within a running MOO simulation. This is a limitation (feature) of the Java language, which doesn't allow classes to be redefined once they have been loaded. This consequence, though, is only a problem if the simulation requires the creation or modification of classes while running the simulation, as we would probably want to disallow global changes like class modification on a MOO server that is on line and in production. The development procedure would then be broken up into two parts.
First, a Java programmer would create whatever object classes were needed in the world to be simulated. He or she would do this by adding to or extending the standard object set that comes with JavaMOO. This object library would then be put onto the server host where the server can have access to it.
Second, content producers would log into the running server and start building the world using the object types that the programmer has created. These objects would get stored in the Object Database, and would define the starting state of the simulated world.
Obviously, these two steps can overlap quite a bit, but care must be taken to plan ahead and maintain compatibility from one version of the Object Library to the next, lest the Object Database be rendered obsolete. For example, if a programmer changes all the fields of an object, the server won’t know how to match the object in the database with the new class definition. What's missing, though, is a way to convert existing objects to their new class types when they are modified. This needs to be specified.
It would be possible, then, to upgrade the Object Library of a running, online server. The procedure would be the following:
1. The developer creates and debugs a new version of the Object Library.
2. The developer then places the new version of the library on the server host.
3. The administrator then tells the server that a new version of the Object Library is to be used.
4. The server then launches a new server, one which loads the new library.
5. The old server then migrates the currently connected clients to the new server on a different port.
6. Once all the connections have been migrated, the old server shuts down.
7. Once the old server shuts down, the new server then migrates its clients to the original port.
If all goes well, this procedure should go entirely unnoticed by the clients. Of course, maintaining compatibility between versions of the Object Library is paramount.
Object Database
There is a question as to how to store all the simulations objects and their states. One approach would be to use an out-of-the-box database solution, such as mySQL. Another is to simply store each object in its own file in some directory structure. Since we are talking about Java objects, we can use Serialization to stream the object information to any storage facility, whether it is a file or a SQL BLOB. The out-of-the-box approach has the advantage of already solving many of our issues for us. Plus the database would be directly accessible from the JavaMOO server using the Java Database Connection protocol (JDBC).
Client-Server Communication
One idea for effecting server changes from the client is to use Java's Remote Method Invocation (RMI). What this allows you to do is have the client request a proxy to an object that exists on the server. The client would then have what appears to be a real reference to a server object, as if that object were local to the client. The client could then call methods on the object, just as it would a local object. However, these method calls would get translated into messages that are transmitted to the server, and the server would then call those methods on the server object. This approach is very exciting and seems like it would be highly attractive to the client developer.
There are some drawbacks and some unknowns. First, it does not appear like this mechanism could be used to pass notification from the server to the client. This might have to happen via a traditional message passing method. Second, getting this system all up and running would require the learning of a good chunk of new technology. The benefits seem really great, though, so this should be further explored.
Distributed Servers
It seems very desirable to have more than one JavaMOO server running simultaneously to handle very large numbers of client connections. There is a problem, though, of synchronizing the servers so that we don't have branching versions of the Object Database. One (bad) approach to this problem is to have a master server and several slave servers, where all slave servers would need to get permission from the master server before any changes to objects are made. This is a classic bottleneck scenario, and would make things worse than the single server approach.
A second approach would be to have peer servers, but only allow any given object to be modified by a single server. If a user connected to server A wanted to change object X, and object X was assigned to server A, then the change would just happen and all other servers would receive notification of the change. If, however, object X was assigned to server B, then server A would pass the change request to server B. Server B would then be responsible for notifying the other servers.
There is a serious concern with this or any other distributed scenario, which is the problem of distributed object locking. As with any multi-threaded system, object locking will be required to maintain object sanity. On distributed servers, where different objects are being maintained on different servers, this locking must be done over the network. This is certainly doable, but some serious care must be taken.
Client Details
Another consequence of having a binary connection between the client and the server is that there will be no "text mode" like there is today. For clients to log in to the JavaMOO server, they will need to use a Java Applet client. This does not preclude the creation of a text-based client, and indeed there will be many users of JavaMOO who will want such a client.
There was also discussion about player-based security. MOO has a player-based security system that limits which players can manipulate which objects. It is possible to simply re-implement the existing MOO security system. But also bear in mind that a certain level of security can be established simply by limiting the capabilities of the client. In other words, if you don't want players deleting any rooms, you wouldn't put a "Delete Room" button in the client. There is always the possibility that a "Wizard" client could fall into the wrong hands, though, and so some level of player authentication and security are required.
Also, it is unknown what kind of security measures are provided for by RMI.
Distributed Servers, Part II
There are now two possibilities for distributing the server load. One, which was discussed previously, would allow multiple servers to run as peers, with each server being in charge of some mutually exclusive subset of database objects. Another twist is to allow the JavaMOO clients to be these peer servers, with the subset of objects for which they are responsible consisting of the player and his or her possessions. It's unclear how useful this would be, considering that the client would really only be responsible for a small subset of objects, while the server would still be in charge of the vast bulk of objects. Still, it seems to be the case that some client-to-client communication would be very useful for distributing server load.
Any client-to-client scenario calls for the client to establish connections with servers other than the applet host. This is an applet security violation, which requires a certificate to be overridden. We already know how to do this.
Multicasting was also discussed as a potentially desirable technology to employ for the server. Currently, multicasting relies on UDP, which does not guarantee delivery of messages, which does not make it useful for our purposes. However, there is currently under development a Reliable Multicasting Transport Protocol (RMTP) that might well suit our needs.
Backward Compatability Issues
Currently, backward compatibility with currently existing MOOs is envisioned as a conversion process that will read in LambdaMOO source and produce a translation into the new JavaMOO scheme. As the day went on, it became increasingly clear that translated JavaMOO games will be a lot uglier than games written in JavaMOO from start to finish. Plus, there seem to be a number of thorny issues associated with this translation.
The primary source of trouble with translation is the fundamental differences in handling objects and classes between LambdaMOO and Java. Some of these are defined below.
LambdaMOO
/Java
Class objects are also instances of the defined class. / Class objects are distinct from instances of that class.Both classes and instances can be subclasses. / Only classes can be subclassed.
A property which is "clear" will reflect the value of that property in the superclass. / There is no "clear" value, and it doesn't make sense to reflect values in the parent, since the parent is a class and has no instance values.
Another issue: task scheduling.
This is a complicated problem, but a solution is highly desirable if not mandatory. I recommend that this be studied, explored and tested thoroughly, and that a plan be written up which would describe the exact process for performing the translation from LambdaMOO to JavaMOO.
Core Object Library Architecture
There was general agreement about the design of the Core Object Library. There would be a MOObject root object that would look something like this:
public class MOObject
{
protected String name;
protected Container location;
protected Point position;
protected Dimension size;
protected Vector contents;
protected Player owner;
protected String imageURL;
public void action( Player p ) {};
[...]
}
The idea is that all MOObjects have a name, owner, location, position, size, and image URL. Also, all objects would be capable of being containers, but there would be language support for enforcing which objects would be containers and which wouldn't. The could be done through the use of an empty interface, like so:
public interface Container {}
All methods dealing with containers would take Containers as arguments. Then, only those classes which implement Container would be accepted in those argument positions. This could serve as a model for other types of objects as well.
The primary goal of the Core Object Library is to provide a basic model of multiplayer database access and communication and simulation building and running. It is also important that these capabilities are replaceable by the programmer. For example, the Room metaphor will define the scope of a player: players will only see those objects which are in the player’s current room. However, one can imagine different models of scope, which can be dependent on objects of interest or Euclidian distance. While providing basic functionality for the room metaphor of player scope, the library should allow for the implementation of any of these other scope metaphors. One can imagine an online object library that holds class definitions (or collections of classes) which add new functionality to the core object library. These objects can then be downloaded and incorporated into the MOO by the game programmer to provide whatever functionality he or she deems necessary.
We might want to include an alternative scope metaphor, such as Brad’s VCell scope implementation, in the Core Library.
Note that, like containing objects, even though the root object has certain capabilities, programmers need not use them if they don't want to. For example, all MOObjects may have a Point location, but programmers are welcome to subclass this class and provide a more sophisticated location representation for, say, 3-dimentional presentations.