Server Version 1.1 Release Notes
From Multiverse
| Multiverse Servers |
|
Installing • Installing on Linux • Running • Troubleshooting • FAQ • Release Notes • Updating • JMX Monitoring & Mgmt. |
| Infrastructure |
|
Platform Architecture • Registering a World • Proxy Server • Event Handling • World Manager • Voice Server |
| Messaging System |
|
Perception Messaging • Using Extension Messages • Message Marshalling • Multi-subject Messaging • Message Catalog |
| Object Architecture |
|
World Instancing • Server Object Search • Server Regions • Server Markers |
| Scalability and Performance |
| Reference |
|
File Layout • Property File • Logging • API |
Contents |
Platform Requirements
Minimimum requirements for the Multiverse servers are:
- Operating System: Windows XP, Windows Vista, or Linux (tested on Fedora core 4)
- Processor: Pentium 4 - 2.5GHz or greater
- RAM: 1GB or more
Upgrading to version 1.1
IMPORTANT: Due to changes in the server and client APIs, if you have previously run the Multiverse servers or written code, you must take steps to upgrade to version 1.1. See Upgrading to Version 1.1.
New features and changes
Server version
Information has been added to the server version:
- Build number
- Build string - Describes the release type (e.g. "Beta", "GA")
- Build date - Build date and time formatted as YYYYMMDD.HHMMSS - this is different from the old format.
The server package file name includes the build date and build number.
Each process logs the full version string during startup. The version and build information is available at runtime via multiverse.server.util.ServerVersion and as properties in multiverse.properties.
Startup scripts and properties
Server Java VM required
The Multiverse servers now require the "server Java Virtual machine", only available with the Java Development Kit (JDK), not the Java Runtime Engine (JRE). To run the servers, you must install the Sun JDK, and make sure your JAVA_HOME environment variable is set to the JDK installation directory, not the JRE installation directory.
For information on the differences between client and server VMs, see Sun's document Java Virtual Machines.
For information on how to set an environment variable, see Setting Environment Variables.
On Linux, or with Cygwin, enter this command:
which java
If this command returns a directory with "jdk" in the name, then you are OK. If it returns a directory with "jre" in the name, then you need to change the JAVA_HOME environment variable to the JDK installation directory.
If you try to run the Multiverse servers with the JRE, you will get startup errors like the following:
Starting domain server: Error: no `server' JVM at `c:\ProgramFiles\Java\jre1.5.0_08\bin\server\jvm.dll'. FAILED Starting combat server: Error: no `server' JVM at `c:\Program Files\Java\jre1.5.0_08\bin\server\jvm.dll'. FAILED ...
Changes to startup scripts
Made following changes to multiverse.sh and start-multiverse.bat:
- Added EXT_JAR (by default
worldname.jar) to classpath which allows you to load an additional world-specific JAR file. - Added
global_props.pyto the mobserver process.
Load testing properties
Two new properties control periodic logging of histograms of time-in-queue and processing time for messages handled by the proxy:
- multiverse.log_proxy_histograms: If true proxy server creates a pair of TimeHistogram instances to track time-in-queue and message processing time for messages handled by the proxy.
- multiverse.log_proxy_histograms_interval: How often histograms are logged. Default is 5000, or 5 seconds.
Client queuing policy properties
The client queuing policy limits the number of bytes and packets that the server keeps in queue for a single Client connection, to prevent an idle connection from consuming all the memory on the server. The policy is governed by two numbers:
- ProxyPlugin.maxMessagesBeforeConnectionReset: Maximum number of queued packets. If the client connection has more than this number of queued messages, the server resets the client connection. Default is 15000.
- ProxyPlugin.maxByteCountBeforeConnectionReset: Total number of bytes occupied by queued packets. If the client connection has more than this number of message queued bytes, the server resets the client connection. Default is 2000000 (2Mbytes).
Message and object system
These parts of the server have been extensively reworked. For a full description of the new architecture, see:
For details on API changes and how you may need to change your code, see Upgrading to Version 1.1.
Server message marshalling
Previously, the servers used Java serialization to create the on-the-wire representation of server messages. However, Java serialization results in a huge numbers of bytes for simple messages, and serializing and deserializing messages is very slow. The 1.1 server generates code at startup to marshal and unmarshal messages; that generated code runs very fast and results in very compact messages. See Server Message Marshalling for the details.
Namespaces and sub-objects
The 1.1 server release significantly simplifies the management of sub-objects that represent the per-plugin components of an object.
Sub-object OIDs eliminated
In previous releases, you had to deal with a different unique object ID (OID) for object
state within the plugin than the OID for the master object managed by the Object Manager. The reason for the distinct OIDs for plugin versions of object state was that the methods that wrote object state to the database distinguished objects solely by OID. To create or load a conceptual object, the Object Manager sent each plugin a message containing the master OID, and each plugin would create or load an Entity with an OID unique to the plugin, and send the new sub-object OID back to the Object Manager.
The the version 1.1 server database routines, in contrast, distinguish objects to be saved based on both the OID and the plugin's namespace object, so several plugins can store object state using the same OID as long as they use their own namespaces. The master OID sent by the Object Manager is the same OID by which the plugins refer to their object state.
Namespace objects
Namespaces are part of the Multiverse Object Architecture, and exist to partition the set of subobjects among the server plugins, so that each plugin can maintain it's own state for each object. The principal reason to have namespaces is that they provide a way to distinguish subobjects when storing their state in the database, since all subobjects have
the same OID.
In previous releases, namespaces were just strings, and were not stored in the database. In the version 1.1 server, the database stores both the namespace strings as well as small integers that provide a shorthand for the namespace strings. In plugin code, the namespace strings have been replaced by Namespace class instances, and all plugins agree on the set of namespaces, because during startup each server process encaches the mapping between namespace strings and namespace numbers by reading the mapping from the database. Namespaces can be created on the fly, and when they are, the new namespace string and number are saved in the database.
For more information, see Multiverse Object Architecture (Namespaces).
GenerateSubObjectHook
The EnginePlugin.GenerateSubObjectHook class is now static. To subclass it, define a constructor that takes a reference to the plugin object it is to be associated with. For an example, see AnimationPluginGenerateSubObjectHook in mv-home/src/mars/plugins/AnimationPlugin.java.
PropertyMessage
PropertyMessage has moved from being an inner class of WorldManagerClient to being its own class in multiverse.server.messages.
get/setObjectProperty
These methods have been moved to EnginePlugin and now support a namespace argument. The versions in WorldManagerClient are deprecated.
The APIs to set and retrieve object properties have been generalized; see Object Property APIs.
Recursive property maps
The property map mechanism has been generalized, by extending the number of basic types that can be properties, and allowing values to be lists, maps and sets of these basic types, or of other lists, maps and sets. See Nested Property Maps.
Name/Value Pairs for Static Objects
Static objects placed with the world editor now have their Name/Value pairs copied as properties to the WorldManager namespace when the object is created.
Networking
Network Performance Improvements
Optimized receive buffer allocation for RDP connections.
Client and server support TCP
In the 1.1 release, both the client and the server support TCP message transmission as well as RDP/UDP transmission. The
server always listens for both TCP and UDP connections; the client can use either protocol to connect. By default, as
in previous releases, the client connects using RDP. However, if the client is given the command-line argument --tcp,
it will connect over TCP. Both the client and the server must be running Release 1.1 or later to make use of this feature.
Packet aggregation works for both RDP and TCP
Packet Aggregation, which groups together messages for transmission in a single packet if they are sent within the packet aggregation
interval, works for both RDP and TCP connections. The property in multiverse.properties that sets the packet
aggregation interval is multiverse.packet_aggregation_interval. In the shipped multiverse.properties,
this property is commented out, meaning that packet aggregation will be turned on by default, with a aggregation interval
of 25ms. If you wish to turn packet aggregation off, you should uncomment this property and set its value to 0.
RDP packet delivery made reliable
RDP is built on UDP, and hence reliable delivery is not guaranteed by the underlying protocol. RDP itself does retransmission, but if there are more than 255 messages outstanding, additional ones will be dropped.
In Release 1.1 adds queueing to RDP to ensure that messages are not dropped until the queuing limits are exceeded. See Client queuing policy properties.
MARS
MARS Behaviors
PatrolBehavior has been moved from the core server into MARS.
PatrolBehavior, TeleporterBehavior and ChatResponseBehavior have been modified to make them easier to extend.
Quest Chaining
New method MarsQuest.setChainQuest(MarsQuest chainQuest) to automatically trigger a new quest when concluding a current quest.
Mobs and mob server
Mob Manager Object Creation
Created MobManagerPlugin.createObject(String templateName, Template override) and ObjectFactory.makeObject(Template override) to allow creation of mobs with an override template. This will allow custom object factories much greater control over object creation.
Mobs Supported By Collision Volumes
Mobs are now supported by collision volumes as they move. Typically, you will want to spawn your mob so that it's base is just above the collision volume that will support it. Like players, the mob can walk around between collision volumes and terrain and make the transition smoothly.
Mob Pathing Correctly Sets Mob Orientation
In 1.0 and earlier releases, mobs are displayed in the client with the appropriate orientation as they move, but prior to this release, the orientation of mobs on the server was always the identity quaternion, (0, 0, 0, 1). In this release, as mobs move their orientation on the server is updated correctly.
Moreover, you can examine the server's orientation for any mob by targeting the mob in the client and issuing the new command /orientation.
Note that for mobs that have never moved, the server's notion of their orientation is still the identity quaternion; if you want a different value, you must set it in your mob factory.
Other
Client Startup And Scene Transitions
The client has been changed so that the splash screen will remain displayed until all of the initial objects have been loaded, preventing the former "light show" at startup. Also, in any "scene change" that requires more than three objects to be loaded, the loading will be completed before the client switches the player to the new location. This is done while continuing rendering and in particular animation; the underlying mechanism is controlling when the client updates the list of renderable objects.
Character Creation
Properties from the server object for a character can now be sent to the client character selection script. To register what properties are sent, call MarsLoginPlugin.registerCharacterProperty() in character_factory.py
Directional Lights
Directional lights specified in the world editor now have names when sent to the client. The name for a directional light is "dirlight_<name>", where <name> is either the name of the region the light is placed on or "GLOBAL" for a global light.
Character Deletion
The login plugin now supports character deletion.
Animation Plugin
The animation system now allows multiple particle systems to be attached to a single attachment socket.
The animation plugin has been removed. All of its features are now supported by the coordinated effects system or other client-side scripts. To enable static animations or particle effects on objects, you will need to add StaticAnim.py to your asset repository and import it in WorldInit.py.
Static animations for objects may be set in templates with the "StaticAnim" property in the WorldManagerClient.NAMESPACE namespace.
Trade System
The Trade System has been reworked to exclusively use extension messages for communications between the client and server. All of the hardcoded logic in the client has been moved to the MarsTrade.py script.
Bug fixes
1.1 Update 2
- Fix add item bug: If you tried to add an item when the first subbag was full, it would fail because the item thought it was added to the first subbag.
- Fix null pointer in WorldNodeCorrectMessage: Seen when player died while moving.
- Fix ambient sounds heard by other players: A player's ambient sounds were sent as a subject message which was forwarded to all perceivers of the player. Added a target to the message so the proxy only forwards to the target player.
- Fix (harmless) terrain decal error: Terrain decals placed with the world editor caused a (harmless) error in the proxy log.
- Fix setObjectPropertyNoResponse(): This was the cause of problems with "/release" and clearing the loot flag.
- Fix loadObjectData(): Failed when the object does not exist. Fixed to return 'null' in this situation.
1.1 Update 1
- Fix bug creating custom Namespace: Under some circumstances, creation of a custom
Namespaceobject could result in a database error because multiple plugins try to create the sameNamespaceobject at the same time. This bug has been fixed.
- Make Namespace objects Serializable: If you create a custom class, and do not add the class to
config/worldname/worldmarshallers.txt, and that custom class refers to aNamespaceobject, and you send that custom object in a message, an error would be reported saying thatNamespaceis not a serializable class. TheNamespaceclass has been changed to implement the Serializable interface.
- Fix duplicate TargetedExtensionMessage: If you send a TargetedExtensionMessage to a player oid, the proxy sent the message twice to the client. Also improved proxy's extension message debug logs.
- Add mv.EXTENSION to mobserver and combat advertisements
- Fixed null pointer in CombatPlugin: If CombatClient.autoAttack() was called with a null target oid, it would cause a null pointer exception in the CombatPlugin.
Version 1.1
- multiverse.sh: changed the 'ps' command used in check_process and status_process to be '-e ho' so that we get status on processes not attached to a tty.
- Ambient sound regions: Previously, if an region's sound was audible to one player, it would be audible to all players, even if they were not in the region. This bug has been fixed so that region sounds are only audible to players inside the region.
- Messaging System: Fixed bug where large messages requiring more than 2 'writes' failed because the selection key was never updated. this exhibited itself when logging into an area which large number of objects.
- Spawn Messages for sructures: The world manager did not subscribe to MSG_TYPE_SPAWN_REQ messages for structures. This would prevent a structure from being spawned again if it was ever despawned. This has been fixed.
- Debug log messages: Fixed null pointer exception in PropertyMessage log message.
- Stability:
- Fix for QuadTree exception during spawn/despawn that causes logins to stop.
- Fix for deadlock during startup.
- Cleanup:
- Removed a lot of unused code.
- Deleted MarsPropertyMessage class as it is no longer used.
- Mob Pathing :
- Send path messages for newly perceived objects.
- Deschedule BaseBehavior pending tasks before executing a new command.
- Correctly interpolate the path when we get a path correction message.
- Spawn Generator: Fix use of incorrect time value when scheduling new spawns.
MARS
- Quest System:
- Fixed bug causing other completed quests to lose their state when concluding a quest.
- Fixed incorrect quest property state when moving around near perceiver boundaries.
- Fixed bug in collection quests that would prevent you from completing a quest with no collection goals.
- Combat Plugin:
- Combat Subobjects were not being persisted correctly when stat values changed.
- The
GenerateSubObjectHookfor theCombatPluginwas incorrectly namedAnimationPluginGenerateSubObjectHook. It has been renamed toCombatPluginGenerateSubObjectHook. - Fixed bug where two objects attacking each other could cause a deadlock.
- Ability System: Fix CreateItemAbility to generate objects correctly.
Known issues
- Kill quests do not work.
- bubble chat is broken (shows no text)
- Rarely, when the servers start, they will encounter a deadlock condition that will prevent them from initializsing properly. This occurs perhaps 2% of the time. If simply stop and restart them, they will initialize properly.
- If you shut down the servers when a client is connected, the client will not exit.
