Multiplayer - Vaei/TurnInPlace GitHub Wiki
[!IMPORTANT] You don't need to do anything to make Turn In Place work with multiplayer. It works out of the box. This is intended for curious minds.
Server & Local Client Replication
Simulations are highly accurate and did not require additional replication to achieve between the server and local client.
The only potential to come out of sync is a result of UE5 itself compressing the rotation, so you could just barely trigger a turn on the server and then not complete it on the local client, however this is difficult to achieve even when trying to do so intentionally, and will never be more than that single step out of sync, and will re-sync automatically when the character moves.
Otherwise, the system is flawless.
Simulated Proxy Replication
The TurnOffset
is compressed to a uint16 and sent to simulated proxies who decompress and apply it. Even with high latency the simulated proxies turn in place smoothly, without jitter, and accurately.
The UTurnInPlace
handles the replication. Push-Model is used. UTurnInPlace::CompressSimulatedTurnOffset
handles the compression if required and UTurnInPlace::OnRep_SimulatedTurnOffset
handles the decompression.
The actual compression and decompression functionality is tucked away inside the FTurnInPlaceSimulatedReplication
struct.
Testing shows that even with high latency of 150ms+, the simulated proxies turn accurately and with great visual quality.
Character Movement Prediction
By default when frame rate exceeds 60fps the UCharacterMovementComponent
(CMC) combines moves to avoid flooding the server with a significant amount of information.
When a move is combined, we are first reset to the initial position. The initial position is set in FSavedMove_Character::SetInitialPosition
. By default the engine caches StartRotation
here and then sets the actor's rotation back to this in FSavedMove_Character::CombineWith
.
To handle this, we cache any Rotation that we apply to our Character as LastAppliedTurnYaw
, and we do the same, we set LastAppliedTurnYaw
in SetInitialPosition
and then in CombineWith
we append it to the StartRotation
.
If we didn't do this, we would see the local client losing roughly half it's rotation, so when the server turns 90 degrees, the local client would only turn ~45 degrees! It is a confusing system to wrap your head around, but its a vital part of the CMC's high performance.