Hi, I’m currently trying to understand how CharacterMovementComponent works.
From my understanding, UCharacterMovementComponent::ClientUpdatePositionAfterServerUpdate is used when client and server moves diverge and a correction issued from the server is necessary. Here’s my question: why is it that the character reproduces any moves sent from the server instead of the server simply directly updating the characters position, velocity, acceleration, movement state, etc.? Wouldn’t this be a simpler solution or am I misunderstanding something?
Specifically, I’m interested about this part:
// Replay moves that have not yet been acked.
UE_LOG(LogNetPlayerMovement, Verbose, TEXT("ClientUpdatePositionAfterServerUpdate Replaying %d Moves, starting at Timestamp %f"), ClientData->SavedMoves.Num(), ClientData->SavedMoves[0]->TimeStamp);
for (int32 i=0; i<ClientData->SavedMoves.Num(); i++)
{
FSavedMove_Character* const CurrentMove = ClientData->SavedMoves[i].Get();
checkSlow(CurrentMove != nullptr);
CurrentMove->PrepMoveFor(CharacterOwner);
MoveAutonomous(CurrentMove->TimeStamp, CurrentMove->DeltaTime, CurrentMove->GetCompressedFlags(), CurrentMove->Acceleration);
CurrentMove->PostUpdate(CharacterOwner, FSavedMove_Character::PostUpdate_Replay);
}
Long answer: First of all, the moves that are replayed are all client moves, the server doesn’t send moves to the client. The client saves all moves that are executed locally up to a certain amount (I think by default the last 100 moves or so are saved). Let’s say there is a latency of 100 ms between client and server and something went wrong on the client: the server will notice the error only 100 ms after it happened on the client, meanwhile the client keeps on playing with the erroneous state. Sending the correction data back to the client will take another 100 ms so when the client receives the packet he is already 200 ms ahead of when the error originally occured. If you just set the client to that corrected state now he will teleport 200 ms back in time which the player would notice as a massive teleport, even if the error was just very minor at the time when it originally happened. Instead, after the correction, we also replay all of the moves that the client has executed within the 200 ms since the error occured. That way, the player doesn’t lose all the input of the last 200 ms and, depending on the circumstances, may not even notice the correction at all.