Server message format

From ioquake3 wiki
Jump to: navigation, search

At its basic level, a server message consists of the ID of the last client command that it received along with a list of server operations. There are several different types of server operations. To identify which type of operation it is, each operation in the list starts with an 8-bit identifier code. The last operation in the list is identified with a special EOF code.

Structures

top-level format

32 bits ID of last client command received
(<nop> | <gamestate> | <server-command> | <download> | <snapshot>)*
8 bits 0x08 EOF indicator


nop

8 bits 0x01 nop indicator


gamestate

8 bits 0x02 gamestate indicator
32 bits server's last command ID
(<configstring> | <baseline>)*
8 bits 0x08 EOF indicator
32 bits client ID
32 bits randomly generated checksum seed value


configstring

8 bits 0x03 configstring indicator
16 bits config ID
string config value


baseline

8 bits 0x04 baseline indicator
<entity>


server-command

8 bits 0x05 server-command indicator
32 bits command ID
string command value


download

8 bits 0x06 download indicator
16 bits block number
if {block number} == 0x0000: // first block
32 bits file size
if {file size} == 0xFFFFFFFF: // error indicator
string error message
else
16 bits block size
data data stream, {block size} bytes long
else
16 bits block size
data data stream, {block size} bytes long


snapshot

8 bits 0x07 snapshot indicator
32 bits server time
8 bits last frame num
8 bits snapshot flag bits
8 bits area mask size
data area mask, {area mask size} bytes long
<player-state>
<entity>*
10 bits 0x3FF end of entities indicator


entity

10 bits entity ID
1 bit removed-entity indicator
if removed-entity != 0x1:
1 bit changed-entity indicator
if changed-entity == 0x1:
8 bits max changed field index
loop {max changed field index} times:
1 bit changed-field indicator
if changed-field == 0x1:
1 bit is-not-zero indicator
if is-not-zero == 0x1:
<int-value> | <float-value> // choice depends on field index
else:
// value = 0


int-value

N bits value, where N depends on field index


float-value

1 bit full-float indicator
if full-float == 0x1:
32 bits value, as C float
else:
13 bits value, as unsigned int; subtract (1<<12) to return signed int

If a field has floating point values, but its current value is a small integer (< ±4096) without a fractional part, then it is transmitted as a 13-bit unsigned integer instead of transmitting it as a full 32-bit float. To convert a small signed integer that is between -4096 and 4095 to a 13-bit unsigned integer, we simply add 4096 (1<<12) to the number before we send it and then subtract 4096 after it's received.


player-state

8 bits max changed field index
loop {max changed field index} times:
1 bit changed-field indicator
if changed-field == 0x1:
<int-value> | <float-value> // choice depends on field index
1 bit changed-state indicator
if changed-state == 0x1:
<values> // player stats
<values> // persistent player stats
<values> // weapon ammo
<values> // power-up timeouts


values

1 bit changed-values indicator
if changed-values == 0x1:
16 bits changed value bitmask
loop for each bit set in {changed value bitmask}:
16 bits value


See also