Recently I revisited the idea of throwing out acknowledged moves and replaying a local simulation and it dawned on me that the client’s local world time and the server’s world time would likely be different because of a world start time delta. In this lecture, when we decide which moves to throw out based on time, we’re actually comparing the client’s local world time to the server’s world time. Since we’re essentially starting both up at the same time using the editor’s built-in server/client feature, the difference in world time is likely very small.
However, in a case where client and server might be a considerable distance from each other, I’m wondering what the effect would be in our Move.Time comparison. I attempted to draw this out and I think if the client and server timelines deviated too far due to a large enough start-up time delta, the server might actually appear to be running ahead of the client, and thus all moves would be thrown out and we might get some ‘jerk’ because we’re still resetting the actor to an out-of-date position.
Again this is all theoretical - client and server world times may never deviate far enough to matter. However, I did want to point out some interesting functions in GameState:
float AGameStateBase::GetServerWorldTimeSeconds() const
{
UWorld* World = GetWorld();
if (World)
{
return World->GetTimeSeconds() + ServerWorldTimeSecondsDelta;
}
return 0.f;
}
void AGameStateBase::UpdateServerTimeSeconds()
{
UWorld* World = GetWorld();
if (World)
{
ReplicatedWorldTimeSeconds = World->GetTimeSeconds();
}
}
void AGameStateBase::OnRep_ReplicatedWorldTimeSeconds()
{
UWorld* World = GetWorld();
if (World)
{
ServerWorldTimeSecondsDelta = ReplicatedWorldTimeSeconds - World->GetTimeSeconds();
}
}
As well as this property in GameStateBase.h:
/** Server TimeSeconds. Useful for syncing up animation and gameplay. */
UPROPERTY(Transient, ReplicatedUsing=OnRep_ReplicatedWorldTimeSeconds)
float ReplicatedWorldTimeSeconds;
In theory, if we’re the client we could use GetServerWorldTimeSeconds()
instead of GetWorld()->TimeSeconds
, and then when we’re comparing move times in ClearAcknowledgedMoves
we’d actually be comparing two times that exist relative to the server’s timeline.
Again it’s hard to determine how much this would matter in a real-world simulation without observing the extreme cases. As a side project, I was thinking about adding some logic to KrazyKarts to dump time and position to a csv file so I can actually plot the movement-over-time graphs in a spreadsheet and observe the effects of using different timelines. I’ll post the results if I find anything interesting.
Anyway, I wanted to bring this up for discussion if anybody is interested. I’d love to hear your feedback.