Jump to: navigation, search

Replication is an optimized mechanism for communicating data between the client and area server, or between area servers. It allows nodes on one server to be replicated on a different one in real-time. This can be used to provide the illusion of a seamless world as players move from one area to another.




Massive Multiplayer Online games depend on the communication of information between servers and clients, but the nature of things is that there is a finite amount of communication traffic that can be sent to a client.

Utilizing bandwidth efficiently is important from an operating cost standpoint, and for maintaining a good experience for the player whose bandwidth limits may vary greatly. Consequently, one of the hallmarks of a good MMO platform is the ability to move data between client and server in a flexible and automated fashion with support for the ability to shape and prioritize communication traffic.

Replication is a highly optimized mechanism for communicating between the client and the area server, and also between area servers. Essentially, Replication allows data represented as Nodes in one GOM (client or server) to be replicated (updated) in another GOM (client or server) in an efficient manner.

HeroEngine's replication mechanics are under HSL script control, which allows you absolute control over how, when and to whom information is communicated. Using whatever game logic makes sense, a script introduces clients to the Nodes on the area server and, following introduction, changes to the fields of these nodes are communicated to the clients in an optimal way. This same mechanism can also be used for communicating between area servers.
There are four key elements to replication:

What problem(s) does this solve?

What problem(s) does this not solve?


Replication can be used any time data needs to be communicated between area servers and clients, or between area servers. The following examples show how it can be used.

Character Movement

The Seamless world implementation for HeroEngine will leverage the Replication capabilities of the engine to handle proxying of information across area boundaries.

Area Server Proxying

Area Server Load Splitting


There are four key components to Replication:

Replication Group

A Replication Group is represented by a node in the area server GOM. The Group is controlled by changing the field values with HeroScript. Using a Replication Group node is explained on the Replication Script Interface page.

Replication parameters

The parameters which control replication are set in the DOM. The Field Replication Parameters control destination field and relative priority of updates. Class Replication Parameters control which fields on the class are replicated and the destination class.

Spatial Awareness System

Similar to the replication group, a Spatial Awareness System is a node in the GOM created from a specific class. Setting the fields on this node through script controls the behavior of the system.

Bandwidth Control

Replication traffic is designed to attenuate at the bandwidth limit. The exact limits for each client are controllable through script, as described by Bandwidth Control.


Field updates which are sent by the replication system are prioritized. When a replication message is created, the highest priority updates are sent. The bandwidth limit may restrict the amount of updates which can be sent. When the total amount of updates exceeds the bandwidth available, the Replication Priority controls which fields are sent and which are delayed.


Example communication

Network Traffic Example

The serialization of data sent by the replication system is optimized to minimize the size of replication packets (bit efficient). For example, dictionary-based lookups reduce the number of bytes necessary to identify 8-byte NODE ids and FIELD ids to just one byte. When sending integer values, a 7-bit compression code reduces values from 0 to 127 to just one byte. Floating point values occupy 4 bytes without quantization; Vector3 positions would be 12 bytes.

Scenario: sending 5 nodes' position and heading updates

For the purposes of this example, we are ignoring the physical network and logical session overhead of the connections between client and server; although, the more frequent a network packet is sent, the more the overhead can matter. (Windows Dial-up Networking uses PPP, broadband generally uses PPP-over-ethernet encapsulation or straight ethernet, both of which have a 20-40 byte overhead per packet. At 4000 bytes per second desired throughput, and 10 packets per second, this can result in a network overhead of 5%-10%, and either a reduction in throughput to 3600 bytes per second, or an increase in actual network traffic to 4400 bytes per second! Worst case, of course.)

This scenario demonstrates the estimated bandwidth required to send position and heading updates for five entities.

 byte 0:  replication channel ID
 byte 1:  replication group #.
 byte 2:  node group count (1 byte, since there might be only 5 or 6 nodes worth of replication data in this one payload)
 byte 3:    node #1 ID lookup (with only 80 characters to track, 1 byte suffices for the dictionary lookup)
 byte 4:    node #1 field count 2 (sending a limited number of fields in the first place, fits in 1 byte)
 byte 5:      node #1 field #1 ID (sending a restricted list of field ID numbers, 1 byte suffices for dictionary lookup)
 byte 6-17:   node #1 field #1 value for position (vec3 of float)
 byte 18:     node #1 field #2 ID (heading)
 byte 19-22:  node #1 field #2 value for rotation (float)
 byte 23:   node #2 ID lookup 
 byte 24:   node #2 field count 2 
 byte 25:     node #2 field #1 ID 
 byte 26-37:  node #2 field #1 value for position 
 byte 38:     node #2 field #2 ID 
 byte 39-42:  node #2 field #2 value for rotation 
 byte 43:   node #3 ID lookup 
 byte 44:   node #3 field count 2 
 byte 45:     node #3 field #1 ID 
 byte 46-57:  node #3 field #1 value for position 
 byte 58:     node #3 field #2 ID 
 byte 59-62:  node #3 field #2 value for rotation 
 byte 63:   node #4 ID lookup 
 byte 64:   node #4 field count 2 
 byte 65:     node #4 field #1 ID 
 byte 66-77:  node #4 field #1 value for position 
 byte 78:     node #4 field #2 ID 
 byte 78-82:  node #4 field #2 value for rotation 
 byte 83:   node #5 ID lookup 
 byte 84:   node #5 field count 2 
 byte 85:     node #5 field #1 ID 
 byte 86-97:  node #5 field #1 value for position 
 byte 98:     node #5 field #2 ID 
 byte 99-102: node #5 field #2 value for rotation 
 bytes 103-200: and so on...

Replication Tracing

Replication Tracing provides visibility into the information being received by the client by virtue of replication or remote call traffic. It does not include tracing for traffic related to repository downloads.

repTrace <dudeID|0> - Enable replication trace logging for yourself (0) or the specified client (designated by a Dude ID number). Logging is placed in \ProgramData\HeroEngine\logs in a file named ReplicationTrace. When the reptrace is started, there will be no specific feedback to the Console Panel. To turn the trace logging off, type UnRepTrace <id>

Identifiers are internal bit efficient representations and do not map DOM/GOM IDs, they represent a connection specific (i.e. between the server and a specific client) dictionary agreed upon for the purpose of looking up IDs for replication events. Consequently, the identifiers for one client bear absolutely NO relation to those for another client.
Client - identifies a client
Group - identifies a replication group
Node - identifies a particular node relative to a particular replication group
Field - identifies a specific field which is translated to a field name in logs
Replication tracing logs a number of events:
GroupCreated, client, group - Issued when a replication group is introduced to the client
GroupRemoved, client, group - Issued when a replication group is torn down
DistanceUpdated,client, group, distance - Issued when Spatial Awareness adjusts the entity position used by the replication group
NodeCreated, client, group, node - Issued when a node has been added to a replication group
NodeRemoved, client, group, node - Issued when a node has been removed from a replication group
UpdateBegin, client, availableBandwidth, non-replicationBandwidthSpent - Issued at the beginning of an update frame displaying bandwidth available for the current frame and bandwidth spent by non-replication traffic (i.e. bandwidth already consumed by remote calls and other non-replication traffic out of what was available for the frame)
UpdateEnd, client, replicationBandwidthSpent - Issued at the end of an update frame
FieldUpdateBlocked, client, group, node, field - Issued when a field update could not be sent due the client not being ready to receive it
FieldUpdated, client, group, node, field, timestamp, size, currentPriority, deltaPriority, distanceFactor, lifetime - Issued when a field update is received by the Dude Server
FieldCoalesced, client, group, node, field, oldTimestamp, newTimestamp, deltaSize - Issued when an update for a field not yet sent is coalesced at the Dude Server as an new update comes in
FieldMarked, client, group, node, field, timestamp, effectivePriority, accumulatedPriority, dependent - Issued when a field is marked to be sent along with other fields of an atomic group
FieldSent, client, group, node, field, timestamp, size - Issued when the field update is sent to the client
ImmediateTraffic, client, group, size - Issued when immediate traffic is being sent (such as node introduction or disposal)
FieldDisposedImmediate, client, group, node, field, timestamp, size - Issued when a field update is disposed of as the result of an immediate update affecting that field
FieldDisposedTimeout, client, group, node, field, timestamp, size - Issued when a field update is disposed of as the result of failure to send the update prior to timeout
FieldDisposedNodeRemoved', client, group, node, field, timestamp, size - Issued when a field update is disposed of as the result of the node to which it belongs being removed from the replication
Remote call
bytes=<number of bytes> to=<destination method name> node=<destination node> from=<script:method> - Issued for a remote call to a method for a node
bytes=<number of bytes> to=<destination function> script=<destination script> from=<script:function> - Issued for a remote function call to the client

See also

Personal tools