I\'ve been reading this article from Valve that seems to explain the architecture of their multiplayer system. It seems they delay rendering by a couple ticks on the client so t
The server probably sends fully syncs (ie not deltas) periodically but less frequently. That's what I'm doing, at least.
From the linked article:
Usually full (non-delta) snapshots are only sent when a game starts or a client suffers from heavy packet loss for a couple of seconds. Clients can request a full snapshot manually with the cl_fullupdate command.
The deltas don't have to be relative to the previous message that was sent (by delta or snapshot). Instead, they would be relative to the last acknowledged state. So in the example above, the update at C could be a delta relative to A. Losing message B therefore becomes an inconvenience as the deltas are getting larger (and potentially error is accumulating) but eventually a message will get through and be acknowledged, and the server can start sending deltas relative to that updated state.
I'm guessing every once in a while they send a full snapshot. this is why laggy games involve people running at the wrong speed as delta frames are dropped, then "teleporting" to the correct position when a full snapshot comes in.
The complete state is synchronized periodically or upon client request. Interpolation/extrapolation can be used to compensate for packet loss while waiting for a full position update. Some events require reliabe delivery and a means of acknowledging receipt could be added.
Glenn Fiedler has some excellent articles about networked games on his blog.
This old article about Quake 3 networking sounds similar. The delta states represent changes from the last client acknowledged state that was received. So, if the server sees that the client is behind then the next delta will be created from the difference between the client state and the current server state.
Without looking at the implementation, I would imagine that packet C also includes the id of the packet it is the delta from (in this case, packet B).
When the client receives packet C following packet A, it will know that it hasn't seen packet B yet, and can consequently request a full update from the server.