The simulation frame represents an internal clock that every Client syncs with a Replication Server. This clock runs at a 60Hz frequency which means that the resolution of a single simulation frame is ~16ms.
There are 3 different simulation frame types used within the coherence:
The latest simulation frame received from the Replication Server. Accessible via CoherenceMonoBridge.NetworkTime.ServerSimulationFrame
.
Local Client simulation frame that progresses with local time. Accessible via CoherenceMonoBridge.NetworkTime.ClientSimulationFrame
.
Every Client tries to match the Client simulation frame with the Server simulation frame by continuously monitoring the distance between the two and adjusting the NetworkTime.NetworkTimeScale
based on the distance, ping, delta time, and several other factors starting from the first simulation frame captured when the client first connects in NetworkTime.ConnectionSimulationFrame
The Time.timeScale
is automatically set to the value of NetworkTime.NetworkTimeScale
if the CoherenceMonoBridge.controlTimeScale
is set to true (default value).
In perfect conditions, all Clients connected to a single session should have exactly the same ClientSimulationFrame
value at any point in the real-world time.
The value of the ClientSimulationFrame
can jump by more than 1 between two engine frames if the frame rate is low enough.
The Client simulation frame is used to timestamp any outgoing Entity changes to achieve a consistent view of the World for all players. The receiving side uses it for interpolation of the synced values.
Local simulation frame that progresses in user-controlled fixed steps. Accessible via CoherenceMonoBridge.ClientFixedSimulationFrame
.
By default, the fixed step value is set to the Time.fixedDeltaTime
.
Just like the basic Client simulation frame, it uses the NetworkTime.NetworkTimeScale
to correct the drift. The fixed simulation frame is used as a base for the fixed-step, network-driven simulation loop that is run via CoherenceMonoBridge.OnFixedNetworkUpdate
. This loop is used internally to power the CoherenceInput
and the GGPO code.
Unlike ClientSimulationFrame
the CoherenceMonoBridge.OnFixedNetworkUpdate
loop never skips frames - it is guaranteed to run for every single frame increment.