PiaClone has three hierarchical layers. From smallest to largest, they are clone elements, clones, and CloneProtocol.
A clone element is the smallest unit by which game object states can be communicated between stations. Clone elements are used to synchronize (share) individual game object values between stations. Any of the following four template classes, which inherit from CloneElementBase, can be used to synchronize information between stations.
UnreliableCloneElement
Send the value set only once. Due to factors such as packet loss, the value may not arrive at the receiving station.
This class is best suited for sending values that are updated frequently.
ReliableCloneElement
Ensures the arrival of the latest set value, which makes sharing more reliable.
This class is best suited for sending values that are updated infrequently but need to be guaranteed to arrive at the receiving station.
EventCloneElement
Ensures the arrival of all of the various set values (events), which makes sharing more reliable.
This class is best suited for sending data that is sent only when a specific event occurs and that must arrive in the correct order.
ReckoningCloneElement
This class estimates the difference between sample values as they are changing. It allows you to reduce the frequency of changing sample values to reduce the number of communications sent. The ReckoningCloneElement class is defined in the PiaReckoning module.
This class is best suited for situations when sending data with UnreliableCloneElement would result in an unreasonably large number of communications, and there is some tolerance for error.
As with ReliableCloneElement, ensures the arrival of the latest set value, which makes sharing more reliable.
Used to share larger values that cannot fit in one packet, and so could not be used with ReliableCloneElement.
Clone elements can be used to store game object information such as vectors and matrices that represent position and orientation, and to store parameter structures associated with game objects.
Using too many clone elements to manage this data increases the number of communication headers and thereby increases the total volume of communications. Similarly, sending a single huge clone element that stores all of this data every time even if only some of the values have changed also increases total communication volume. In most cases, it is most efficient to use a single clone element for each group of values that are updated at the same time.
Clones comprise several clone elements and are used to manage rights that govern when values can be set to clone elements. Each of the following four classes, which also inherit from CloneBase, can be used to control these rights in a different way.
SendClone
Values can be set at any time.
You can use this class to send values from one station to another.
ReceiveClone
Values can never be set.
Use this class when receiving values sent using SendClone.
AtomicSharingClone
Values can only be set when other stations are successfully locked.
Use this class to give the station that set the values exclusive control over changing them in the future.
SequentialSharingClone
Any station can set values at any time.
Use this class when you want any of the stations to be able to set values at any time. EventCloneElement and ReckoningCloneElement cannot be added to this class because they do not ensure consistency of data between stations.
Clones can be used to manage game objects and game items on a per object or per item basis.
A CloneProtocol comprises several clones and is used to manage entire PiaClone instances.
CloneProtocol is only one of several protocols available in Pia. It provides the following features.
Clone elements are assigned an ID when they are added to a clone to make them easier to manage. Clone element IDs are managed separately for each clone. Although two clone elements may have the same ID if they are assigned to different clones, they are actually treated as separate objects.
Make sure that clone elements with the same ID in clones that share values have the same type (including for template parameters). If the clone elements have different types, your application may become unstable.
Similar to clone elements, clones are assigned an ID when they are added to an instance of CloneProtocol to make them easier to manage. Clone IDs are managed by clone type. Clones of different types may have the same ID, but they are actually treated as separate objects.
After values set to a SendClone are sent, they are obtained from a ReceiveClone with the same clone ID. SendClone IDs can be managed on a station-by-station basis. You can specify a SendClone ID from a particular station to get the values from the corresponding ReceiveClone. A ReceiveClone can also get values sent from a SendClone on the same station.
Each AtomicSharingClone and SequentialSharingClone has the same ID on all stations that share it.
The figure below shows an example of adding clones. In Figure 8-1. Adding Clones , five clones are registered to separate stations. Each clone has same ID of 1, but each clone is treated as a separate object because it has a different type or because it has a different SendStationIndex (for the ReceiveClone). Each clone has two clone elements (with the same IDs within each clone) that are used to share values between the stations.
For example, consider the situation where a value of 100 is set in an UnreliableCloneElement, and Id:1 is registered to a SendClone with Id:1 at STATION_INDEX_1. To retrieve the value of 100 from the UnreliableCloneElement, Id:1 must be in the ReceiveClone with Id:1 at SendStationIndex:STATION_INDEX_1 on each station.
This section describes how each of the clone elements would actually be used in games.
ReliableCloneElement and EventCloneElement differ as follows.
ReliableCloneElement does not resend old values, even if there are players who have not received them. It only sends the latest value. EventCloneElement reliably delivers all set values in the correct order. The amount of communication is significantly greater for EventCloneElement than for ReliableCloneElement.
This section describes how each of the clones would actually be used in games.
AtomicSharingClone and SequentialSharingClone differ as follows.
With AtomicSharingClone, the stations that can set values can be fixed with locks. For example, it can be used for cases like issuing an event when an item that only one person can have is taken or setting the position of where that item is taken. With SequentialSharingClone, there are no locks from any station, and the values can be set. It can be used when multiple stations can all set a value at the same time, and all that matters is the final value. The amount of communication is significantly greater for AtomicSharingClone than for SequentialSharingClone, and the delay is longer due to waiting for locks to be released.