Previous Next Table of Contents

6. List of all message types

The easiest way to explain a message is to give a short C like program fragment to parse such a message. Each message can be described by its ID or its name.

6.1 bad

ID

0x00

purpose

Something is bad. This message should never appear.

parse routine

none

6.2 nop

ID

0x01

purpose

No operation.

parse routine

none

6.3 disconnect

ID

0x02

purpose

Disconnect from the server. Stops the game.

parse routine

none

6.4 updatestat

ID

0x03

purpose

Updates directly any values in the player state.

variables

long index;

is the index in the playerstate array. Possible indices are:

index variable
0 health
1 ??? (not used)
2 weaponmodel
3 currentammo
4 armorvalue
5 weaponframe
6 ammo_shells
7 ammo_nails
8 ammo_rockets
9 ammo_cells
10 weapon
11 total_secrets
12 total_monsters
13 found_secrets
14 found_monsters
15 ???
.
.
.
31 ???
Normal DEM files use index 11 to 14 only.

long value;

is the new value.

long playerstate[32];

is the array to describe the player state. Many other messages change (indirectly) some values in it.

parse routine

index = ReadByte;
if (index > 0x1F) {
  error("svc_updatestat: %i is invalid", index);
}
value = ReadLong;
playerstate[index] = value;

6.5 version

ID

0x04

purpose

This message defines the version of the server. I never found such a message in a DEM file. It may be absorbed by the serverinfo message.

variables

long serverprotocol;

is the version number of the server. It should be 0x0F.

parse routine

serverprotocol = ReadLong;
if (serverprotocol != 0x0F) {
  error("CL_ParseServerMessage: Server is protocol %i instead of %i\n", 
                                                 serverprotocol, 0x0F);
}

6.6 setview

ID

0x05

purpose

Sets the camera position to the origin of this entity.

variables

long entity;

is the entity with the camera.

parse routine

entity = ReadShort;

6.7 sound

ID

0x06

purpose

This message starts the play of a sound at a specific point.

variables

long mask;

is a bitmask to reduce the amount of data.

float vol;

is the volume of the sound (0.0 off, 1.0 max)

float attenuation;

is the attenuation of the sound. Possible values (for all kind of sounds) are:

value QuakeC purpose
0 ATTN_NONE i. e. player's death sound doesn't get an attenuation
1 ATTN_NORM the normal attenuation
2 ATTN_IDLE idle monsters get this attenuation
3 ATTN_STATIC spawnstaticsound messages get this attenuation

long channel;

is the sound channel. There are 8 possible sound channels in Quake but the game uses 5 only. Possible values are:

value QuakeC purpose
0 CHAN_AUTO big powerups
1 CHAN_WEAPON weapon use sounds
2 CHAN_VOICE pain calls
3 CHAN_ITEM item get sounds
4 CHAN_BODY jump and fall sounds

long entity;

is the entity which caused the sound.

long soundnum;

is the sound number in the sound-table.

ve3_t origin;

is the origin of the sound.

parse routine

long entity_channel; // combined variable

mask = ReadByte;
vol = mask & 0x01 ? (float) ReadByte / 255.0 : 1.0;
attenuation = mask & 0x02 ? (float) ReadByte / 64.0 : 1.0;
entity_channel = ReadShort;
channel = entity_channel & 0x07;
entity = (entity_channel >> 3) & 0x1FFF;
soundnum = ReadByte;
for (i=0 ; i<3 ; i++) origin[i] = ReadCoord;

6.8 time

ID

0x07

purpose

This is the time stamp of a block of messages. A time message should appear in every block.

variables

float time;

is the time in seconds from the beginning of the current level (not of the recording).

parse routine

time = ReadFloat;

6.9 print

ID

0x08

purpose

The client prints the text in the top left corner of the screen. The text appears on the console as well.

variables

char* text;

is the text to be displayed. The text contains something like ``You get 5 shells''. There are special non-printable characters in the text: ``\n'' means new line and ``\002'' changes the color of the following text. The value 2 may be a color number but I'm not sure about this.

parse routine

text = ReadString;

6.10 stufftext

ID

0x09

purpose

The client transfers the text to the console and runs it.

variables

char* text;

is the command, which the client has to execute. These are commands like ``bf\n'' to make a flash after you take something.

parse routine

text = ReadString;

6.11 setangle

ID

0x0A

purpose

This message set the camera orientation.

variables

vec3_t angles;

is the new camera orientation.

parse routine

for (i=0 ; i<3 ; i++) angles[i] = ReadAngle;

6.12 serverinfo

ID

0x0B

purpose

This message is usually one of the first messages after a level start. It loads model and sound files.

variables

long serverversion;

is the version of the server. It should be the same as the version of the client. Up to now this version was always 0x0F.

long maxclients;

is the maximum number of clients in this recording. It is 1 in single player recordings or the number after the -listen command line parameter.

long multi;

is 0 in single player recordings and 1 in multi player recordings. It actually toggles the ranking screen at the end of a level.

char* mapname;

is the name of the level.

char* precache_models[256];

is the model-table. It will be filled up with model names. Many other messages contain an index in this array. The first used index is 1.

long nummodels;

is the number of models in the model-table.

char* precache_sounds[256];

is the sound-table. It will be filled up with sound names. Many other messages contain an index in this array. The first used index is 1.

long numsounds;

is the number of sounds in the sound-table.

parse routine

serverversion = ReadLong;
if (serverversion != 0x0F) { 
  error("Server returned version %i, not %i", serverversion, 0x0F);
}
maxclients = ReadByte;
multi = ReadByte;
mapname = ReadString;
nummodels = 0;
do {
  if (++nummodels > 255) error("Server sent too many model_precache");
  precache_models[nummodels] = ReadString;
} while (*precache_models[nummodels]);
numsounds = 0;
do {
  if (++numsounds > 255) error("Server sent too many sound_precache");
  precache_sounds[numsounds] = ReadString;
} while (*precache_sounds[numsounds]);

6.13 lightstyle

ID

0x0C

purpose

This message defines a light style.

variables

long style;

is the light style number.

char* string;

is a string of letters ``a'' .. ``z'', where ``a'' means black and ``z'' white. All known effects from nervous flashing: ``az'' to slow dimming: ``zyxwvu ... edcba'' can so be described.

parse routine

style = ReadByte;
string = ReadString;

6.14 updatename

ID

0x0D

purpose

This message sets the player name.

variables

long player;

is the internal player number (client 1 is player number 0).

char* netname;

is the new player name.

parse routine

player = ReadByte;
netname = ReadString;

6.15 updatefrags

ID

0x0E

purpose

This message updates the frag count of a specific player.

variables

long player;

is the internal player number (client 1 is player number 0).

long frags;

is the new frag count for this player.

parse routine

player = ReadByte;
frags = ReadShort;

6.16 clientdata

ID

0x0F

purpose

This message updates the status line and the camera coordinates.

variables

long mask;

is a bitmask to show which values are coming.

float view_ofs_z;

is an additional view offset because the camera is at the origin of the entitiy and not at the eyes (is -8 if the player is death).

float ang_ofs_1;

is an additional offset of the first angle.

vec3_t angles;

indicates the camera direction change.

vec3_t vel;

indicates the camera velocity.

long items;

contains a bit mask for the inventory:

bit value QuakeC purpose
0 0x00000001 IT_SHOTGUN Shotgun (should be always 1)
1 0x00000002 IT_SUPER_SHOTGUN Double-barrelled Shotgun
2 0x00000004 IT_NAILGUN Nailgun
3 0x00000008 IT_SUPER_NAILGUN Supernailgun
4 0x00000010 IT_GRENADE_LAUNCHER Grenade Launcher
5 0x00000020 IT_ROCKET_LAUNCHER Rocket Launcher
6 0x00000040 IT_LIGHTNING Thunderbolt
7 0x00000080 IT_EXTRA_WEAPON extra weapon (there is no extra weapon)
8 0x00000100 IT_SHELLS Shells are active
9 0x00000200 IT_NAILS Flechettes are active
10 0x00000400 IT_ROCKETS Grenades are active
11 0x00000800 IT_CELLS Cells are active
12 0x00001000 IT_AXE Axe (should be always 1)
13 0x00002000 IT_ARMOR1 green Armor
14 0x00004000 IT_ARMOR2 yellow Armor
15 0x00008000 IT_ARMOR3 red Armor
16 0x00010000 IT_SUPERHEALTH Megahealth
17 0x00020000 IT_KEY1 silver (keycard or runekey or key)
18 0x00040000 IT_KEY2 gold (keycard or runekey or key)
19 0x00080000 IT_INVISIBILITY Ring of Shadows
20 0x00100000 IT_INVULNERABILITY Pentagram of Protection
21 0x00200000 IT_SUIT Biosuit
22 0x00400000 IT_QUAD Quad Damage
23 0x00800000 unknown unknown (is 0)
24 0x01000000 unknown unknown (is 0)
25 0x02000000 unknown unknown (is 0)
26 0x04000000 unknown unknown (is 0)
27 0x08000000 unknown unknown (is 0)
28 0x10000000 unknown Rune 1
29 0x20000000 unknown Rune 2
30 0x40000000 unknwon Rune 3
31 0x80000000 unknown Rune 4
You can find the default value for items in the parse routine: 0x4001. It looks like a programmer's mistake because this means Shotgun any yellow Armor. It should be 0x1001: Shotgun and Axe.

long weaponframe;

is the frame of the weapon model.

long armorvalue;

is the current armor.

long weaponmodel;

is the model number of the weapon in the model-table.

long health;

is the current health.

long currentammo;

is the current number of the current ammunition.

long ammo_shells;

is the current number of shells.

long ammo_nails;

is the current number of nails.

long ammo_rockets;

is the current number of rockets.

long ammo_cells;

is the current number of cells.

long weapon;

contains a bit mask for the current weapon:

bit value QuakeC weapon
? 0x00 not available Axe
0 0x01 IT_SHOTGUN Shotgun
1 0x02 IT_SUPER_SHOTGUN Double-barrelled Shotgun
2 0x04 IT_NAILGUN Nailgun
3 0x08 IT_SUPER_NAILGUNSupernailgun
4 0x10 IT_GRENADE_LAUNCHERGrenade Launcher
5 0x20 IT_ROCKET_LAUNCHERRocket Launcher
6 0x40 IT_LIGHTNINGThunderbolt
7 0x80 IT_EXTRA_WEAPONextra weapon (there is no extra weapon)

parse routine

long uk_bit_b10, uk_bit_b11; // unknown (unused ??)

mask = ReadShort;
view_ofs_z = mask & 0x0001 ? (float) ReadChar : 22.0;
ang_ofs_1 = mask & 0x0002 ? (float) ReadChar : 0.0; 
angles[0] = mask & 0x0004 ? (vec_t) ReadChar : 0.0; 
vel[0] = mask & 0x0020 ? (vec_t) ReadChar : 0.0;
angles[1] = mask & 0x0008 ? (vec_t) ReadChar : 0.0; 
vel[1] = mask & 0x0040 ? (vec_t) ReadChar : 0.0;
angles[2] = mask & 0x0010 ? (vec_t) ReadChar : 0.0; 
vel[2] = mask & 0x0080 ? (vec_t) ReadChar : 0.0;
items = mask & 0x0200 ? ReadLong : 0x4001;
uk_bit_b10 = mask & 0x0400 ? 1 : 0; // bit 10 
uk_bit_b11 = mask & 0x0800 ? 1 : 0; // bit 11 
weaponframe = mask & 0x1000 ? ReadByte : 0;
armorvalue = mask & 0x2000 ? ReadByte : 0;
weaponmodel = mask & 0x4000 ? ReadByte : 0; 
health = ReadShort;  
currentammo = ReadByte;
ammo_shells = ReadByte;
ammo_nails = ReadByte;
ammo_rockets = ReadByte;
ammo_cells = ReadByte;
weapon = ReadByte;

6.17 stopsound

ID

0x10

purpose

Stops a sound. I never found such a message in a DEM file.

parse routine

long uk_short;  // unknown (an index??)

uk_short = ReadShort;

6.18 updatecolors

ID

0x11

purpose

Updates the colors of the specified player.

variables

long player;

is the internal player number (client 1 is player 0).

long colors;

is the combined color of this player.

long shirtcolor;

is the color of the shirt (0 <= shirtcolor <= 3).

long pantscolor;

is the color of the pants (0 <= pantscolor <= 3).

parse routine

player = ReadByte;
colors = ReadByte;
shirtcolor = (colors>>4) & 0x0F;
pantscolor = colors & 0x0F;

6.19 particle

ID

0x12

purpose

This starts particles flying around. This happens, if a barrel explodes or blood particles fly after being hit by an axe, shells or nails.

variables

vec3_t origin;

is the origin of the particles.

vec3_t vel;

is the velocity of the particles.

long color;

is the color of the particles (blood is 73).

long count;

is the number of the particles

parse routine

for (i=0 ; i<3 ; i++) origin[i] = ReadCoord;
for (i=0 ; i<3 ; i++) vel[i] = (vec_t) ReadChar * 0.0625;
color = ReadByte;
count = ReadByte;

6.20 damage

ID

0x13

purpose

Tells how severe was a hit and from which points it came.

variables

long save;

will be subtracted from the current armor.

long take;

will be subtracted from the current health.

vec3_t origin;

is the origin of the hit. It points to the weapon of a monster or player (not the origin of the monster entity) or it is (0,0,0) if the damage was caused by drowning or burning.

parse routine

save = ReadByte;
take = ReadByte;
for (i=0 ; i<3 ; i++) origin[i] = ReadCoord;

6.21 spawnstatic

ID

0x14

purpose

This message creates a static entity and sets the internal default values.

variables

long StaticEntityCount;

is the number of already started static entities. The maximum number is 127.

long default_modelindex;

is the model number in the model-table.

long default_frame;

is the frame number of the model.

long default_colormap;

is the colormap number to display the model.

long default_skin;

is the skin number of the model. This is used for things with different skins (like players or armors).

vec3_t default_origin;

is the origin of the entity.

vec3_t default_angles;

is the orientation of the entity.

parse routine

if (StaticEntityCount > 127) error("Too many static entities");
StaticEntityCount++;
default_modelindex = ReadByte;
default_frame = ReadByte;
default_colormap = ReadByte;
default_skin = ReadByte;
for (i=0 ; i<3 ; i++) {
  default_origin[i] = ReadCoord;
  default_angles[i] = ReadAngle;
}

6.22 spawnbinary

ID

0x15

purpose

This is OBSOLETE. It should never occur in DEM files.

parse routine

error ("CL_ParseServerMessage: Illegible server message\n");

6.23 spawnbaseline

ID

0x16

purpose

This message creates a dynamic entity and sets the internal default values.

variables

long entity;

is the number of the entity.

long default_modelindex;

is the model number in the model-table.

long default_frame;

is the frame number of the model.

long default_colormap;

is the colormap number to display the model.

long default_skin;

is the skin number of the model. This is used for things with different skins (like players or armors).

vec3_t default_origin;

is the origin of the entity.

vec3_t default_angles;

is the orientation of the entity.

parse routine

entity = ReadShort;
if (entity > 449) error("CL_EntityNum: %i is an invalid number", entity);
default_modelindex = ReadByte;
default_frame = ReadByte;
default_colormap = ReadByte;
default_skin = ReadByte;
for (i=0 ; i<3 ; i++) {
  default_origin[i] = ReadCoord;
  default_angles[i] = ReadAngle;
}

6.24 temp_entity

ID

0x17

purpose

This message creates a temporary entity.

variables

long entitytype;

is the type of the temporary entity. There are two kinds of temporary entities:

point entity

is a small point like entity.

value QuakeC purpose
0 TE_SPIKE unknown
1 TE_SUPERSPIKE superspike hits (spike traps)
2 TE_GUNSHOT hit on the wall (Axe, Shotgun)
3 TE_EXPLOSION grenade/missile explosion
4 TE_TAREXPLOSION explosion of a tarbaby
7 TE_WIZSPIKE wizard's hit
8 TE_KNIGHTSPIKE hell knight's shot hit
10 TE_LAVASPLASH Chthon awakes and falls dead
11 TE_TELEPORT teleport end

large entity

is a 2 dimensional entity.

value QuakeC purpose
5 TE_LIGHTNING1 flash of the Shambler
6 TE_LIGHTNING2 flash of the Thunderbolt
9 TE_LIGHTNING3 flash in e1m7 to kill Chthon

long entity;

is the entity which created the temporary entity.

vec3_t origin;

is the origin of the entity.

vec3_t trace_endpos;

is the destination of the large temporary entity.

parse routine

entitytype = ReadByte;
if (entitytype > 11) 
  error("CL_ParserTEnt: bad type");
switch (entitytype) {
  case 0,1,2,3,4,7,8,10,11:
         for (i=0 ; i<3 ; i++) org[i] = ReadCoord;
  break;
  case 5,6,9:
         entity = ReadEntity;
         for (i=0 ; i<3 ; i++) origin[i] = ReadCoord;
         for (i=0 ; i<3 ; i++) trace_endpos[i] = ReadCoord;
  break;
}

6.25 setpause

ID

0x18

purpose

Set the pause state. The time stands still but all entities get their update messages.

variables

long pausestate;

is 1 to start the pause and 0 to stop it.

parse routine

pausestate = ReadByte;
if (pausestate) {
  // pause is on
}
else {
  // pause is off
}

6.26 signonum

ID

0x19

purpose

This message selects the client state.

variables

long signon;

is the client state. The possible values are:

value purpose
1 after model/sound precache, start spawning entities (``prespawn'')
2 start initializing light effects
3 start 3D rendering

parse routine

signon = ReadByte;

6.27 centerprint

ID

0x1A

purpose

Prints the specified text at the center of the screen.

variables

char* text;

is the text to be displayed.

parse routine

text = ReadString;

6.28 killedmoster

ID

0x1B

purpose

This message indicates the death of a monster.

variables

long killed_monsters;

is the number of killed monsters. It may be displayed with the console command showscores.

parse routine

killed_mosters++;

6.29 foundsecret

ID

0x1C

purpose

This message receives a client, if the player enters a secret area. It comes usually with a print message.

variables

long found_secrets;

is the number of found secrets. It may be displayed with the console command showscores.

parse routine

found_secrets++;

6.30 spawnstaticsound

ID

0x1D

purpose

This message starts a static (ambient) sound not connected to an entity but to a position.

variables

vec3_t origin;

is the origin of the sound.

long soundnum;

is the sound number in the sound-table.

float vol;

is the volume (0.0 off, 1.0 max)

float attenuation;

is the attenuation of the sound. Possible values (for all kind of sounds) are:

value QuakeC purpose
0 ATTN_NONE i. e. player's death sound doesn't get an attenuation
1 ATTN_NORM the normal attenuation
2 ATTN_IDLE idle monsters get this attenuation
3 ATTN_STATIC all spawnstaticsound messages get thisattenuation

parse routine

for (i=0 ; i<3 ; i++) origin[i] = ReadCoord;
soundnum = ReadByte; 
vol = (float) ReadByte / 255.0; 
attenuation = (float) ReadByte / 64.0;

6.31 intermission

ID

0x1E

purpose

Displays the level end screen. Depending on the multi command in the serverinfo message this is either the single player summary screen or the multi player ranking screen.

parse routine

none

6.32 finale

ID

0x1F

purpose

Displays the episode end screen and some text.

variables

char* text;

is the episode end text.

parse routine

text = ReadString;

6.33 cdtrack

ID

0x20

purpose

This message selects the audio CD track numbers.

variables

long fromtrack;

is the start track.

long totrack;

is the last track. Both values are equal at the start of a game but become 2 and 3 at the end of an episode.

parse routine

fromtrack = ReadByte;
totrack = ReadByte;

6.34 sellscreen

ID

0x21

purpose

Displays the help and sell screen.

parse routine

none

6.35 updateentity

ID

>=0x80

purpose

This is the general entity update message. For every entity (potentially) in sight the server sends such a message. The message contains only the values, which changed since the creation (or spawning) of the entity (with spawnstatic, spawnbaseline).

variables

long mask;

is a bit mask to reduce the amount of data to be sent. Only the changed parts get their bit and their values.

long entity;

is the entity number.

long modelindex;

is the model number in the model-table.

long frame;

is the frame number of the model.

long colormap;

is the colormap number to display the model.

long skin;

is the skin number of the model. This is used for things with different skins (like players or armors).

long attack_state;

shows how the entity attacks. I'm not really sure about the explanation because I found only the values 0 and 2 in DEM files. The possible values are:

value QuakeC purpose
0 none don't attack
1 AS_STRAIGHT straight shot
2 AS_SLIDING move to a side
3 AS_MELEE single combat (dog, ogre)
4 AS_MISSILE shooting attack

vec3_t origin;

is the origin of the entity.

vec3_t angles;

is the orientation of the entity.

long new;

is 1 if the entity gets some really new values (modelindex etc.)

parse routine

mask = ID & 0x07F;
if (mask & 0x0001) mask |= (ReadByte) << 8;
entity = mask & 0x4000 ? ReadShort : ReadByte;
modelindex = mask & 0x0400 ? ReadByte : default_modelindex;
frame = mask & 0x0040 ? ReadByte : default_frame; 
colormap = mask & 0x0800 ? ReadByte : default_colormap; 
skin = mask & 0x1000 ? ReadByte : default_skin;
attack_state = mask & 0x2000 ? ReadByte : default_attack_state;
origin[0] = mask & 0x0002 ? ReadCoord : default_origin[0];
angles[0] = mask & 0x0100 ? ReadAngle : default_angles[0];
origin[1] = mask & 0x0004 ? ReadCoord : default_origin[1];
angles[1] = mask & 0x0010 ? ReadAngle : default_angles[1];
origin[2] = mask & 0x0008 ? ReadCoord : default_origin[2];
angles[2] = mask & 0x0200 ? ReadAngle : default_angles[2];
new = mask & 0x0020 ? 1 : 0;


Previous Next Table of Contents