NetworkTransform component uses Snapshot Interpolation.
When developing the new
NetworkTransform component, we've had two goals:
Make it stable: We needed something that can be used by thousands of projects without any surprises. Major hits already use Mirror and production, so we needed to be extremely careful to get this right.
Make it reusable: NetworkTransform is one of many components that need Snapshot Interpolation. Someone might need it for 3D / 2D Rigidbodies, Character Controllers and more. The algorithm however is always the same.
In order to achieve both goals, we decided to split the Snapshot Interpolation algorithm into a standalone class that can be used by anyone. It's raw C#, completely independent from Mirror & Unity. You can use it in Mirror, or in standalone servers or in different game engines.
In short, we wanted to solve the problem once and for all, so we have an algorithm that we can use for decades, no matter which engine.
Snapshot Interpolation is quite difficult to get right. Not only do we operate on two timelines (local & remote), we also have to deal with adverse network conditions like latency spikes, packet loss and scramble. To make matters worse, servers & clients might also be under heavy load and update on significantly different frequencies at times.
Developing Snapshot Interpolation as a standalone algorithm allows us to simulate the different scenarios without even running latency simulation or Mirror:
We can simulate exactly how the snapshot interpolation algorithm behaves if the remote is at t=5, we are at t=3 and we have three snapshots at t=0, 1, 2, while sampling through different points of the interpolation.
We can simulate what happens if someone only has two snapshots, reached the end of the interpolation and is still waiting for the next one.
We can simulate how the algorithm behaves if a mobile user switches back to the game after a 100s delay.
We can simulate extremely poor network conditions like 99% packet loss & scramble.
We can catch-up if the buffer gets too large.
And many more..
It's only a matter of computing with snapshots & parameters in, result out.intended
Please read through our
SnapshotInterpolation.cs code in Mirror to see the algorithm & helper functions, and then read through
NetworkTransform as usage example.
To summarize, there are a few key aspects:
The Snapshot interface: your
CharacterControllerSnapshot etc. structs have to implement that interface.
The Time Buffer, which is a
SortedList<timestamp, Snapshot> buffer. We offer several helper functions like
InsertIfNewEnough for convenience.
All of those functions are heavily covered with unit tests.
The Compute() algorithm: given a snapshot buffer, time, deltaTime and configuration parameters, it spits out the next interpolated Snapshot (if any).
This function comes with heavy test coverage, in fact it's likely the most tested function in all of Mirror.
We recommend using Mirror's LatencySimulationTransport to try it yourself, for example with our Benchmark demo. Even for poor networking conditions, Snapshot Interpolation will perform well as long as the bufferMultiplier is high enough.
NetworkTransform old vs. new comparison on Youtube (secret project).
See the original Pull Request progress videos. You can see how latency, loss & scramble are gradually solved with every added feature.
JesusLovsYooh old vs. new NetworkTransform (watch the left build, OG NT is the old one and NT 2k is the new one)