Let's assume each client sends a packet every 0.05 seconds. (rate = 20)
Server update tickrate is 60 and it sends data back to client every 1 / 30 seconds.
Now client A has 50ms ping time and it sent each data at [A]5, [B]5.05, [C]5.10 second.
But due to some networking issue, server received each data at [A]5.05(good), [B]5.10(good), [C]5.18(bad! it delayed 0.03 seconds.)
When server get the packet [A] at 5.05 seconds, since each packet contains client data(like commands) for 0.05 seconds, it updates the entity based on this [A] packet for 0.05 seconds. after that, server time is now 5.10. and the next packet, [B] is already arrived so server just can keep updating.
At 5.15, now server has to update the entity with next packet, which is C, but there's no packet! Server has to wait for 0.03 seconds till next packet will be arrived. now, server is behind 0.03 seconds from client. sync failed.
I have two idea for solving this problem.
Server maintains its own client's time and sends back to client. For client side, when there is heavy desync between client and server, the client syncs to the server time.
Solution 1 is still applied. but there is one more. like entity-interpolation, there is packet-interpolation. Client sends each packets every t seconds which is (t = [SEND-TICKRATE + CLIENT-LAG]) . It means server gets next packet after [t + LATENCY] seconds which is always larger than SEND-TICKRATE, 0.05 in this assumption.
So when server gets packet, it doesn't update it immediately but waits for some time (like 0.03 ~ 0.05 seconds). Now server has next packet with a high probability.
I think Solution 2 is good. But the drawback is, client renders other player's data behind [RTT + Entity-Interpolation time + Server packet Interpolation time], so for a fast-paced-game, Shot-behind-the-wall will more happen.
What technique is used in other fast-pace-game like league of legends or overwatch?