Snapshot deltas
The snap_items page already explains a bit what deltas are.
But this page is a full deep dive into how exactly the deltas work.
The network messages
NETMSG_SNAP,
NETMSG_SNAPEMPTY and
NETMSG_SNAPSINGLE
contain snapshots which represent the current game state.
Snapshot data layout
The NETMSG_SNAPEMPTY has no payload. And NETMSG_SNAP contains a partial snap. And NETMSG_SNAPSINGLE contains a full snap. That full snap payload has the following format.Field name | Size in integers | Description |
---|---|---|
Num removed items | 1 | It determines the amount of snap item keys. in the removed items section. |
Num updated items | 1 | Also known as item deltas. It determines the amount of snap items in the updated items section. |
Unused zero | 1 |
The value of this field should be 0 at all times.
It is unused.
|
Removed items | The size will be exactly num removed items. | A list of single integers that represent the key of snap items from the delta snapshot (old snapshot). That should be removed from the snap. The removal is explicit while the keep is implicit. When the client unpacks a delta it should copy over all old items from the old snapshot to the new snapshot that were not removed or changed. |
Updated items | The size is dynamic. It will depend on the amount of snap items and their sizes | A list of full snap items. All their payload fields are a diff to the previous (delta) snapshot. The type id, id and size are sent as is. But the actual payload integers have to be undiffed by adding them to the payload of the delta snapshot to receive their real values. |
Dead reckoning
One thing to note here is that even if tees move in the world it might still not create an updated character snap item that is because of a concept called dead reckoning. It expects the client to compute the current tee position based on the known map, current gametick, old tee position/speed/gametick and physics. The server only sends character items when it has to because something changed that can not be predicted by the client.Snapshot delta tick
All three messages NETMSG_SNAP, NETMSG_SNAPEMPTY and NETMSG_SNAPSINGLE send a game tick and a delta tick. A bit of a trap is that the result of the subtraction game tick - delta_tick is also referred to as delta tick! So I will be calling the delta tick sent over the network raw delta tick and the result of game tick - delta_tick I will be calling real delta tickIf the real delta tick has the special value
-1
it is a delta against the empty snapshot. One could also interpret as it not being a delta at all.
Because doing a delta against nothing does nothing. Meaning all snap item values are the real absolute
correct values.
This real delta tick of
-1
is used at the beginning of every new connection
because there is no previous snap to delta against. But it usually will be actually used more than once.
That is because the server only creates deltas against snapshots the client confirmed to have received.
This confirm happens in the
NETMSG_INPUT message sent by the client.
It is the field ack game tick to be precise.
Because the server is faster at sending snapshots than the client to respond with the input message.
The server will send multiple snaps with a real delta tick of -1 against the empty snap.
The client will then ack the most recent snapshot it received as soon as it gets to sending the input message.
After the server received that ack it will send the next snap as a delta to that acknowledged tick.
Meaning the real delta tick will match the ack game tick
so the client is supposed to store the full snapshot and its tick to be able to perform the correct undiff of all items.
The result of the unpacked snapshot should again be stored by the client for furture delta unpacks.
Even if the server sends an NETMSG_SNAPEMPTY that contains no snap payload at all.
The client is still supposed to note down its game tick and ack it in the input message. And technically also "store" its "payload"
which just means creating a exact copy of the last known snapshot with a new gametick.