"Java-MOO" Project Planning Document

advertisement
"Java-MOO" Project Planning Document
The broad outlines of the project are to write an initial specification document for the reimplemention 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
Class objects are also instances of
the defined class.
Both classes and instances can be
subclasses.
A property which is "clear" will
reflect the value of that property in
the superclass.
Java
Class objects are distinct from
instances of that class.
Only classes can be subclassed.
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
protected Container
protected Point
protected Dimension
protected Vector
protected Player
protected String
name;
location;
position;
size;
contents;
owner;
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.
The interface and implementation spec should be completed before implementation
starts.
Initial Client Design
The JavaMOO package should come with three basic clients (or one client with three
modes). All three clients will provide a graphical user interface to support their
functionality. These clients are:
Wizard Client. This client allows for the administration of the MOO as a whole. This
would include interfaces for account management, database management, etc. This is a
very powerful client and should only be made accessible to the most trusted users.
Builder Client: This client would be used for world building. It would have an interface for
the creation of rooms, objects, and NPCs. It would have an interface for connection
rooms to each other. It would also allow for the application of art to objects, including
rooms, objects, NPCs, etc. This client should be built to support any content provision.
User Client: This is a very basic user client for the testing of the MOO. The user client
should be thought of as the equivalent of text mode for non-privileged users. Users
would be able to use this client to move around the MOO, talk to other players, etc.
Clearly, most game builders will want to build their own specific interface, and the client
library will be provided and documented to allow such a customization. The game
builders could then create their own client with their own interface and provide this client
on an http server.
One such custom client could be the much-talked-about text-based client. This client
would include a text parser like the one that exists in the current MOO, which would
translate between English and the client/server communication protocol which all clients
would use.
Client/Server Communication
For the purposes of clarity, a message sent from the client to the server will be called a
“command,” while a message sent from the server to the client will be called an “event.”
Commands inform the server when the client has performed an action, and servers will
keep the clients updated as to the state of the world by issuing events.
As previously stated, there is a desire to use RMI for sending commands. But we don’t
know enough about RMI to create a spec that uses it, and it is currently under study.
Without RMI, there would be a simple client/server communication protocol based on
serialized objects.
When the user performs an action on a client that changes the state of an object, the
client issues a command to the server by creating a Command object and sending it to
the server via an open TCP/IP connection. The command that is issued will be defined
on the object in the server, and will be transmitted to the client along with all of the other
information about the object (position, owner, image, etc.). Once the server receives the
command, it will look up the command in a Master Command Table (MCT). This table
will contain the ID of the command, the method to be invoked by the command on the
server, and a privilege description. The privilege description will be checked against the
user to see if the user has authorization to issue the command. If the command is
authorized, the appropriate method is invoked.
This simple command-based security scheme (thanks to John Bauer) will be a first level
security check to make sure that nobody using a pirated client can issue destructive
commands.
When the server determines that a player should receive an update, it creates an Event
object and sends it to the client via the open TCP/IP connection. The client will then
receive the event and invoke the appropriate method as determined by a lookup table on
the server. Event reception should be handled asynchronously, so that extensive client
operations will not block the reception of events.
Security Issues
In our discussion, the use of a security system in the JavaMOO has been talked about
as serving two purposes: protection from the malicious, and protection from programmer
error. This document refers to the second purpose as “sanity checking.” We feel that
some degree of sanity checking is important, and must be implemented to avoid the
inevitable occurrence of a buggy client or server creating a database inconsistency.
While sanity checking can be a great tool in creating MOO games, the programmer is
fully capable of obviating any sanity checking scheme we could implement, and that’s
ok. Sanity checking should be a safety net, not a straight jacket. The details of this
sanity checking, though, are currently unspecified, and will be part of the MOO Database
Access Spec.
But on to security. Security issues are meant to protect the MOO, specifically the MOO
Database contents, from malicious people. These people can be MOO users or MOO
programmers. In the world of LambdaMOO, programmers, content providers and
players all occupy the same interface. As a consequence, LambdaMOO has a
complicated protection scheme to give the right people access to the right things.
However, JavaMOO has a much different architecture, which gives programmers
absolute power and clients (including users and content providers) virtually no power (or
as much power as the programmers give them). While this simplifies the problem of
malicious clients (see the simple command security system described above), it severely
complicates the problem of protecting the MOO from malicious programmers.
It is our belief that under most circumstances, this will not be a problem, since the
programming team will usually be working together and under each other’s supervision.
This system was designed to give programmers as much power over the MOO as
possible, including the power to mess things up royally.
But in the current LambdaMOO implementation, there is also the provision for having
multiple, uncoordinated and untrusted programmers working on the MOO. Without a
security provision on the programmer side of things, this kind of community
programming system is untenable. The trick here is to keep programmers from writing
code that could screw up the database, while still allowing for the absolute power to
trusted programmers. While the previously described methods (command
authentication, sanity checking) will go some way in protecting the database, all these
are designed to be obviated by the knowing programmer, and will not suffice as a
security system for community programming.
This is very complicated issue and must be specified fully before implementation can
begin. There are many tools that have been suggested to aid in the implementation of a
community programming security scheme, including the use of the Java Security
Manager, host file protections, etc. While I am fully confident that this problem is
solvable, I want to strongly urge that we make sure the cure does not kill the patient. It
would be very easy for a security implementation to render the JavaMOO so
complicated and unwieldy as to be nearly unusable. At the very least, whatever security
scheme is decided upon should be optional, so that developers who are using the
trusted programmer team model of development will not be unduly burdened. In
addition, the benefits of such a security scheme must be weighed against the costs of
implementing the scheme in terms of time, resources, technology and usability. It may
be the case that the number of people who would need a community development
security scheme would be small compared to the number of man-hours it takes to
implement the scheme.
Implementation
Implementation will take place in four phases (0-3). Phase 0 will be the completion of
the design specs. Phase 1 will be creating a reliable core. Phase 2 will be building on
this core and fleshing out all the features. Phase 3 will be the implementation of a game,
which will iron out all the wrinkles.
Phase 0:
MOO Database Access Spec
Distributed Server Spec
Legacy Server Translation Spec
Community Development Security Spec
Client Interface and Design Spec
Phase 1:
Start with server
Mini-core library
Loading library is trivial
Work out details with database access
This includes the local caching scheme.
Whatever security system will be used for the first pass, will likely overlap somewhat with
database implementation.
Minimal client that can issue commands and accept events.
Implement client/server communication on server side.
Maybe a little load testing at this point to check for bottlenecks.
Phase 2:
At this point, progress can be made on all fronts simultaneously.
The server should be fleshed out and stabilized.
The basic clients should be created and beautified.
The core object library should be designed and implemented.
Simultaneous with all this is the implementation of the legacy server translator.
Phase 3:
Once most of the details have been pounded out, phase 3 would be the implementation
of a game on the new system. This will bring out all of the flaws in the entire system,
and make the architecture solid and robust.
Download