Worlds.com     |  Development Kit Table of Contents  |

 

WorldServer v11 Administration Guide

This document contains information needed for installing and maintaining  WorldServers. It is intended for system administrators and assumes knowledge of Unix, Oracle and Web concepts. It uses the following conventions:

 File names and directory names  Bold 
 (startup.htm)
Command lines, output samples, option names   Typewriter font 
 (kill 17016)
Key terms  Italics 
 (server world)


Table of Contents

Top of Page


Overview

Architecture

WorldServer supports the registration, authentication, and communication needs for 3D chat clients. Typically the client is intended to view a 3D multi-user community where users can choose avatars (3D representations of themselves) and navigate through a 3D environment, while chatting with other users. The WorldServer suite consists of two primary types of server processes: the UserServer and the RoomServer. 

Application Architecture

The above diagram depicts an example Worlds application consisting of 2 clients, a WorldServer (containing 2 RoomServers and a UserServer), and an Oracle/SQL*Plus database server.  This example application will be used later to illustrate WorldServer operation.  First we describe how responsibilities are divided between RoomServers and UserServers.

The RoomServer

The RoomServer can operate in stand-alone mode to handle an entire world when no user authentication is required. For larger worlds, or when user authentication and registration are required, multiple RoomServers can be used in conjunction with a UserServer. If shared state (shared objects) is desired, the RoomServer must run in conjunction with an Oracle database that will store persistent room data. The RoomServer performs the following tasks:

  • Listens on a given port to connections by clients.
  • Establishes and maintains TCP/IP client connections (when used in conjunction with a UserServer, UserServer will establish the first TCP/IP connection with a client and then redirect users to the RoomServers).
  • Subscribes clients to any room the RoomServer is servicing
  • Processes client's avatar locations and properties.
  • Disseminates and provides client locations and properties information to other clients in the vicinity. Performs crowd control calculations that determine how avatars are seen and heard by others.
  • Handles and distributes chat text, whispers and broadcast text. Whispers and other messages targeted at users not on that RoomServer are forwarded to the UserServer for routing.
  • Acts as a database client for a properties database to query or modify Room properties, if any. This includes accessing properties for any shared state or shared objects found in rooms.

    The UserServer

    The UserServer is used for larger worlds that require more than one RoomServer, or when user registration and authentication are required. When user registration and authentication are not required, the UserServer is used in anonymous mode, and can handle large worlds with multiple RoomServers. When user registration and authentication are needed, the UserServer maintains a user database and is configured to provide the necessary user services. The UserServer performs the following tasks:

  • Listens on a port for connections from RoomServers. On startup, every RoomServer opens a TCP/IP connection to the UserServer.
  • Maintains that TCP/IP connection with the RoomServers as long as the RoomServer is running. UserServer - RoomServer communications fall into one of the following categories: user connection and privileges management, redirection, whisper forwarding, broadcast text, and miscellaneous properties management.
  • Listens on a designated port for new connections from clients.
  • Establishes "transactional" TCP/IP connections with clients for the purposes of logging in, providing redirection to RoomServers, and other user queries. Transactional means that the client connection to the UserServer is maintained only as long as it takes to complete the desired transaction, then the client is either redirected to a RoomServer or dropped after a "grace period" of two minutes.
  • Provides registration and authentication services when registration and authentication are required.
  • Acts as database client to query or maintain a user database when registration and authentication services are required.
  • Acts as database client to query or maintain a World properties database when persistent property changes are made by users or administrators.

    Possible Configurations

    Possible WorldServer configurations include the following:

    Single RoomServer 

    A RoomServer may be utilized in stand-alone mode to provide anonymous multi-user capabilities for a small virtual reality space. Users do not have to register or be authenticated, they only have to present a unique user name (one not currently in use on the RoomServer) at the time they initialize a session. Single RoomServers run in anonymous mode are useful for demos and small worlds but cannot scale to more than 1000-2000 users and cannot keep track of persistent data such as users' permanent names, email addresses, or usage.

    Note: This configuration hasn't been extensively tested.

    Multiple RoomServers - single anonymous UserServer 

    Multiple RoomServers may be utilized with a UserServer configured in anonymous mode to provide scalable multi-user capabilities for a virtual reality space. When the UserServer is configured to run in anonymous mode, users only have to present a unique user name (one not currently in use by a client actively logged on to the WorldServer) at the time they initialize a session. The UserServer provides redirection services and message forwarding as necessary between the RoomServers.

    Note: This configuration hasn't been extensively tested.

    Multiple RoomServers - single UserServer (Currently used configuration)

    One or more RoomServers may be utilized with a UserServer configured to provide registration and authentication services. In this case, users must register, and must authenticate each time they log into the system. In addition to providing redirection and command forwarding, the UserServer handles user registration and authentication, and maintains a database of information on users, their usage, and other per user information. The UserServer can also be configured to allow guest logins, where a client is assigned a guest name and has access to a limited area only. Guest logins do not require authentication.

    Single UserServer

    A UserServer may be utilized without any RoomServers for the sole purpose of delivering a text message to the client, giving the status of the WorldServer. The UserServer may either be configured to require authentication, or to operate in anonymous mode. The server message file will contain the message to be delivered to all clients that connect, and all redirection will indicate that the desired rooms do not exist, causing the client to terminate the connection after displaying the text message.

    Note: This configuration hasn't been extensively tested.

    Redundant WorldServers

    Two WorldServers, each with their own UserServer and RoomServers, can be combined to provide redundancy and additional scalability.  The UserServers in the two WorldServers share information concerning which users are currently logged in.   Clients are configured to try to connect through both UserServers and the first one to respond is used.  If one WorldServer fails, clients connected to the failed WorldServer will reconnect to the working WorldServer automatically.  Users cannot see or chat with users which are in rooms served by a different WorldServer, but they can whisper to such users and can teleport to the user's room on the other WorldServer.   Buddylist notifications also work across WorldServer boundaries.

    Note: This option is no longer supported.

    Single WorldServer Operation

    The following diagrams and associated narratives describe how clients, a WorldServer, and a database server interact during normal operations.  The diagrams show two clients and a WorldServer configuration consisting of two RoomServers and a single UserServer.  Although this is not typical, it is sufficient to illustrate the majority of WorldServer operation.

    What follows should not be used as a basis for understanding the details of the underlying protocols.  Several aspects of the communication protocol have been simplified or ignored.  For example, positive and negative acknowledgments are not generally presented, and there is no mention of room subscriptions.  The aspects not presented were not considered essential to understand overall operation in sufficient detail to administer a WorldServer installation.

    If a UserServer is to be used, it is started first.  On startup it reads its configuration file.  If it is configured to work with a user database, it connects to the database server, using the username and password provided in the UserServer's configuration file, and retrieves all user properties stored in the database.  User properties include registration serial numbers, usernames, and passwords.  The UserServer is now ready to receive connections from clients.

    Once the UserServer (if any) is ready, each RoomServer is started.  On startup it reads its configuration file and allocates any rooms listed in its configuration file.   These rooms are called statically allocated rooms.  If it is configured to work with a room database, it connects to the database server, using the username and password provided in the RoomServer's configuration file, and retrieves the room properties for all rooms that it serves.  It also adds any rooms that are listed in its configuration file which are not yet in the database.  Note that use of statically allocated rooms is deprecated in favor of dynamic assignment and dynamic allocation discussed below.

    If the RoomServer is configured to work with a UserServer, it connects to the UserServer using the password provided in the RoomServer's configuration file.  The RoomServer then identifies itself to the UserServer with a unique name and indicates which rooms it is willing to serve.  The UserServer stores this information for quick retrieval when redirecting clients and routing messages.

    The RoomServer can indicate to the UserServer that it will serve rooms in particular worlds.  When one of these rooms is first referenced by the client, the UserServer will dynamically assign them to such a "volunteering" RoomServer.  If there are no volunteers, the UserServer will dynamically assign the room (and all future rooms in the same world) to the RoomServer which is currently serving the smallest number of worlds.  The room will then be dynamically allocated by the RoomServer and the room properties will be retrieved from the database server.  The RoomServer configuration file specifies which worlds the RoomServer volunteers to serve.

      

    If the WorldServer includes a UserServer, clients send the user's name, password, and optionally the number of nearby avatars for which the client would like to receive updates.  If the UserServer determines that the username/password combination is authentic, it responds with the number of nearby avatars for which updates will be sent.   This will be the same as the number requested by the client, or a default if they client did not specify.  The default number of avatars is set in the UserServer configuration file.  For guest logins (if permitted), no username or password is sent by the client.  Instead, the UserServer assigns a username and sends it and a time limit to the client.  The client is responsible for enforcing the time limit by logging the user off after the specified time has elapsed.  The time limit, the prefix for assigned guest usernames, and the number of guests allowed are all specified in the UserServer configuration file.

    If the UserServer is configured to work with a database (i.e. it is not anonymous) and username and password are not authentic, the UserServer requests a registration serial number from the client which queries the user.  If the provided registration serial number is valid, the username, and password are added to the user database.

    If the UserServer is anonymous, any username which is not being used will be considered valid.

    If the WorldServer does not include a UserServer, the client authenticates directly with the RoomServer.  As with an anonymous UserServer configuration, any username which is not being used will be considered valid by the RoomServer.

        

    If the WorldServer includes a UserServer, the initial client request to change rooms is sent to the UserServer.  The UserServer determines which RoomServer is serving the requested room and responds by redirecting the client to that RoomServer.  The client then connects to the RoomServer using the user's name and password, and requests to change rooms.  The RoomServer requests that the UserServer authenticate the username/password combination.  If the user is authentic, the UserServer sends the user's properties to the requesting RoomServer.  The RoomServer, now knowing that the user is valid, allows the user to change rooms and sends the properties of the new room back to the client.

     

    Once a user is in a room, almost all communication is between RoomServers and clients.   Each client communicates with the RoomServer serving the room where the user is currently located.  The client informs the RoomServer of any changes in the user's location and any messages the user wishes to send to other users.  The RoomServer informs the client of any changes in the location of nearby users and any messages from other users.

        

    If a RoomServer receives a message for a user in a room that it does not serve, it forwards the message to the UserServer.  The UserServer determines which RoomServer is currently serving the user and forwards the message to the recipient's RoomServer.   The recipient's RoomServer then forwards the message to the recipient's client.

    This process is used for whispers, broadcasts, and normal chat across room boundaries.   The UserServer forwards broadcasts to all RoomServers.

    Redirects are the transfer of a user from one RoomServer to another RoomServer. This might happen if the user walks between rooms, or if the user teleports, uses bookmarks or first connects past the UserServer. The UserServer acts as intermediary for all redirect requests, because only the UserServer knows which rooms are being served by which RoomServers.

    When a RoomServer receives a client request to move to a room served by a different RoomServer, it queries the UserServer to determine which RoomServer serves the requested room and then redirects the client to the new RoomServer.   The client then connects to the new RoomServer using the user's name and password, and requests to change rooms.  The RoomServer requests that the UserServer authenticate the username/password combination.  If the user is authentic, the UserServer sends the user's properties to the requesting RoomServer.  The RoomServer, knowing that the user is valid, allows the user to change rooms and sends the properties of the new room back to the client.

    Because this involves a number of steps, redirects occasionally cause a short hitch on the client side. A well-designed world should keep the number of redirects to a minimum, by placing divisions between RoomServers at natural "choke points" between physical portions of a virtual space, such as between worlds.  The dynamic room assignment scheme meets this requirement because all rooms within a world are served by the same RoomServer.  (Note that a single RoomServer can serve multiple worlds.)
     

     

    When a user wishes to logout, the client informs the current RoomServer, and disconnects.  The RoomServer then notifies the UserServer, and the UserServer updates the database with any changes to the user's properties.

        

    If the UserServer or a RoomServer were to fail, any changes to user or room properties which have not been sent to the database server would be lost.  To minimize the loss, the UserServer and RoomServer periodically send these changes to the database server.  The frequency of these updates is set in the configuration files.
     

    Advanced Topics

    Client vs. Server Worlds and Channels

    As mentioned in the introduction, a WorldServer application allows users to navigate a virtual space consisting of many worlds which, in turn, consists of many rooms.   However, the meaning of the terms virtual space, world, and room depends on whether the context is what the user perceives or how the WorldServer works.  In this section, we will attempt to better define these terms in each of these contexts.

    We call the virtual space that the user perceives the user virtual space.   It consists of multiple interconnected user worlds. A user world generally corresponds to a ".world" file on the client machine.  This file describes the connectivity of user rooms and their visual characteristics (e.g. locations of walls, and textures).

    From the WorldServer's perspective, what we call the server virtual space consists of multiple channels.  Each channel consists of multiple server worlds and handles a separate, disjoint set of users.  Each server world consists of a collection of server rooms.  Each server room handles most of the message traffic from the users in the containing channel whose avatar is in the corresponding user room.  Each RoomServer can serve several server worlds (in the same or different channels) by dynamically allocating server rooms within each server world as needed.   One (or two redundant) WorldServer, each with one or more RoomServers, can be used to serve the entire server virtual space.

    Note that the use of channels means that multiple server worlds can correspond to the same user world and multiple server rooms can correspond to the same user room.  By limiting the number of users per channel, it is possible to reduce the load on each RoomServer and better balance the load between RoomServers.  The recommended maximum number of users per channel is set in the configuration files.  When a user logs in, the WorldServer searches for a channel with less than this maximum population and places the user in that channel.  If all channels are full, a new channel is created.

    Using multiple channels can improves performance in two ways.  First, it results in fewer users in each server room.  This means that there are less users to search to find the nearest avatars and results in a lighter load.  Second, in configurations with a UserServer, load balancing is also improved.  With or without channels the UserServer dynamically assigns new server worlds to the RoomServer serving the fewest server worlds.  More channels result in more server worlds and finer-grained balancing.

    Channels are strictly a performance optimization, and as such, they are designed to be mostly invisible to the user.  The WorldServer treats messaging between users in server worlds in different channels no differently than messaging between users in different server worlds on the same channel.  Whispers, teleports, and buddy list notifications can cross channel and server world boundaries, but normal chat and position updates do not.  Note that users can teleport into full channels so the per channel population limit is not strictly enforced.

    The fact that normal chat and position updates do not cross channels can lead to a perceivable artifact in the users experience.  It means that 2 users can be standing next to each other in the user world, and show up on each others buddy lists, but they may not be able to see each other or chat with each other because they are in two different server worlds in two different channels.  They can however, whisper to each other and one of them can teleport to the other's location.  This will put them in the same server world and they will be able to see and chat with each other.  Other than the existence of this  artifact, users are completely unaware of the existence of multiple channels.

    Redundant WorldServer Operation

    A certain amount of redundancy is available by simply running two WorldServers which are connected to the same (if any) database.  Clients can be configured to attempt to connect to two WorldServers at the same time.  Each client keeps the first connection which is established and discards the other.  This generally results in clients connecting to the closest WorldServer and ensures that if one WorldServer is unavailable, users will still be able to connect.  This kind of redundancy is valuable, but it results in separate server virtual spaces which correspond to the same user virtual space.   Users connected to one WorldServer cannot see, chat with, whisper to, or teleport to users connected to the other WorldServer.

    In order for the two WorldServers to serve the same server virtual space, one of the two UserServers must be configured to act as a backup server and the other as a backup client.  Whenever the backup client UserServer is running, it periodically attempts to connect to the backup server UserServer until a connection is established.  Once a connection is established all other communication is symmetric (i.e. peer-to-peer).   Upon establishing the link, each UserServer sends to the other the list of users which are currently logged in.  This allows buddy lists to initially include users connected to either WorldServer.  As users log in and out of either UserServer, they notify each other so that the buddy lists are always kept up to date.  Broadcasts, and whispers are also forwarded to the other UserServer.

    When a user on one WorldServer attempts to teleport to a server room served by the other WorldServer, the following rather complex communication occurs.

    1. The client sends a request to its current RoomServer to teleport to the new room.  The room is identified by its channel name, world name and room name.  The channel name includes a suffix that indicates which WorldServer is serving it.
    2. Since the RoomServer does not serve the server world indicated by the channel name and world name in the request, it forwards it to the local UserServer.
    3. The local UserServer recognizes that the requested channel is on the remote WorldServer and sends a request to the remote UserServer that the user be transferred to the requested room.
    4. The remote UserServer adds the user to its list of users and determines which of its RoomServers is currently serving the requested server room.  The address and port of the RoomServer is then sent back to the original UserServer
    5. The original UserServer then relays the address and port back to the original RoomServer which sends a traditional redirect message to the client.  This UserServer also sends the users properties to the remote UserServer.   From now on, all whispers sent to this user will be forwarded to the remote UserServer.
    6. The client connects to the remote RoomServer using users login name and password and requests to be placed in the room.
    7. The remote RoomServer forwards the login name and password to its UserServer for authentication.
    8. Upon authentication, the UserServer sends the user's properties to the RoomServer.
    9. The RoomServer then places the user in the requested room and sends the room's properties to the client.

    10.  

    Top of Page


    Selecting a WorldServer Configuration

    Remember that the server executables have hard-coded maximum user limitations. This makes it fairly important to make accurate estimates of the size of your intended user base. Any WorldServer configuration that uses a UserServer can only use at most two UserServers, so make sure you choose UserServers that have a large enough upper limit to cover expansion. RoomServers also have maximum user limits, but because you can scale up your world by adding multiple RoomServers, the initial user estimate won't be as critical.

    If the entire WorldServer suite will be running on one single-processor architecture, there is a slight performance degradation in running more than one RoomServer process through the single processor (because of the extra overhead in the form of context switches). However, configuring multiple RoomServers on a single-processor machine offers some minor advantages for long term user tracking, only because each RoomServer generates its own log file.

    If the WorldServer will be running on multiple single-processor machines, configure one RoomServer per machine.  Run the UserServer on a machine of its own, or the most powerful machine if a separate machine is not available.  If all machines are identical, start the last RoomServer on the machine running the UserServer.  The last RoomServer started will be the last to have server worlds dynamically assigned to it.

    If the WorldServer will be running on a multi-processor architecture, configure one RoomServer per processor, plus one UserServer.

    If possible, for systems which use an Oracle database, run the UserServer on the same machine as the Oracle server. This is not a requirement, but it will reduce network bandwidth usage and may reduce database client-server configuration problems.  If possible, the UserServer and the Oracle server should be running on the same local network. The potential down side of running on a single machine is the performance of the machine which supports both the UserServer and the database, particularly if the database is also used by other applications.  The degree to which this will be a problem depends mainly on the database. The UserServer will probably never be the majority CPU-cycle user on any machine. Our experience is that 1000 users logging in and out randomly on an SparcStation 1000 UserServer only accounted for 3 percent of maximum CPU load.

    Another possible reason for distributing RoomServers on multiple machines (or even for splitting up a single machine into several RoomServer processes) is that if an individual RoomServer goes down it won't bring down the whole system. When a RoomServer is brought down, the UserServer will not be able to provide redirection for the rooms it was serving.   Clients will reconnect to the UserServer and rooms will be dynamically reassigned to the remaining RoomServers.  This allows for real-time correction of problems without bringing down your entire world, and if necessary the configuration file of the non-operating RoomServer could be used to start a new process on another machine without any long-term visible difference to the client.

    The guidelines for determining the optimal number of RoomServers vary between configurations, processors and specific load situations. The hardware requirements give some idea of how many users could be supported with several configurations, but there are several variables that will affect your true user capacity. Some of these variables are intangibles or design considerations for specific worlds: for instance how "chatty" the population of your intended world will prove to be, the percentage of whispered messages vs. standard chat, number of undeliverable messages, etc. Other variables are controllable, for instance the update cycles keyword in the RoomServers' configuration files.

    The following list of questions will help you identify your needs and determine the optimal RoomServer organization for your WorldServer:

  • How many users do you plan to support? The recommended maximum number of simultaneous users per RoomServer process is between 1000 and 1800, depending on the speed of the machine. To estimate the number of simultaneous users, figure approximately 1%-2% of the total user base. Not everyone will be logged in at the same time.
  • Do you plan to support guest logins, and if so, will guests be timed out? Guest login decreases the load on the RoomServer (and slightly increases the load on the UserServer).
  • Do you plan to change the Avatar Update frequency keyword from the default value of 1 second?  Requiring more avatar updates will greatly increase the load on the RoomServer(s).
  • Do you plan to change the MaxAvatars keyword from the default value of 6?  Increasing this value will slightly increase the load on the RoomServer.
  • A large number of doorways into a given room can also slightly increase server load.
  • Is the room intended as a chat space or an exploring world?  Chat requires more bandwidth than positional updates, and has more erratic bandwidth usage peaks.
  • What is the nature of chat in this room or the world?  Whispers increase server load more than normal text broadcast. "Whispers" can be whispers sent within RoomServers or whisper redirects up to the UserServer and back to another RoomServer (even greater load).

    Hardware Requirements

    Our tests indicate that between 4.5 and 10 active users can be supported per MHz of CPU speed.  The tests simulated users which moved constantly and sent a short chat message once every 10 seconds.  Servers were configured with the default settings which result in chat and movement being sent to the 6 nearest avatars once every second.  The hardware we tested and the expected number of users supported are described in the table below.  Note that, due to testing conditions, some numbers are extrapolated:
     
     

    Hardware Description

    Number of RoomServers

    Number of Active Users

    Users/MHz

    Dual 300 MHz Sun Ultra

    3

    4500

    7.5

    Dual 400 MHz Dell running NT or Solaris

    2

    3600

    4.5

    143 MHz Sun

    1

    1000

    7

    Note that this does not take into account HTTP or SMTP server load.

    Database requirements

    If user authentication is required, an Oracle database server must be running. The actual Oracle database server may be run on the same machine, or on a separate machine. In the case of running Oracle on a separate machine, an Oracle SQL*Plus client needs to be on the same machine as the UserServer process. Oracle's system requirements need to be considered in addition to WorldServer's requirements. If full logging is enabled, allow about 1 GB of disk space on the Oracle machine. Also consider that there are varying levels of logging possible, both by Oracle and by the WorldServers, and some logging options may require automated or real-time maintenance and intervention to keep the log files from getting unwieldy.

    Bandwidth Requirements

    Wide area bandwidth per user is approximately 1 Kbps from server to client and approximately 1 Kbps from client to server.  This is based on internal testing of a 3 RoomServer configuration serving 3000 simulated users behaving as described above.

    Top of Page


    Configuring

    Configuring Oracle

    Some WorldServer configurations use the Oracle database server to store user or room properties. In these configurations, the UserServer and/or RoomServer(s) act as Oracle database clients. If your selected WorldServer configuration uses the Oracle database server, then you must first establish an Oracle account for the WorldServer and make sure the necessary environment variables and Oracle service name(s) are defined on the machine(s) where the WorldServer will run. You will also need to create and populate the database tables that your WorldServer configuration requires.

    Please note that technical questions relating to the Oracle database need to be addressed through Oracle technical support (800) 223-1711.

    Establishing Accounts and Services

    In order for the database clients to gain access to the database, one or more accounts (i.e. username/password combinations) must first be created on the Oracle database server. Separate accounts should be created for each database client. 

    If the UserServer will need to access the database remotely via SQL*NET you will need to edit tnsnames.ora on the database server machine to get a service and set the SID. The user and room tables can share a service name or they can each have their own.

    If you already run other Oracle client applications on the WorldServer machine(s), then it is likely that the machines are already set up. If they are, just set the ORACLE_HOME environment variable to point at your installation of Oracle. If not, it is still possible to configure each database client machine by hand to allow access to the database server. If the database client machine is running Oracle Names, the configuration process is too involved to describe here. Please refer to the the Oracle documentation for a description. If the database client machine is not running Oracle Names you SHOULD be able to use the following steps to configure each database client machine:

    1. Somewhere in the WorldServer installation directory, create a directory called oracle/network/admin
    2. From the machine with the Oracle server, copy the file ~oracle/network/admin/tnsnames.ora to the admin directory you just created on the WorldServer machine.
    3. Set the ORACLE_HOME environment variable to the full path to the oracle directory you created. For example, if the WorldServer installation is installed in the worldserv user's home directory (and you use the C-shell), and you created the oracle directory within the worldserv user's home directory, and you are using a C-shell variant, you would type:

    4. setenv ORACLE_HOME ~worldserv/oracle

    Initializing the User Database

    To create the user database tables:

    1. Login as worldserv.
    2. Change to the directory that contains the createUserTables.sql script (or move the script to current working directory).
    3. Using an SQLPlus client, login to the database using the account you created for the UserServer.
    4. After connecting, type:

       @createUserTables

      The tables should now exist. We will populate the serial number table in the next section. The other tables will be populated as users register.

      QAQA123456789012
      
      QAQA142857142857
      
      ...

      To create the user database tables:

      1. Login to the UserServer machine as worldserv.
      2. Change to the directory that contains the NewSerials.sql script (or move the script to current working directory).
      3. Using an SQLPlus client, login to the database using the account you created for the UserServer.
      4. After connecting, type:

         @NewSerials

        The serial number table will now be populated.

      Configuring Multiple RoomServers with a Single UserServer with User Services

      To configure Multiple RoomServers with a single UserServer with user services, you will need to configure each of the RoomServers as well as the UserServer, as follows:

      1. For every RoomServer you plan to run, create a file named roomservernameRS.cfg (where roomservername is the name you have chosen for that particular RoomServer, the characters "RS" identify this with the RoomServer, and the file ends with .cfg. Again, the naming conventions are recommended practices but not required. Save the file in the WorldServer's /wc_config directory. If processes are running on separate machines, each server should have its own /wc_config directory on the local machine.

        Sample configuration file for one or more RoomServers with a UserServer and user services (firstRS.cfg):

        Server                  Private
        
        # This RoomServer is part of the WorldServer named "Private".  Log
        
        # files will have names like Private.20045.log.  A good choice
        
        # for your WorldServer name is the name of your company or product.
        
        # This name must be the same for all RoomServers and UserServers which
        
        # are part of this WorldServer.
        
        
        
        UserServer              127.0.0.1 5200 first def456
        
        
        
        # Connect to the UserServer at IP address 127.0.0.1 (i.e., the local
        
        # host), port number 5200, using a RoomServer name of "first"
        
        # and a password of "def456".  The IP address must match the address of
        
        # the machine running the UserServer.  The port number and password
        
        # must match those specified in the RoomServers option in the
        
        # UserServer configuration file.  Each RoomServer which connects to
        
        # UserServer must have a unique name (e.g. first, second).  For example,
        
        # secondRS.cfg has the following line instead:
        
        #
        
        # UserServer 127.0.0.1 5200 second def456
        
        
        
        Users                   5100
        
        # Listen for connections from clients on TCP/IP port 5100 (the
        
        # default).  You can choose any unused port.  Port numbers in the high
        
        # thousands are mostly unused.  If 2 or more RoomServers are running
        
        # on the same machine, they need to use different ports.  For example,
        
        # secondRS.cfg might have the following line instead:
        
        #
        
        # Users                   5101
        
        
        
        ClientUpdates           6 1000000 
        
        # By default, each user can only see the nearest 6 avatars and these
        
        # avatars are updated every 1,000,000 microseconds (i.e., once per
        
        # second).  The number of visible avatars can be overridden by the
        
        # client/user.
        
        
        
        RoomDatabase            rs1 abc123 RoomService 60 Dynamic
        
        # Connect to the Oracle room database as "rs1" with a password of
        
        # "abc123" and use the service named "RoomService" to get room properties
        
        # and other shared state.  Store changes back to the database every 60
        
        # minutes.  Any rooms which are dynamically allocated (i.e., allocated
        
        # as they are referenced) should be added to the RoomRegistration
        
        # database table.  Note that each RoomServer should connect to the database
        
        # with a different name.  For example, secondRS.cfg might have the following
        
        # line instead:
        
        #
        
        # RoomDatabase          rs2 bcd234 RoomService 60 Dynamic
        
        
        
        MothFile                moth
        
        # Every hour, read the "message of the hour" from the file named
        
        # "moth" (the default) in the directory where the server is started.
        
        # This message will be sent to every client that successfully connects
        
        # and initializes a session.
        
        
        
        Access                  !@#
        
        # Give special priority access to users which login with a username
        
        # beginning with "!@#".  Priority users may gain access to the
        
        # RoomServer when it is otherwise full of ordinary users.  They can
        
        # also broadcast text, boot users, and ban users.  The access code is hidden 
        
        # when the client's username is displayed to others.
      2. Create a file named userservernameUS.cfg (where userservername is the name you have chosen for your world, the characters "US" identify this with the UserServer, and the file ends with ".cfg"). Save the file in the WorldServer's /wc_config directory. Some of the information used for creating the Oracle database also needs to be included in this configuration file - specifically the Oracle username, password and servicename.

        Sample configuration file for a UserServer with user services (PrivateUS.cfg):

        Server                  Private
        
        # This UserServer is part of the WorldServer named "Private".  Log
        
        # files will have names like Private.20045.log.  A good choice
        
        # for your WorldServer name is the name of your company or product.
        
        # This name must be the same for all RoomServers and UserServers which
        
        # are part of this WorldServer.
        
        
        
        Users                   5110 0
        
        # Listen for connections from clients on TCP/IP port 5110 (the
        
        # default).  This port number must match the port number built into
        
        # the client software.  Delay for 0 minutes before accepting
        
        # connections from clients.  If you manually start the RoomServers you
        
        # will want to increase this to allow time for them to connect to the
        
        # UserServer.
        
        
        
        RoomServers             5200 def456
        
        # Listen for connections from RoomServers on TCP/IP port 5200.  The
        
        # RoomServers must use a password of def456 when connecting.  The port
        
        # and password on this line must match the port and password on the
        
        # UserServer line in the RoomServer configuration files.
        
        
        
        UserDatabase            us abc123 UserService 60
        
        # Connect to the Oracle user database as "us" with a password of
        
        # "abc123" and use the service named UserService to get user properties.
        
        # Store changes back to the database every 60 minutes.
        
        
        
        MothFile                moth
        
        # Every hour, read the "message of the hour" from the file named
        
        # "moth" (the default) in the directory where the server is started.
        
        # This message will be sent to every client that successfully connects
        
        # and initializes a session.
        
        
        
        Guests                  10 guest 60
        
        # Allow up to 10 simultaneous guest logins and assign them usernames
        
        # guest_1 through guest_10.  Inform each guest client during session
        
        # initialization that the requested maximum guest login duration is 60
        
        # minutes.  It is the client's responsibility to honor this request.
        
        
        
        UnicodeNames
        
        # Accept non-English (i.e., Unicode) usernames from clients.  To
        
        # disable Unicode names, omit this line.  The Oracle installation must
        
        # be done appropriately for this feature to work.

      Configuring Redundant WorldServers

      To connect 2 WorldServers in order to provide redundancy:
       

      1. Configure each WorldServer separately according to Configuring Multiple RoomServers with a Single UserServer with User Services.  Be sure to use separate database login names for each UserServer and RoomServer.  Also ensure that each server which will be running on the same machine is listening on a different port, or uses different IP addresses.

      2. Add a line like the following to one of the 2 UserServer configuration files (it doesn't matter which one):

        BackupServer 5200 cde987

        This will cause this UserServer to act as a backup server listening on port 5200 for the backup client to connect with a password of "cde987".

      3. Add a line like the following to the other UserServer configuration file:

        BackupClient 123.231.132.3 5200 cde987

        This will cause this UserServer to act as a backup client.  It will periodically attempt to to connect to the other UserServer at IP address 123.231.132.3 on port 5200 with a password of "cde987".  The IP address must be the IP address of the machine running the other UserServer and the port and password must match the port and password specified in the other UserServer's configuration file.

      Starting the Servers

      To start the WorldServer:

      1. If you are using a UserServer with user services, or a RoomServer with room properties on a database, the Oracle database needs to be running. Start the database if necessary and make sure that you have SQL*NET or direct access to the running database from the machines which will need database access. Refer to the Oracle documentation for more information on starting Oracle.
         
      2. If you are using the UserServer either with services or anonymously, you must start the UserServer before starting any RoomServers.

        To start the UserServer, type:

        UserServer-name config-file-name

        For example:

        US_v11 PrivateUS.cfg

        The initial output from the UserServer will go to the screen and will end with a line like:

        Redirecting server output to file

        From then on, all normal output will be appended to a log file with a name of the form:

        nameUS.pid.log

        where "name" is the name assigned via the Server configuration keyword, the characters "US" are appended to the name to identify this as UserServer output, "pid" is the process id, and the file ends in ".log". For the example given above, the log file might have a name like PrivateUS.2345.log.

        In addition to some particulars about the configuration of the server, all errors are written to the log file. Each error is timestamped, has the name of the user or other object encountering the error, and has other information pertinent to the error.

        Debugging output will go to a file with a name of the form nameUS.pid.out.  Voluminous detailed debugging information will be sent to the ".out" file if the Logging keyword appears in the configuration file.
         

      3. You can now put the UserServer process in the background.  
      4. There will be a delay while the UserServer establishes a link with the Oracle database. Start up time may vary depending on the number of registered users. The UserServer will add the following line to the output file when it is ready to receive connections from RoomServers:

        Ready to serve

        You can monitor this file manually using a shell command like:

        tail -f Private.2345.log | grep Ready

        When Ready to serve appears, you can kill the command with Control-C and proceed to the next step.
         

      5. Start each of the RoomServers. To start a RoomServer, type:

        RoomServer-name config-file-name

        For example, to start the first RoomServer for the "Private" configuration described above, you might type:

        RS_v11 firstRS.cfg

        The initial output from the RoomServer will go to the screen and will end with a line like:

        Redirecting server output to file

        From then on, all normal output will be appended to a log file with a name of the form:

        nameRS.pid.log

        where "name" is either the name assigned via the UserServer (or Server in the case of stand-alone RoomServer) configuration keyword, the characters "RS" are appended to the name to identify this as RoomServer output, "pid" is the process id, and the file ends in ".log". In our example, the log file might have a name like firstRS.2348.log.

        In addition to some particulars about the configuration of the server, all errors are written to the log file. Each error is timestamped, has the name of the user or other object encountering the error, and has other information pertinent to the error.

        Debugging output will go to a file with a name of the form nameRS.pid.out.  Voluminous detailed debugging information will be sent to the ".out" file if the Logging keyword appears in the configuration file.
         

      6. You can now put the RoomServer process in the background.  In most Unix shells you would do this by pressing Cntrl-Z and typing bg.
         
      7. Repeat the last two steps for each additional RoomServer.

      Monitoring the Servers

      WorldServer Logs

      To view the log files, change into the directory containing the log file and type more followed by the filename of the appropriate log, or use a text viewing utility to open the file. You can tail any log file which is currently being written to get the most current data from the file.

      RoomServer Logs

      RoomServer log entries are appended to a file with a name of the form:

      nameRS.pid.log

      where "name" is either the name assigned via the UserServer (or Server in the case of a stand-alone RoomServer) configuration keyword, the characters "RS" are appended to the name to identify this as RoomServer output, "pid" is the process id, and the file ends in ".log".

      Every day or week, a new log file is started and the previous log file is saved in a file with a name of the form:

      nameRS.pid.MM-DD-YY.log

      where "MM-DD-YY" is the date the file was saved.

      Of the types of information logged by the RoomServer, the following are the most notable:

      • User Sessions. Whenever a user leaves a RoomServer, the RoomServer logs the user's session in the following format:

      Weekday Month Day Time Year UserName (IP Address)
      
        on since Weekday Month Day Time Year
      
        N text messages, avatar = avatarFileName

      For example:

      Thu Jun 27 13:26:12 1996 Bot_347 (205.153.211.35)
      on since Thu Jun 27 13:05:44 1996
      108 text messages, avatar = avatars/ffrog.mov
       

      • User Statistics. Every hour the RoomServer logs the number of active users on that server:

      Weekday Month Day Time Year - RoomServerName: 
      
          Serving N users 
      
          Serving M rooms 
      
              RoomName - P Users 
      
              ... 
      
              ...

      For example:

      Tue Jun 25 20:08:00 1996 - Hub: 
      
           Serving 151 users 
      
           Serving 11 rooms
      
             sky_1301 - 87 Users
      
             sky_1221 - 1 Users
      
             sky_1250 - 1 Users
      
             sky_1219 - 3 Users
      
             glee_1029 - 2 Users
      
             sky_1264 - 1 Users
      
             sky_1238 - 25 Users
      
             sky_1227 - 1 Users
      
             sky_1252 - 26 Users
      
             sky_1272 - 1 Users
      
             sky_1224 - 3 Users

      • Errors. The RoomServer adds outstanding errors to the log file. Note that the errors might often be generated by unexpected client or network behavior rather than true errors within the server process. For example:

      (SomeGuy) - timeout
      (BadBob) - Protocol::recvCommand: Connection reset by peer

      These two "errors" are common if the user's ISP has dropped them offline or cannot support enough bandwidth for the client to maintain a connection.
       

      • Alerts.  If the RoomServer is unable to send updates to clients at the requested interval more than 5 times in an hour, the following alert will be logged:

      ALERT: Load appears to be approaching the limits of this hardware.

      If you see this message, you should consider upgrading your hardware or reconfiguring your WorldServer or user virtual space.
       

      • Resource Usage. In addition, every hour the RoomServer logs resource usage information accumulated since the RoomServer was started. For example:

      Resource usage -
      user time = 14 minutes
      system time = 4 minutes
      maximum resident set size = 0
      integral shared text memory size = 0
      integral unshared data size = 0
      integral unshared stack size = 0
      page reclaims (minor faults) = 0
      page faults (major faults) = 15
      swaps = 0
      messages sent = 1
      messages received = 799105
      voluntary context switches = 610383
      involuntary context switches = 108202

      This information is gathered using the getrusage() system call. Unfortunately, many of the entries are not supported on Sun workstations.

      UserServer Logs

      UserServer log entries are appended to a file with a name of the form:

      nameUS.pid.log

      where "name" is the name assigned via the Server configuration keyword, the characters "US" are appended to the name to identify this as UserServer output, "pid" is the process id, and the file ends in ".log".

      Every week a new log file is started and the current log file is saved in a file with a name of the form:

      nameUS.pid.MM-DD-YY.log

      where "MM-DD-YY" is the date the file was saved.

      Of the types of information logged by the UserServer, the following are the most notable:

      • User Sessions. At the end of every user authentication session, the UserServer appends an entry of the following form to the log:

      Weekday Month Day Time Year UserName (IP Address)
      
      connected since Weekday Month Day Time Year

      For example:

      Thu Jun 27 13:26:12 1996 Bot_347 (205.153.211.35)
      connected since Thu Jun 27 13:05:44 1996

      The UserServer also logs every user logout in the following format:

      Weekday Month Day Time Year UserName (IP Address)
      active since Weekday Month Day Time Year

      For example:

      Thu Jun 27 12:07:17 1996 Bot_778 (205.153.211.35)
      active since Thu Jun 27 11:46:17 1996

      If the user was a guest, the UserServer also logs the client version identifier, sent by the client as part of the login process:

      Weekday Month Day Time Year UserName (IP Address) ClientVersion
      active since Weekday Month Day Time Year

      For example:

      Thu Jun 27 12:07:17 1996 Guest_78 (205.153.211.35) 96070215-HomePC
      active since Thu Jun 27 11:46:17 1996
       

      • User Statistics. Every hour from when the server was first launched, the UserServer logs the number of live connections to the UserServer (including the permanent connections to the RoomServers) and the total number of users active (i.e. logged in) in the world,

      Weekday Month Day Time Year - ServerName
      Serving N connections
      Serving M active users

      For example:

      Thu Jun 27 12:07:15 1996 - WorldsChat
      Serving 4 connections
      Serving 700 active users
       

      • Errors. The UserServer adds outstanding errors to the log file. Note that the errors may be generated by unexpected user input rather than true errors with the server process. For example:

      USRoomServer::userDisconnect: active user not found - Bot_80
      USRoomServer::userWhisper:  undeliverable whisper dropped - too many tries

      These two "errors" can both be generated by users trying to find people who aren't currently online by using the whisper functionality.

      (UserName) - recv: Error 0

      This message is due to the user unexpectedly dropping the connection.
       

      • Resource Usage. Every hour the RoomServer logs resource usage information accumulated since the RoomServer was started. This information is gathered using the getrusage() system call. Unfortunately, many of the entries are not supported on Sun workstations. An example resource usage report might look like:

      Resource usage -
      user time = 14 minutes
      system time = 4 minutes
      maximum resident set size = 0
      integral shared text memory size = 0
      integral unshared data size = 0
      integral unshared stack size = 0
      page reclaims (minor faults) = 0
      page faults (major faults) = 15
      swaps = 0
      messages sent = 1
      messages received = 799105
      voluntary context switches = 610383
      involuntary context switches = 108202

      Tools and Monitoring

      Many of your existing UNIX system tools and monitoring applications will be useful when running the WorldServer. The server process itself is mostly self-contained and will not require ongoing maintenance. Nonetheless, the system tools can help you monitor usage and check if people are having problems connecting to your servers.  You can also use these tools to help determine if a particular server is overloaded.   If you see that a server is running at near capacity, you will probably have to reconfigure your client virtual space and/or your WorldServer.

      Netstat

      The netstat command can be used to check how many users are connected to each server. The RoomServer logs also give this information, in a simple-to-read format. But the logs update user totals hourly and write to a file, not the screen. Using netstat, you can display instantaneous user totals and status and then grep for the subset of information you are interested in either for one-time queries or as a supplement to the logs.

      Because each individual RoomServer or UserServer is running on a distinct port, you can isolate results for each by refining the grep parameters. Likewise you can grep for certain connect status messages.

      Note that for upcoming examples you may have to modify flags slightly for your flavor of UNIX.

      Example: here is a quick command line you can use to check how many users are connected to a RoomServer that you're running on a machine at IP# 209.153.219.00 and port number 5100:

      netstat -n | grep 209.153.219.00.5100 | wc -l

      You could further refine the search by checking for established connections, or you could isolate the various wait state messages instead to check how many people are trying to connect but cannot.

      If you netstat for connections to the UserServer, consider that actual TCP/IP connections to the UserServer by clients are fairly short; total users in a world is best determined by tailing the UserServer's stdout and looking for the hourly report. Once a user has gone through registration and authentication and is added to the set of active users, they need not connect to the UserServer again. Past that point all communication with the UserServer is handled by using the RoomServer that the client is currently connected to as an intermediary.

      Worlds Inc.'s operators have taken many of these netstat routines and automated them as scripts. The output is then scrolled to the screen and refreshed every 2 seconds or so, or written to an HTML file location that can be viewed remotely. Remember that much of this information can also be obtained by looking at the logs, or by querying the databases. Therefore, you will need to consider the impact that running grep and netstat will have on the overall processing load on the server machine.

      System specific tools like Sun's perfmeter

      Tools that let you check overall performance on your server machines will also be helpful when operating the servers. Overall processor use can help you know when a server is close to overloading, and can give you a rough idea of traffic overall. Drastic drops in processor usage might also be an indication that a server has gone down or something else is wrong. Information on packet traffic will help you determine if your connection to the Internet is being overloaded by inbound connections or outgoing messages. Check your specific tool's documentation and to determine what might be useful information to track during server operation.

       

      Terminating the Servers

      Terminating the servers allows you to reconfigure the configuration files. You should also terminate the servers before shutting down the machines they are running on. This will give them an opportunity to update the database(s) and exit cleanly.

      To terminate a server:

      1. Use ps or analyze the names of the .log and .out files to determine the process ID of the server process is running under.
      2. Use the kill command, followed by pid of the process. For example, if the pid is 17016, type:

        kill 17016

        Note: Do not use kill -9.

      When the UserServer is terminated it conducts whatever database transactions are required to log off all active users. This process can take a few minutes. Do not repeat the kill command, simply wait for the process to terminate.    Similarly, when the RoomServer is terminated it conducts whatever database transactions are required to update persistent room information. This process can also take a few minutes.

      Note that whenever a RoomServer loses its connection to its UserServer it will close all user connections, and go to sleep.  Every 30 seconds it will reawaken, reread its configuration files, and attempt to reconnect to the UserServer.   This behavior allows you to temporarily disable the WorldServer for maintenance by terminating the UserServer, editing the UserServer or RoomServer configuration files, and restarting the UserServer.  To completely shutdown the WorldServer you must terminate the UserServer and each RoomServer manually.

       

      Common Maintenance Tasks

      Broadcasting

      To broadcast a text message to all users on the system. It is useful for sending messages about events, or prior to bringing a server down for maintenance. You must first obtain broadcast privileges.  To do this:

      1. Open the web page http://.../cgi-bin/broadcast.pl in your web browser.
      2. Enter your username, the broadcast password, "1" for privilege and then click OK.  
      3. On your next login, your client will have a "Broadcast" submenu under the "Options" menu which can be used to send broadcast text.

      Booting a User

      If a user is being disruptive, it may be necessary to log them off the WorldServer. Users who have Host accounts should also be able to boot a user by right clicking their avatars, and choosing Boot from the menu. To do this:

      1. Use the client software to login to the WorldServer as a user with broadcast privileges.
      2. Send "!boot BadUser" as broadcast text to log the user named "BadUser" off the WorldServer.
      3. You should receive a whisper back saying "BadUser has been booted." Due to the automatic retries in the client, the server maintains a list of users (and their corresponding IP addresses) that have been booted in the last 30 minutes. New attempts at logging in before the 30 minutes expire results in the user receiving a message about "Bad IP address."

      Deactivating and Reactivating Related Accounts

      If a user is being repeatedly disruptive, it may be necessary to deactivate their account so they cannot login again. To deactivate all accounts tied to the disruptive user's email address, do the following:
       

      1. Open the web page http://.../cgi-bin/ban.pl in your web browser.
      2. Enter the disruptive user's username, the banning password, "0" for account status and then click OK.  The banning password can be obtained from a senior Worlds' administrator.
      3. A list of the accounts which were deactivated will be displayed.

      To reactivate accounts, use the same procedure but enter "1" instead of "0" for account status.

      If you only want to deactivate or reactivate some of the accounts for a particular e-mail address, follow the procedures in Deactivating a Single Account and Reactivating a Single Account below.

      Deactivating a Single Account

      To temporarily deactivate the account for username "fred" (case sensitive), with the intention of being able to reactivate it:

      1. Use SQLplus to connect to the user database. Use the database username and password specified on the UserDatabase line in the UserServer configuration file.
      2. Set the account status to 0 for username "fred" by entering the following command:
          update userregistration set accountstatus = 0 where username = 'fred';
      3. Commit the change to the database by exiting SQLplus or entering:
          commit work;

        The client may now register a new username under this serial number.

      Reactivating a Single Account

      To reactivate the account for username "fred":

      1. Use SQLplus to connect to the user database. Use the database username and password specified on the UserDatabase line in the UserServer configuration file.
      2. Set the account status to 1 for username "fred" by entering the following command:
          update userregistration set accountstatus = 1 where username = 'fred';
      3. Commit the change to the database by exiting SQLplus or entering:
          commit work;

      Deleting an Account

      To delete the account for username "fred" (case sensitive) in such a way that the client may reregister:

      1. Use SQLplus to connect to the user database. Use the database username and password specified on the UserDatabase line in the UserServer configuration file.
      2. Deactivate the user's account by following the instructions above.
      3. Ensure that the user is not currently logged in. If he is, you should boot them (or wait for them to disconnect) before continuing.
      4. Retrieve the user's serial number by entering:
          select * from serialnumbers where username = 'fred';

        This should return one row. The username will be 'fred', the serialstatus should be 1, the serial number will also be given. Note the 16-character serial number (case sensitive). Let's call it SN.

      5. Reset the serial number so it can be reused by entering:
          update serialnumbers set username = 'none', serialstatus = 0 
        
          where serialnumber = 'SN';

        SQLplus should respond with "1 row updated."

      6. All other entries pertaining to the username 'fred' should now be deleted by entering:
          delete from userregistration where username = 'fred';

        SQLplus should respond with "1 row deleted."

          delete from userproperties where username = 'fred';

        SQLplus should respond with "N rows deleted.", where N is the number of rows deleted.

      7. Commit the change to the database by exiting SQLplus or entering:
            commit work;

        The client may now register a new username under this serial number.

      User Report

      To look up a user record, go to http://www-dynamic.worldsinasia.com/newmedia/cgi-bin/users.pl. This is particularly useful when you want o look up a user's email address, password, VIP status, etc.

      1. Enter the administrative password in the Password field.
      2. You can now enter one of the following, to display the user record related to it: Username, Email address, Serial Number, PIN Number, or IP Address. You can also make general queries by entering one or more characters in any of these fields followed by *. All records that start with those characters will display.

      Creating a Host Account

      Hosts, or community leaders, are volunteer members who greet, assist and monitor the worlds. They are given a special account, by flagging their record with host privilege bit.  This host account makes their name tag yellow and prefixes their chosen Host username with HOST-XXX, gives them the ability to boot a user, and prevents users from muting them.

      Hosts are screened and carefully selected and trained (see Community Building). Once you've chosen a host, you can create an account for him or her at  http://www-dynamic.worldsinasia.com/newmedia/cgi-bin/newhost.pl.

      1. Enter the administrative password in the Password field.
      2. Enter the Host's email address, the desired Host name (include the HOST- prefix), and their current username.

      Manual VIP Assignment 

      To manually give a user VIP privileges, or to remove their VIP privileges, go to  http://www-dynamic.worldsinasia.com/newmedia/bank/csvip.pl. This is particularly useful for giving users complimentary VIP or extending their complimentary VIP memberships, or for setting the VIP flag for users who paid for it via check or money order.

      1. Enter the "bank" password in the password field.
      2. Enter the username.
      3. From the drop down menu, choose to subscribe a new VIP, renew an existing VIP, cancel an existing VIP, or Show VIP status.
      4. Choose a length in months (1, 6, or 12 months).
      5. Choose a type of payment - complimentary, check, credit card, phone, etc.
      6. A mail notice will be automatically sent to the user notifying him of the transaction.

      Creating a Special Guest Account

      To create accounts for celebrity chats or a game directors, you have to set the user's account with a Special Guest flag. A special guest can be seen and 'heard' by all users logged into the server at the time. The special gust has a magenta colored name tag with a GUEST- prefix.   Note that special guests should only log in with their special guest accounts for special events, as they impact server performance greatly.

      1. Enter the "bank" password.
      2. Enter the username of the special guest.
      3. Choose to make a special guest, or to remove special guest pivileges.

      Troubleshooting Guide

       UserServer or RoomServer exits immediately.  This is usually an indication of an error in the server configuration file.  Things to check:

      • Confirm that you specified a configuration file as an argument when you started the server.

      • Check that the configuration file exists.

      • Look for syntax errors in the configuration file

      • Check the log file for error messages that may help pinpoint the problem.

       

      UserServer never says "Ready".  This usually means that the UserServer is unable to contact the database server.  Things to check:

      • Try to ping the database server from the UserServer.  If you can't then there is a network problem.

      • Verify that the database server is running on the database server machine.

      • Ensure that you can connect to the database server by running sqlplus on the UserServer.  Try:

      sqlplus dbusername/dbpassword@oracleinstance

      where the dbusername and dbpassword are from the UserDatabase line in the UserServer configuration file.  If things are working correctly and you are manually establishing a database client connection, the SQLplus prompt will appear, otherwise you will get some sort of error. Because the UserServer sends something similar to connect to the database, you'll need to correct any SQL*Net problems or other database problems before you can continue. See the Oracle documentation for more details.

      • Look in $ORACLE_HOME/network/admin/tnsnames.ora for the service name of the machine running the Oracle instance you wish to connect to. If tnsnames.ora does not exist, it may be that you have not properly installed SQL*Net. If you're trying to run Oracle locally, try some tests from an SQL prompt to see if the tables can be accessed.

      • Verify that the Oracle username, password and servicename agree between UserServer configuration file and the tsrnames.ora file (or other Oracle configuration files). You can test this by trying to log on to the database server machine and checking the server configuration files for agreement.

      • If you are using unicode or non-ASCII character encoding, verify that the Oracle database was set up to support that data type.

      • Check the log file for error messages that may help pinpoint the problem.

       

      No users can login.  This usually indicates a network problem.  Things to check:

      • Make sure you can reach the outside world from the UserServer machine. Try something like "ping www.sgi.com".  If not, contact the network administrator.

      • If possible, see if you can reach the server machine from the outside world.  If not, contact the network administrator.

      • Check the log file for error messages that may help pinpoint the problem.

       

      Only some users can login.  Things to check:

      • Verify that you have not exceeded the maximum number of users for your server(s).

      • Manually check the database entries for the problem users.

      • Check the log file for error messages that may help pinpoint the problem.

       

      Guests cannot login.  Things to check:

      • Make sure guest access is allowed in the configuration file you are using.

      • Verify that you haven't exceeded the maximum number of guests.

      • Check the log file for error messages that may help pinpoint the problem.

       

      Users can login but can't enter some or all rooms.  This typically means that the RoomServer is having difficulty communicating with the UserServer.  Things to check:

      • Confirm that your server is configured properly. Look particularly for errors in the RoomServer login name and password.  These must agree between the UserServer and each of the RoomServers configuration files.

      • Check the connection between the UserServer and the RoomServer by checking to see if that connection shows up with netstat.

      • Check the log files for error messages that may help pinpoint the problem.

       

      User chat crosses room boundaries unexpectedly.  Things to check:

      • Ensure that the default number of avatars is set to a reasonable value.

      • Check the log files for error messages that may help pinpoint the problem.

       

      New users cannot register.  This usually means that the database tables have filled up.  If the database tables fill up, registered users will still be able to log in, but no new users will be able to register, no new serial numbers can be added, and no new properties can be stored. To avoid filling up the data tables, you should use the Oracle "extend" option so that you only get a table full error when the entire Unix partition fills up. If the tables fill up, there are two options for recovery:

      1. Using Oracle Server Manager or SQL*Plus, add an additional data file to the tablespace where the UserServer Oracle tables are stored.
      2. Shut down the UserServer, back up the Oracle tables, use the Server Manager to drop the data file the tables were stored in, and recreate the data file as a larger file. Finally, restore the database tables. To back up and restore the data tables, use imp/exp, or write a custom SQL script to copy the tables into a larger tablespace.

      Refer to the Oracle documentation or a database administrator for help with these tasks. 

      Appendix I:  RoomServer Configuration Options

      # (comment)

      Any line beginning with '#' is disregarded.

      Server (server name)

      This parameter specifies the name of the application this RoomServer is serving. All servers (UserServer and all RoomServers) that are serving the same application must be given the same name.

      This parameter is required, there is no default.

      Users (port)

      This specifies the port that the RoomServer listens for connections from users on.
      The default is port = 5100.

      ClientUpdates (maximum avatars) (update interval microseconds)

      This parameter specifies the default maximum number of avatars that a given user can see. It can be overridden for a particular client by a request from that client when the client begins a session. In addition, the number of microseconds between avatar updates to the clients is specified.

      The default is maximum avatars = 6, update interval = 1,000,000 microseconds.

      UserServer (IP address) (port) (name) (password)

      This option specifies the IP address and port of the UserServer which will handle logins by users and manage multiple RoomServers. It also specifies the name of this RoomServer and the password to give during the login with the UserServer. In the case where there are multiple RoomServers connected to a UserServer, each RoomServer name must be unique. A RoomServer may be run in a stand-alone mode if only one RoomServer is required for the world, and it does not require user services (e.g., registration, authentication). If a UserServer is not specified, the RoomServer will run in stand-alone mode by default.

      This feature is disabled by default.

      UnicodeNames

      This parameter must be specified when RoomServer is running in stand-alone mode, and the application being served has clients that send non-English unicode usernames.

      This feature is disabled by default.

      World (server world name)

      This option is deprecated.  By default, in configurations with a UserServer, server worlds are dynamically assigned by the UserServer to the RoomServer serving the fewest server worlds.

      Server worlds may be statically assigned to a RoomServer by declaring them in the RoomServer's configuration file with this keyword. Assigning a server world to a RoomServer means that the UserServer will assign any rooms from that server world to that RoomServer.  An line using the World keyword should look like:

      World earth<dimension-3;2>

      In this case "earth" is the name of the client world.  It corresponds to the name of a ".world" file on the client machines.  "dimension-3" indicates that the 3rd server world channel that the UserServer allocates for this client world should be assigned to this RoomServer.  "2" is the channel suffix.  The channel suffix must correspond to the suffix used by this RoomServer's UserServer.  For single WorldServer configurations (i.e. no backup UserServer), no suffix should be used and the semicolon should not appear.  The server world channel name would then become "earth<dimension-3>".

      This option is not supported in applications that have ACE clients.

      Static world assignment is disable by default.

      MothFile (file name)

      This specifies the name of the file containing the "message of the hour". The RoomServer will check this file every hour for a new message. A nonexistent or empty file will cause the current message to be deleted. The RoomServer will send a the message to every client that successfully connects and initializes a session. Unless a full or relative path is given as part of the filename, the file is assumed to be located in the working directory of the server.

      The default file name is 'moth'.

      Connections (maximum ordinary connections) (maximum priority connections)

      This specifies the maximum number of connections from ordinary users and the maximum number of connections from priority users that will be accepted by the RoomServer. This keyword is only available in RoomServers that have been compiled for Worlds' internal use. Shippable versions have the connection capacities hard coded.

      The default is 1000 ordinary and 10 priority connections for internal versions.

      MaxChannelPopulation (maximum users per channel)

      This option only effects stand-alone RoomServers.  If a UserServer is present, it will assign users to channels based on the MaxChannelPopulation option in the UserServer configuration file.

      This option specifies the number of users allowed on a channel before the server starts directing new connections to a different channel. The server does not enforce any channel population limits, so users can still join a full channel; this number is merely a hint to the server to help with scalability.

      To determine which channel a server will direct new logins to, the server searches for the first channel with fewer than the number of users specified in the MaxChannelPopulation option, starting with channel number one.  If all existing channels are full, a new one is created.

      The default value is to allow the maximum number of users allowed on the server onto a single channel.

      Logging

      Inclusion of this keyword enables logging of every command that passes over the network (both input and output), as well as logging of various other information. It is primarily intended to be used for debugging. All of this debugging information is appended to the ".out" file not the ".log" file.

      Logging can also be toggled on and off while the RoomServer is running by sending the server SIGUSR1:

        kill -USR1 pid

      Use logging carefully, it generates a very large amount of output to the RoomServer output file. Logging functionality and this keyword are only available in RoomServers that have been compiled for Worlds' internal use.

      This feature is disabled by default.

      InternalHttpServer
      This is the base URL of the machine to use for handling HTTP requests for the internal version of Gamma.  For example:  http://dev.worlds.net

      ExternalHttpServer
      This is the base URL of the machine to use for handling static HTTP requests for the release (i.e. external) version of Gamma.  For example: http://www-static.us.worlds.net

      ScriptServer
      Similar to ExternalHttpServer, this is the URL of the directory where server scripts should be executed.  This is for things like the registration script and various other maintenance scripts.  Example:  http://www-dynamic.us.worlds.net/cgi-bin

      BindAddr (UserServer only)
      Used when you wish to run two UserServers on a single multi-homed machine. This is really only useful for redirecting traffic on one of the UserServers to a set of remote RoomServers.

      SmtpServer
      The SMTP server to use to connect to for sending WorldsMail.

      MailDomain>
      The DNS domain to use in the "from" address when sending WorldsMail.
       

       

      Appendix II:  UserServer Configuration Options

      # (comment)

      Any line beginning with '#' is disregarded. Server

      Server (server name)

      This parameter specifies the name of the application this UserServer is serving. All servers (UserServer and all RoomServers) that are serving the same application must be given the same name.

      This parameter is required, there is no default.

      Users (port) (delay minutes)

      This specifies the port that the UserServer listens for connections from users on, and the number of minutes to delay after startup before beginning to listen for connections. This delay allows time for the administrator to start the RoomServers and verify correct system operation.

      The default is port = 5110, delay = 0 minutes.

      RoomServers (port) (password)

      This specifies the port that the UserServer listens for connections from RoomServers on, and the password it expects to receive from them in order to establish a session.

      This parameter is required, there is no default.

      UserDatabase (username) (password) (servicename) (update interval minutes)

      This keyword configures the UserServer to utilize a User Database, and specifies the username, password, and servicename for connecting to the Oracle server. In addition, the interval is specified for updating active user information in the User Database. Information for a particular user is also updated in the User Database at the time the user logs off.

      This feature is disabled by default.

      Guests (maximum guests) (prefix) (duration)

      This option is used to configure the UserServer to allow a certain number of guest logins. The guests are assigned the user name "prefix_N" where N is the guest slot they are occupying. The allowed duration of a visit is given in minutes.

      The default number of guests allowed is zero.

      UnicodeNames

      This parameter must be specified when the application being served has clients that send non-English Unicode usernames. In addition, if the UserServer is configured with a User Database, the Oracle installation must be done appropriately.

      This feature is disabled by default.

      MothFile (file name)

      This specifies the name of the file containing the "message of the hour". The UserServer will check this file every hour for a new message. A nonexistent or empty file will cause the current message to be deleted. The UserServer will send the message to every client that successfully connects and initializes a session. Unless a full or relative path is given as part of the filename, the file is assumed to be located in the working directory of the server.

      The default file name is 'moth'.

      Connections (maximum connections) (maximum active users)

      This specifies the maximum number of connections and the maximum number of active users that may be served by the UserServer. Note that connections to the UserServer are transitory and not compute intensive, so this can be set fairly high. This keyword is only available in UserServers that have been compiled for Worlds' internal use. Shippable versions have the connection and active user capacity hardcoded.

      The default is 1000 connections, 10000 active users, for internal versions.

      MaxChannelPopulation (maximum users per channel before redirection)

      This option specifies the number of users allowed on a channel before the server starts directing new connections to a different channel. The server does not enforce any channel population limits, so users can still join a full channel; this number is merely a hint to the server to help with scalability.

      To determine which channel a server will direct new logins to, the server searches for the first channel with fewer than the number of users specified in the MaxChannelPopulation option, starting with channel number one.  If all existing channels are full, a new one is created.

      The default value is to allow the maximum number of users allowed on the server onto a single channel.

      BackupServer (port) (password)

      Inclusion of this keyword causes the UserServer to act as a backup UserServer for another UserServer.  The other UserServer should use the BackupClient keyword with the same port and password specified here.  The backup UserServer will listen for connections from the client UserServer on the specified port and will authenticate the client UserServer using the password.  If the connection is lost for any reason, the backup UserServer will start listening for another connection on the same port.

      You cannot use both the BackupServer and BackupClient keywords in the same configuration file.

      This feature is disabled by default.
       

      BackupClient (host) (port) (password)

      Inclusion of this keyword causes the UserServer to act as a backup client to a UserServer running on the specified host.  The other UserServer should use the BackupServer keyword with the same port and password specified here.  The backup client will periodically attempt to connect to the backup server on the specified port using the password until it succeeds.  If the connection is lost for any reason, the backup client will periodically attempt to reconnect.

      You cannot use both the BackupServer and BackupClient keywords in the same configuration file.

      This feature is disabled by default.
       

      ChannelSuffix (suffix)

      This keyword specifies the suffix which will be appended to channel names allocated by the UserServer.  The suffix is used to differentiate between identical server world channels on two connected UserServers.  The suffix is separated from the channel name by a semicolon (;).  The channel suffix is only meaningful in a redundant UserServer configuration.  The suffix specified for the backup server and the backup client should be different.

      By default, the backup client uses a suffix of "1" and the backup server uses a suffix of "2".

      Logging

      Inclusion of this keyword enables logging of every command that passes over the network (both input and output), as well as logging of various other information. It is primarily intended to be used for debugging. All of this debugging information is appended to the ".out" file not the ".log" file.

      Logging can also be toggled on and off while the UserServer is running by sending the server SIGUSR1:

        kill -USR1 pid

      Use logging carefully, it generates a very large amount of output to the UserServer output file. Logging functionality and this keyword are only available in UserServers that have been compiled for Worlds' internal use.

      This feature is disabled by default.

      InternalHttpServer
      This is the base URL of the machine to use for handling HTTP requests for the internal version of Gamma.  For example:  http://dev.worlds.net

      ExternalHttpServer
      This is the base URL of the machine to use for handling static HTTP requests for the release (i.e. external) version of Gamma.  For example: http://www-static.us.worlds.net

      ScriptServer
      Similar to ExternalHttpServer, this is the URL of the directory where server scripts should be executed.  This is for things like the registration script and various other maintenance scripts.  Example:  http://www-dynamic.us.worlds.net/cgi-bin

      BindAddr (UserServer only)
      Used when you wish to run two UserServers on a single multi-homed machine. This is really only useful for redirecting traffic on one of the UserServers to a set of remote RoomServers.

      SmtpServer
      The SMTP server to use to connect to for sending WorldsMail.

      MailDomain
      The DNS domain to use in the "from" address when sending WorldsMail.

      Appendix III: Database Schema

      Detailed documentation for SQL and SQLPlus can be found on a variety of sources, including Oracle's web site.  For quick reference, here are a few of the most common SQL commands:

      SELECT: Select clause tells Oracle which column you want.

      FROM: From clause tells Oracle the name of the table or tables those columns are in.

      WHERE: Where clause tells Oracle what qualifiers you'd like to put on the information it is selecting for you.

      ORDER BY: Order by clause tells Oracle what column(s) you want the returned information sorted by.
       

      The UserServer Database

      The UserServer maintains two databases - the user database (three tables), and the serial number database (one table). Each of these tables is set up to allow for relevant queries at runtime. The key to the user database tables is the username field, but queries can be formed based on other fields as well.

      The SerialNumbers Table

      The SerialNumbers table contains a record for every valid serial number. It is initialized with a set of serial numbers by a WorldServer administrator. A user will register by providing a valid serial number that matches an unused table entry. The serial number must be distributed with the client software or in some other way, because it will be required for all registrations from the client. The serial number record contains the following information:
       

      serialNumber VARCHAR2(20)NOTNULL,UNIQUE The user's serial number 
      userName VARCHAR2(50)NOTNULL The user name with case intact 
      serialStatus VARCHAR2(50)NOTNULL One of {SERIAL_FREE, SERIAL_USED} 

      The values defined for serialStatus are:

      0 = SERIAL_FREE
      1 = SERIAL_USED

      The SerialNumbers table will be initialized with a set of serial numbers by a WorldServer administrator. The serialStatus column should be initialized to SERIAL_FREE at this time (this will be done for you when you create serial numbers). A user will then register via the client by providing a valid serial number. The UserServer will set serialStatus to SERIAL_USED upon successful user registration with a given serial number, and enter their username in the userName field.

      The included program SerialGen can generate a list of serial numbers based on a seed and tagged by prefix. The program runs in the C-shell and produces three output files: an SQL script that you can use to directly modify the SerialNumbers table, a master list as a text table for administration purposes, and a separate text table for use in production of the serial numbers to be given to client end users. See Generating Serial Numbers.

      The UserRegistration Table

      The UserRegistration table contains a record for every registered user. The record holds the following information:
       

      userNameLower VARCHAR2(50) NOT NULL The user name in all lower case. 
      userName VARCHAR2(50) NOT NULL The user name with case intact. 
      serialNumber VARCHAR2(20) NOT NULL The user's serial number. 
      password VARCHAR2(20) NOT NULL The user's password. 
      clientVersion VARCHAR2(20) NOT NULL The user's client software version. 
      accountStatus NUMBER(1) NOT NULL, One of {ACCOUNT_ACTIVE, ACCOUNT_INACTIVE}. 
      registrationDate DATE NOT NULL The date and time the user registered. 
      timesOn NUMBER(10) NOT NULL The number of times the user has logged on since registration. 
      totalMinutes NUMBER(10) NOT NULL The number of minutes the user has been logged on since registration. 
      userPrivileges NUMBER(3) NOT NULL The system privileges assigned to this user. 

       

      AccountStatus allowed values:

      The values defined for accountStatus include:

           0 = ACCOUNT_INACTIVE
      
           1 = ACCOUNT_ACTIVE

      The WorldServer will set accountStatus to ACCOUNT_ACTIVE upon successful user registration. The WorldServer administrator may deactivate an account by setting accountStatus to ACCOUNT_INACTIVE.

      userPrivileges allowed values:

      The values defined for userPrivileges include:

           0 = No privileges 
      
           1 = PRIV_BUILD - the user may dynamically register rooms 
      
           2 = PRIV_BROADCAST - the user may broadcast text 
      
           4 = PRIV_PROPERTY - the user may retrieve and set all properties of any object 
      
           3 = PRIV_BUILD and PRIV_BROADCAST 
      
           5 = PRIV_BUILD and PRIV_PROPERTY 
      
           6 = PRIV_BROADCAST and PRIV_PROPERTY 
      
           7 = PRIV_BUILD and PRIV_BROADCAST and PRIV_PROPERTY

      The WorldServer will set an authenticated user's privilege level to the value given in this field when the user logs on. This privilege level is communicated to all RoomServers the user connects to. To take effect, the value must be changed while the user is logged off, otherwise it will only become effective at the next login.

      The UserProperties Table

      The UserProperties table is used to store persistent user properties. These are accessed every time a user logs in, and they may also be used to form the reply for a "finger" operation. The UserProperties table contains the following columns:
       

      userName VARCHAR2(50) NOT NULL The user name with case intact 
      propertyId NUMBER(3) NOT NULL The property identifier. 
      propertyFlags NUMBER(3) NOT NULL Each property has a PropertyFlags field that defines certain aspects of the property. 
      propertyAccess NUMBER(3) NOT NULL Defines access restrictions on the property. 
      propertyStringValue VARCHAR2(255) NOT NULL The value of the property when it is a string.
      propertyBinaryValue RAW(255)  The value of the property when it is binary data.

      The setting of the PropertyFlag determines which column the value of the property is stored in. When the value of the property is a string and is stored in propertyStringValue, the propertyBinaryValue will be NULL. When the value of the property is binary data and is stored in propertyBinaryValue, the propertyStringValue will be NULL. Properties stored in propertyStringValue will be readable using the Select command in SQLplus. Properties stored in propertyBinaryValue will appear encoded in hexadecimal when selected using SQLplus.

      The values in the propertyFlags and propertyAccess as seen when doing a select on these columns are as follows:

      propertyFlags

        128 = Store in DB, no auto-update, not a finger property, stored in propertyStringValue. 
      
        144 = Store in DB, no auto-update, not a finger property, stored in propertyBinaryValue. 
      
        160 = Store in DB, no auto-update, finger property, stored in propertyStringValue. 
      
        176 = Store in DB, no auto-update, finger property, stored in propertyBinaryValue. 
      
        192 = Store in DB, auto-update, not a finger property, stored in propertyStringValue. 
      
        208 = Store in DB, auto-update, not a finger property, stored in propertyBinaryValue. 
      
        224 = Store in DB, auto-update, finger property, stored in propertyStringValue.
      
        240 = Store in DB, auto-update, finger property, stored in propertyBinaryValue.

       

      propertyAccess

        0 = Public write, public read. 
      
        1 = Possessor write, public read. 
      
        2 = Public write, owner read. 
      
        3 = Possessor write, owner read.

      UserProperties can be used to store persistent user data from session to session, including potentially shared-state properties related to users. Properties and their Id's need to be coordinated between the server and the client (or the client's underlying language). Properties are generally meaningless to the server, except for the reserved properties for session tracking etc. It is up to the client to interpret the property values correctly.

      In Gamma, properties are exchanged with the client by using attributes. A full discussion of properties, attributes and using shared objects in Gamma will be included in a future document.

      PropertyId:

      Each property has a PropertyId field that is one byte. Up to 255 PropertyIds may be defined. Zero is reserved and is not a valid PropertyId. Some of these properties are shared between objects (especially those relating to session control), but others may be defined on a per-object basis. Currently defined propertyIds include:

      Session Properties:

      1 = Application Name (string)

      2 = User Name (string)

      3 = Protocol Number (string)

      4 = Error Number (string)

      6 = Password (string)

      8 = Update Interval (string)

      9 = Client Version (string)

      10 = Serial Number (string)

      12 = Logon/Logoff Flag (string)

      13 = Permitted Session Duration (string)

      14 = Guest User Flag (string)

      15 = Server Type (string)

      User Properties:

      5 = Avatar Bitmap (string)

      7 = Avatar Updates Requested (string)

      9 = Client Version (string)

      11 = Email Address (string)

      The client software can require users to register with their email addresses as an optional field. For example, in Worlds Chat, the client sends the email address as VAR_EMAIL. VAR_EMAIL in turn is understood by the server to be a property that is stored in the Properties database, as Property ID 11, with the email itself stored in PropertyStringValue as a string. Since this table is also keyed to the username, you can correlate tables of email addresses as needed using SQL.

      To extract an email address for a given user:

      select propertyStringValue from UserProperties where userName='John Doe' and propertyId=11;

      To extract a list of all recorded email addresses:

      select userName, propertyStringValue from UserProperties
      where propertyId=11
      order by userName;

      You should note however that many database table queries, particularly in the RoomProperties table, might give you data that is stored mostly in binary form, and that cannot be properly interpreted by standard SQL. What you'll get in this case is often meaningless hexadecimal, which could be unicode text or just raw data.