January 30, 1996
There are many possible architectures for building multi-user worlds. Some systems will be based on a client server model, others will be based on a peer to peer model possibly using multicast communication, still others will find some middle ground.
One of the goals of the Moving Worlds proposal is to provide the functionality needed to build these different models without dictating which approach should be used. All of the likely models for multi-user worlds would use Moving Worlds features in the same way.
This document highlights the common requirements for all multi-user worlds and points out the parts of the Moving Worlds proposal that address those requirements. An example demonstrates one possible implementation of a multi-user world.
There are two aspects to a shared multi-user world:
The second aspect is a special case of the first in that a special object -- the user representation, or avatar -- is shared among browsers viewing the world. This document discusses the specific case of shared avatars and then generalizes the functionality to support any shared item.
The approach is the same for both the specific and general cases. One or more Script nodes are put into the world, each specifying either a general-purpose or an application-specific applet which carries out the network functionality. For each node containing shared information, either Routes are added between the appropriate events and the Script node, or the shared node itself is passed to the Script (which can then get and set the node's fields). The former approach should be used when information is needed every time the relevant node changes; the latter should be used when shared information is only needed occasionally.
To support shared multi-user worlds, the following basics are needed:
The browser must make available the spatial location of the viewer relative to a known point, so that the scripts controlling the multi-user functionality can send this position to other browsers.
A BoxProximitySensor can indicate where a user is relative to a specific frame of reference. This is useful when the location and orientation are only needed for parts of the world, or if the world is segmented into Zones (see below) with one sensor for each. (A BoxProximitySensor can be attached to the world's root Transform if it's necessary to determine the viewer's location anywhere in the world.) The user's location can be accessed by routing events from the Sensor's position and orientation fields, or by routing an SFNode for the sensor into the script and reading the fields when needed.
It must be possible to uniquely identify the users in the shared space, in order to inform the server or the other browsers who is sending the location information.
This information is application-specific. The application might require friendly nicknames, email addresses, URLs of avatars, or something else entirely. Typically, user identification will be handled by a script reading information from a configuration file.
Once the spatial location is available, the script needs a means to send the information to other browsers or the server. The protocol used to do this depends on the application; for example it could be VRML+ or DIS or VSCP. Rodger: Do we want to mention these ? Mitra: Yes, since they will be meaningful to the readers, and we want to specifically say that we will work with any of these approaches
Moving Worlds supports such communication by allowing scripts to run asynchronously; any of the languages likely to be used for scripting have network functionality. A Java applet, for example, can use the standard Java threading mechanisms to spawn a thread that then uses Java's network classes to send information to the network. Moving Worlds does not need any added API calls to provide this functionality.
Browsers must be able to receive information over the network, either from a server or a peer, and use that information to update the shared scene.
In Moving Worlds, scripts use normal language constructs to handle application-dependent protocols. When a user first connects to a shared world, information about that user's avatar is sent to other browsers sharing that world. This information typically includes a VRML description (or a URL to a VRML description) of the avatar.
The avatar can be put into the world in several ways. For example, one or more nodes could be placed in the world, in the same Transform as the BoxProximitySensor nodes.
Once the avatar is created, the receive-and-display script could provide an SFNode pointer to the avatar's node(s) to allow other scripts to move the avatar around in the scene.
In the case of trying to share state information across the network -- whether that information consists of a boolean indicating whether a light is lit, or the time an animation should start, or the position of a movable object -- a script must be able to read and write this state.
In Moving Worlds this state-sharing is accomplished by routing events between the nodes to be shared and the script that is responsible for propagating the changes.
Mitra: The nasty part - that I've been trying to convince Gavin we need fixed!
A separate eventIn and eventOut (or a separate script) are provided for every state that can change, so that it can be associated with a unique name before sending it over the network. Rodger: it's here that you need to discuss naming in general, where does the unique name come from. Mitra: Exactly! It could be a DEF name, or it could be a name associated with a route, or it could be a name associated with the eventIn on the script node, both the former work with fan in, but are not passed in the event. The latter doesn't work with fan in.
One fix would be to support the "userData" field on routes to allow us to use fan-in without losing the information as to which peice of state was being sent
As information is received off the network, the script can either send an event via a route to change the state, or can use the getValue() method to obtain the value of a field (if the script has an SFNode pointer to the portion of the scene graph being changed).
The goal of this document is to give potential users and implementors of Moving Worlds a feel for how multi-user systems could be built. However, one strength of the Moving Worlds proposal is that it balances simplicity against flexibility. There are thus many interesting and important aspects of distributed systems that this proposal makes no attempt to address. These areas are open, and the choice of how to solve them is left to the system builder. They include:
Separator { DEF bar BoxProximitySensor { } # To detect our own position DEF foo Separator { } # Avatars are added here } DEF baz Script { eventIn SFVec3f position eventIn SFRotation orientation field SFNode avatarRoot IS foo behavior "http://xyz.com/mynetworkprotocol.java" } ROUTE bar.position -> baz.position ROUTE bar.orientation -> baz.orientation
This example needs rewriting to match the final version of the API, but it should be close enough to give the general idea. class MyNetworkProtocol extends VRMLApplet implements Runnable { void start() { # spawn thread to monitor network } void eventIn(Event e) { # send position and orientation events to server } void run { # monitors network, # on receipt of appropriate events from network calls # sends add, delete, change events to avatarRoot. } }