8.3. PiaClone Detailed Specifications

PiaClone - Guaranteeing That Data Arrives Safely

UnreliableCloneElement

Values shared using UnreliableCloneElement are not guaranteed to arrive at the receiving station.

ReliableCloneElement

Using ReliableCloneElement to share values guarantees that those values will eventually arrive at the receiving station.

However, values may not necessarily arrive in the order they were sent. If you set and sent three values 1, 2, and 3 (in that order), for example, the receiving station may only get values 1 and 3, skipping value 2.

When you use ReliableCloneElement to get values in the middle of a game, values automatically continue to be resent even if there have been no changes to the original values. This ensures that the receiving station can always get the latest values available.

If a station sending values with ReliableCloneElement unexpectedly disconnects from the session (it leaves the session while CloneProtocol is in a state other than STATE_INACTIVE), the remaining stations share the latest values they have to ensure that all the stations get the same values.

EventCloneElement

Using EventCloneElement guarantees that all events that occur while stations are connected are sent and received in the order in which they are issued.

For example, if events 1, 2, and 3 occur (in that order), other stations will get those events 1, 2, and 3 in that same order.

If you start receiving event values using EventCloneElement in the middle of the game, you are guaranteed to be able to get all future events, but you cannot get past events again.

If a station sending values with EventCloneElement unexpectedly disconnects from the session, the remaining stations automatically synchronize the event values they currently have. (They send each other all the event values they have received to ensure that all stations have the same event values.) If a station sending values with an instance of EventCloneElement registered to AtomicSharingClone unexpectedly disconnects from the session while other stations are trying to get the lock at the same time that the next event occurs, however, the stations may fail to synchronize their event values (all the stations may not necessarily have the same event values). When the failed synchronization is detected, the EventCloneElement::IsDropEvent() function returns true and the CloneProtocol::GetError() function returns ERROR_TYPE_DROP_EVENT. You can allow the game to continue as long as the dropped event was not significant to the game. If the dropped event was significant, however, stop CloneProtocol communications on this error. The session stills remains viable even after an unexpected station disconnect, so you do not necessarily need to end the session.

ReckoningCloneElement

With ReckoningCloneElement, you can specify whether certain sample values must be guaranteed to arrive at the receiving station as they are added to the sample value buffer to be sent. ReckoningCloneElement is intended as an alternative to UnreliableCloneElement and is designed on the assumption that sample values will be added as needed. Arrival of values is not as strictly guaranteed as with ReliableCloneElement.

Assume, for example, that the sample value buffer can hold three values and that among the sample values 1, 2, 3, 4, and 5, you specified that only value 2 must be guaranteed to arrive at the receiving station. After value 4 is added to the sample value buffer of the sending station, if values 2 and 4 have not arrived at the receiving station, value 2 will be resent by the sending station because you specified that it must arrive at the receiving station. If value 5 is added to the sample value buffer of the sending station before value 2 is resent, however, value 2 is pushed out of the buffer. After value 5 arrives at the receiving station, it will have received values 1, 3, and 5. Value 2 was skipped even though you specified that it was guaranteed to arrive. In summary, poor sample value buffer management can lead to issues even when guaranteeing the arrival of values using ReckoningCloneElement.

ReliableLargeCloneElement

Using ReliableLargeCloneElement to share values guarantees that those values will eventually arrive at the receiving station.

ReliableLargeCloneElement is basically the same as ReliableCloneElement, except for the fact that it can also receive larger quantities of data that would not fit into one packet.

Stopping Communications

When you remove a clone from an instance of CloneProtocol while still using that instance for communications, all necessary data is guaranteed to be sent before the clone is removed.

Using the CloneProtocol::Stop() function to stop communications ensures that all the necessary data is sent and received before communications are stopped.

Defining a Custom SerializePolicy Class in Your Application

In addition to using the prebuilt serialization methods, you can also define your own custom SerializePolicy class to use in your application. This can be useful, for example, if you have structures that are managed using clone elements and you want to remove, from the data that is sent, some fields that are only for alignment purposes to help reduce communication volume. Similarly, it can also be used to reduce communication volume if you have matrices that are managed using clone elements and some of them are just rotation matrices that you want to convert to quaternions when they are sent.

The following three functions must be defined in the class you create to serialize the type defined in Type.

 

static void Serialize(void* pBuffer, const Type& value);

This function serializes the data specified for value and writes it to pBuffer. Use the GetSize() function to get the size of the buffer to which this data will be written. The pBuffer parameter does not necessarily need to point to a 4-byte aligned buffer.

 

static void Deserialize(Type* pValue, const void* cpData);

This function loads the data specified for the cpData parameter, deserializes it, and then writes it to pValue. Use the GetSize() function to get the size of the buffer the data came from. cpData does not necessarily need to be 4-byte aligned. pValue will be aligned appropriately for use with the Type type as long as it was placed correctly in the clone element used for it.

 

static size_t GetSize();

This function returns the size of the serialized Type data. Serialization methods that allow the size of serialized data to change are not supported. This function must always return the same value when called on a particular chunk of serialized data. Also, the data cannot be serialized in a way that makes the size of the serialized data larger than the size returned by the CloneProtocol::GetElementSizeMax() function. Note that the size returned by the CloneProtocol::GetElementSizeMax() function may change depending on the network module you are using (such as PiaInet) and the MTU you specified in that module.

Compressing Sent and Received Messages

With PiaClone, sent and received messages can be compressed.

Compressing sent and received messages can reduce the number of communications, enable more data to be synchronized, and provide more stable communication, even if the amount of data you want to synchronize is the same.

However, compressing messages increases the amount of processing required for compression and decompression. Compression and decompression is performed by the common::Scheduler::Dispatch() function.

Use CloneProtocol::Setting::dataCompressionLevel to configure whether to use the compression functions.

Data compression uses zlib. If you attempt to compress data with little redundancy or an extremely small size, the compressed data might be larger than the original data.