Skip to content
Darrin W. Cullop edited this page Feb 25, 2016 · 3 revisions

Network Protocol Specifications

Packet Types

Protocol Details

Introduction

All of Quake 2's network transmissions are done with UDP (User Datagram Protocol). UDP is a network transport that uses connectionless datagram sockets and is layered on top of IP. It is ideal for sending small network packets quickly. The downside is that it is unreliable. The sender has no way of knowing whether or not the receiver got the message. However, Q2's packet system has included a technique for making sure that critical information was received by including a sequence number with each packet.

Sequence Numbers

The Quake 2 protocol uses a system of sequence numbers to both label each packet, and acknowledge previously received packets. Each connection based packet contains two sequence numbers. The first one is the number of the current packet. The second one is the number of the last packet that was received from the other side. If a packet contains very important information, then it will be flagged as reliable. The flag is set by toggling bit 0x80000000 in the sequence number. This means that the sender wants an acknowledgement upon receipt of the packet. A packet is acknowledged by toggling the bit in the second sequence number of the next packet to be sent. If it does not get this acknowledgement, it will resend the packet until it does.

Example

In this example, a sequence number will have an 'R' next to it if it is reliable. This is easier to read than having the bit set.

Sender Sequence Number Last Received Notes
A 0001 0000 Sequence numbering starts at 1.
A 0002 0000
B 0001 0002 B tells A it last received sequence number 0002
B 0002 0002
A 0003 0002
B 0003 0003
A 0004R 0003 A sends B a reliable packet!
For some strange reason, the above packet gets lost
A 0005 0003 A sends B another packet that is not reliable.
B 0004R 0005 B sends A a reliable packet. A gets an acknowledgement of sequence number 0005, but it never received one for 0004R! Side A now knows that its reliable packet was lost in transit.
A 0006R 0004R A resends the reliable packet. The contents of this packet are the same as the contents of the packet with sequence number 0004R. Also, A tells B that it received the reliable packet that it sent.
B 0005 0006R B sends another packet to A, and acknowledges that it received the reliable packet.

When one side receives a packet that is marked "reliable", it should immediately send a packet back to acknowledge. If it doesn't have any data to send, it is okay to send a packet that has no message, just header information.

Delta Compression

What is Delta Compression?

In SVC_PACKETENTITIES and SVC_PLAYERINFO messages, not all of the fields are transmitted in order to reduce the amount of information sent. Instead of sending the client all of the information about the current frame, the server tells the client to start with a previous frame as a base, and then update only the things that have changed. This concept, which drastically reduces bandwidth consumption, is known as "delta compression".

How Delta Compression Works

Most entities in the game are initialized with a SVC_SPAWNBASELINE message. This provides the client with the "baseline" values of that particular object. If a baseline is not provided by the server, the client can assume one of all zero values. It is important to remember that there is no SVC_SPAWNBASELINE equivalent for SVC_PLAYERINFO; the client uses all zero values instead. As the game progresses, the client will receive combinations of SVC_FRAME, SVC_PLAYERINFO, and SVC_PACKETENTITIES messages.

The SVC_FRAME message has two pieces of information that are key to delta compression: the current frame and the delta reference frame. The current frame is the frame that the server is currently describing to the client. The delta reference frame is the frame that the current frame's values are based on. The SVC_PACKETENTITIES and the SVC_PLAYERINFO messages tell the client what is different about the objects in the current as opposed to from the delta reference frame.

Delta Reference Frames

How far back must the client keep track of its frames? The server can use any of the last 12 frames as the base of the next frame. The client, on the other hand, keeps track of the previous 16 frames so that it can compensate for random delays or other network glitches.

If the server cannot find a frame suitable for using as a delta reference, it will send the client a value of -1 for the delta reference frame. When this occurs, it is a signal to the client to use the original baseline values as the delta reference. Therefore, in addition to the previous 16 frames, the client also has to keep the original baseline state.

Please note that if a client issues a CL_NODELTA 1 command to the server, the server will ALWAYS use the original baseline values (the delta reference frame will always be -1).