I'm working on a 3D web game with client-side prediction, etc. I have implemented interpolation for my entities, but it seems a bit laggy sometimes even on localhost. First I will describe the algorithm, and then I will describe the problem.
Interpolation algorithm:
1) SERVER sends to all players (at 20 ticks per sec):
1.1) positions and rotations of all players
1.2) server time at the moment of sending this data (for example `serverTime == Date.now()` (it is calculated a little differently, but the value is roughly the same as `Date.now()`; the error is 20 ms), that calculates every server tick)
2) CLIENT receives all data and:
3) Saves received `serverTime` to global variable named `localServerTime`
4) Pushes player's positions and rotations to their buffers (f.e. player1 has `buffer1: { time: number, position: Vector3, rotation: Vector2 }[]`, so we push received(from server) player1 position and rotation to the buffer1: `buffer1.push({ time: localServerTime, position: receivesPlayer1Pos, rotaiton: receivedPlayer1Rotation })`
5) CLIENT executes local game loop and changes `localServerTime`: `localServerTime += deltaMs`
6) CLIENT interpolates all other players positions and rotations like this:
7) We will interpolate players with offset == 100: `INTERPOLATION_OFFSET_MS = 100`, so find current lerp time: `currentLerpTime = localServerTime - INTERPOLATION_OFFSET_MS `
8) For all other players:
9) I will consider `player1`: get `player1`'s buffer: `buffer1` and get state interpolate FROM(`stateInterpolateFrom`) and state interpolate TO(`stateInterpolateTo`) ( we will find this two states by `currentLerpTime`, so `stateInterpolateFrom.time < currentLerpTime` and `stateInterpolateTo.time >= currentLerpTime`).
10) Then we will find alpha(number, that is in range 0-1): `alpha = (currentLerpTime - stateInterpolateFrom.time) / (stateInterpolateTo.time - stateInterpolateFrom.time)`.
11) Finally, i will interpolate position and rotation: `player1.position = lerp(stateInterpolateFrom.position, stateInterpolateTo.position, alpha)`, same for rotation
------------------------------------------
My problem here is the following: sometimes I have small lags that arise for some reason. I read that I need to synchronize time; I read a bunch of articles about entity interpolation, and the general principle is described there, but I did not find an algorithm about time synchronization anywhere, so I am asking for help.
I realized that the matter is in the `localServerTime`, I calculate it incorrectly, but I don’t understand what exactly needs to be done, how to calculate it. If anyone has any relevant articles to put things in place, I would be very happy if you share them.
P.S. On the client I have variable `syncedServerTimeMs`, when player connecting to the server, server send data: `{ serverTime: number, serverTick: number}` and client calculates `syncedServerTimeMs`, so I can exactly say the serverTime when I need on it. In the client loop I update `syncedServerTimeMs`: `syncedServerTimeMs += deltaMs`, maybe I must use this variable somehow?