Quake New Netcode of The Game + Data Types – Overview

Quake New Netcode of The Game + Data Types – Overview 1 - steamsplay.com
Quake New Netcode of The Game + Data Types – Overview 1 - steamsplay.com

Attempts to explain the new netcode of the game, new packets and how mods can use them.
 
 

Introduction

This guide is an attempt at document the netcode of Quake Enhanced for the purpose of modding and source ports adding compatibility.
 
 
There’s no guarantee about the information in this guide being 100% correct or complete.
 
 
The guide will be updated as new information comes in.
 
 
 

Overview

The 2021 Re-Release netcode is based off the existing Netquake netcode. It extends it further with more packets and functionality and adds a layer of encryption.
 
 
Quake netcode uses UDP for communication. The packets are wrapped around DTLS 1.2 for encryption and security. A PSK (Pre-Shared Key) is used for authentication between server and client. The game uses OpenSSL implementation of DTLS.
 
 
 

Data Types

Quake netcode uses a bunch of datatypes.
 
 

Function call Type Size in bytes Callable from QC Comments
WriteChar char 1 Yes
WriteByte byte 1 Yes
WriteShort short 2 Yes
WriteLong int 4 Yes
WriteFloat float 4 No
WriteDouble double 8 No
WriteString C-style string 1+ Yes Repeats chars until the byte 0 is found
WriteCoord float 4 Yes
WriteAngle byte 1 Yes Converts a float using the following formula: ((int)f*256/360) & 255
WriteEntity short 2 Yes Writes out the entity index

 
 
 

Packets – Client to Server

Packet Byte value Description
CLC_BAD 0
CLC_NOP 1
CLC_DISCONNECT 2
CLC_MOVE 3
CLC_STRINGCMD 4
CLC_UNKNOWN1 5 Appears to be sent every frame
CLC_UNKNOWN2 6

 
 
 

Packets – Server to Client

Packet Byte value Description
SVC_BAD 0
SVC_NOP 1 Used as a heartbeat
SVC_DISCONNECT 2 Sent when the server is closing the connection
SVC_UPDATESTAT 3
SVC_VERSION 4
SVC_SETVIEW 5 Tell the client to attach the camera to a specific entity
SVC_SOUND 6
SVC_TIME 7
SVC_PRINT 8 Print something
SVC_STUFFTEXT 9 Print on the top-left of the screen
SVC_SETANGLE 10
SVC_SERVERINFO 11 Contains information about map, maxplayers, which files to precache, and so on
SVC_LIGHTSTYLE 12
SVC_UPDATENAME 13 Sets a player name on the scoreboard
SVC_UPDATEFRAGS 14 Sets a player frags on the scoreboard
SVC_CLIENTDATA 15
SVC_STOPSOUND 16
SVC_UPDATECOLORS 17
SVC_PARTICLE 18 Creates a particle emission effect
SVC_DAMAGE 19
SVC_SPAWNSTATIC 20
SVC_SPAWNBASELINE 22
SVC_TEMPENTITY 23
SVC_SETPAUSE 24
SVC_SIGNONNUM 25
SVC_CENTERPRINT 26 Prints something in the middle of the screen
SVC_KILLEDMONSTER 27
SVC_FOUNDSECRET 28
SVC_SPAWNSTATICSOUND 29
SVC_INTERMISSION 30
SVC_FINALE 31
SVC_CDTRACK 32
SVC_SELLSCREEN 33
SVC_CUTSCENE 34
SVC_SKYBOX 37
SVC_BOTCHAT 38 Displays a text message in chat as coming from a player.
SVC_SPAWNEDMONSTER 39
SVC_BONUSFLASH 40
SVC_FOG 41
SVC_SPAWNBASELINE2 42
SVC_SPAWNSTATIC2 43
SVC_SPAWNSTATICSOUND2 44
SVC_SETVIEWS 45
SVC_UPDATEPING 46
SVC_UPDATESOCIAL 47
SVC_UPDATEPLINFO 48
SVC_RAWPRINT 49
SVC_SERVERVARS 50
SVC_SEQ 51
SVC_ACHIEVEMENT 52
SVC_CHAT 53 Prints a message in the chat
SVC_LEVELCOMPLETED 54 Probably used for achievements
SVC_BACKTOLOBBY 55 Tells the client that they should go back to the lobby screen
SVC_LOCALSOUND 56 Plays a sound that is only heard by the client

 
 
 

SVC_*: A-Z

SVC_BOTCHAT

 
This packet tells the client to display a chat message as coming from a specific player id.
 
 

Offset Call Name
0 WriteByte Packet Id
1 WriteByte Player Id
2 WriteShort String count
4 WriteString String 1
WriteString String …

 
Example
 
 

WriteByte(MSG_ALL,SVC_BOTCHAT);
WriteByte(MSG_ALL,0); // Player 0, the host.
WriteShort(MSG_ALL,1); // How many strings are present
WriteString(MSG_ALL,"Someone is talking for me!");

 
 
With string replacement
 
 

WriteByte(MSG_ALL,SVC_BOTCHAT);
WriteByte(MSG_ALL,0); // Player 0, the host.
WriteShort(MSG_ALL,2); // How many strings are present
WriteString(MSG_ALL,"My name is {}");
WriteString(MSG_ALL,"JPiolho");

 
 
Quake New Netcode of The Game + Data Types - Overview - SVC_*: A-Z - EAF09AD
 
 

SVC_CENTERPRINT

 
This packet tells the client to print text in the middle of the screen. It supports string replacements.
 
 

Offset Call Name
0 WriteByte Packet ID
1 WriteShort String count
3 WriteString String 1
WriteString String …

 
Default center print
 
 

WriteByte(MSG_ALL,SVC_CENTERPRINT);
WriteShort(MSG_ALL,1); // Number of strings that will follow
WriteString(MSG_ALL,"Hello world");

 
 
With string replacement
 
 

WriteByte(MSG_ALL,SVC_CENTERPRINT);
WriteShort(MSG_ALL,2); // Number of strings that will follow
WriteString(MSG_ALL,"Welcome to the game, {}");
WriteString(MSG_ALL,"JPiolho");

 
 
Quake New Netcode of The Game + Data Types - Overview - SVC_*: A-Z - EAF09AD
 
 

SVC_CHAT

 
This packet tells the client to print text in chat. It appears to only work in single player games.
 
Unlike SVC_BOTCHAT, you have full control over the name of the person plus you can specify some colors.
 
 
Available name colors: White (0), Red (1), Light Blue (2), Yellow (3)
 
Available message colors: White (0), Light blue (1)
 
 

Offset Call Name
0 WriteByte Packet ID
1 WriteByte Name color (0-3)
2 WriteByte Message color (0-1)
3 WriteString Name
WriteString Message

 
Default center print
 
 

WriteByte(MSG_ALL,53); // SVC_CHAT
WriteByte(MSG_ALL,0); // Name color (0-3)
WriteByte(MSG_ALL,0); // Message Color (0-1)
WriteString(MSG_ALL,"Name"); // Name
WriteString(MSG_ALL,"Color 0"); // Message

 
 
Quake New Netcode of The Game + Data Types - Overview - SVC_*: A-Z - EAF09AD
 
 

SVC_UPDATENAME

 
This packet tells the client to update a player’s name in the scoreboard
 
 

Offset Call Name
0 WriteByte Packet Id
1 WriteByte Player Id
2 WriteString Player name

 
Example
 
 

WriteByte(MSG_ALL,SVC_UPDATENAME);
WriteByte(MSG_ALL,0); // Player 0, the host.
WriteString(MSG_ALL,"Nobody"); // Set player name to 'Nobody'

 
 
 

Entity packet

This documentation is very incomplete
 
 
The entity packet is a bit special. It needs to be sent every frame to the players so that they know it exists. It also specifies all the attributes the client needs in order to display it on the client-side. Things like position, angles, model, solidness, etc…
 
 
Instead of having a regular numeric packet id, it relies on the bit 7 of the packet id being set. All the other bits in the byte are used as flags. The size of this packet is highly variable as it depends on the flags that are set.
 
 
Start by having a packet id of 128 and then adding different flags that you want.
 
 
The packet starts with a flag bitmap of 1 or more bytes. These indicate which entity properties are being sent. After the flag bitmap, the entity id is sent. After this, all the data that was specified in the flag bitmap is sent (in a specific order).
 
 
Byte Flagmap 1
 

Bit Name
0 More flag bytes
1 Origin X
2 Origin Y
3 Origin Z
4 Angle Y
5 No lerp
6 Frame
7 Entity packet signal (always set to 1)

 
If “More flag bytes” bit was set, then the following packet follows:
 
Byte flagmap 2
 

Bit Name
0 Angle X
1 Angle Z
2 Model Index
3 Color map
4 Skin
5 Effects
6 Is it a long entity?
8 More flag bytes

 
If “More flag bytes” bit was set, then the following packet follows:
 
Byte flagmap 3
 

Bit Name
0 Alpha
1 Unsure – Frame
2 Unsure – Model Index
3 Unsure – When the next think will happen
4
5 Unsure – Origin Offset
6 Solid
7 More flag bytes

 
If “More flag bytes” bit was set, then the following packet follows:
 
Byte flagmap 4
 

Bit Name
0 Unsure – Flags
1 Unsure – Health
2 Unsure – Model Index
3
4
5
6
7

 
The Entity Id follows. If “Long Entity” bit was set, the entity Id is sent as a Short (2 bytes). If not set then it’s sent as a byte (1 byte).
 
 
Now all the information that was specified in the flagmap is sent, in the following order:
 

Call If bit is set Name Comment
WriteByte Byte 2, bit 2 Model Index
WriteByte Byte 1, bit 6 Frame
WriteByte Byte 2, bit 3 Colormap
WriteByte Byte 2, bit 4 Skin
WriteByte Byte 2, bit 5 Effects
WriteFloat Byte 1, bit 1 Origin X If byte 3 bit 5 is set, then the call is WriteShort
WriteByte Byte 2, bit 0 Angle X
WriteFloat Byte 1, bit 2 Origin Y If byte 3 bit 5 is set, then the call is WriteShort
WriteByte Byte 1, bit 4 Angle Y
WriteFloat Byte 1, bit 3 Origin Z If byte 3 bit 5 is set, then the call is WriteShort
WriteByte Byte 2, bit 1 Angle Z
WriteByte Byte 3, bit 0 Alpha
WriteByte Byte 3, bit 1 Frame
WriteByte Byte 3, bit 2 Model Index
WriteByte Byte 3, bit 3 Next Think
WriteByte Byte 3, bit 6 Solid
Unknown Byte 4, bit 0 Flags Appears to send multiple values
Unknown Byte 4, bit 1 Healths Appears to send multiple values
Unknown Byte 4, bit 2 Model Indexes Appears to send multiple values

 
Example in QuakeC
 
 

 local float firstBits;
 local float secondBits;
 local float thirdBits;

 firstBits |= 1; // More bytes

 firstBits |= 1 << 1; // Origin 1
 firstBits |= 1 << 2; // Origin 2
 firstBits |= 1 << 3; // Origin 3
 firstBits |= 1 << 4; // Angle 2
 firstBits |= 1 << 6; // Frame

 secondBits |= (1 << 8) >> 8; // Angle 1
 secondBits |= (1 << 9) >> 8; // Angle 3
 secondBits |= (1 << 10) >> 8; // Model Index
 secondBits |= (1 << 11) >> 8; // Colormap
 secondBits |= (1 << 12) >> 8; // Skin
 secondBits |= (1 << 13) >> 8; // Effects
 secondBits |= (1 << 14) >> 8; // Long Entity
 secondBits |= (1 << 15) >> 8; // More bytes

 thirdBits |= (1 << 16) >> 16; // Alpha
 thirdBits |= (1 << 22) >> 16; // Solid

 msg_entity = self;
 WriteByte(MSG_ONE,firstBits | 128); // Packet Type

 // Send all the values
 if(firstBits & 1)
 WriteByte(MSG_ONE,secondBits);
 if(secondBits & 128)
 WriteByte(MSG_ONE,thirdBits);
 
 WriteShort(MSG_ONE,1500 + pNumber); // Entity ID

 WriteByte(MSG_ONE,modelindex_player);
 WriteByte(MSG_ONE,p.frame); 
 WriteByte(MSG_ONE,p.colormap);
 WriteByte(MSG_ONE,p.skin);
 WriteByte(MSG_ONE,p.effects);
 WriteCoord(MSG_ONE,p.origin_x);
 WriteAngle(MSG_ONE,p.angles_x);
 WriteCoord(MSG_ONE,p.origin_y);
 WriteAngle(MSG_ONE,p.angles_y);
 WriteCoord(MSG_ONE,p.origin_z);
 WriteAngle(MSG_ONE,p.angles_z);
 WriteByte(MSG_ONE,120);
 WriteByte(MSG_ONE,SOLID_NOT);

 
 

Written by JPiolho

 
 
Hope you enjoy the post for Quake New Netcode of The Game + Data Types – Overview, If you think we should update the post or something is wrong please let us know via comment and we will fix it how fast as possible! Thank you and have a great day!
 


Be the first to comment

Leave a Reply

Your email address will not be published.


*