This is part 1 in a series.
The source engine netcode is a little squirrelly. It always has been and it always will be. One of the questions I am bombarded with is ‘How do I fix XYZ to make the game run better?’ In order to make the universe a slightly better place, I’m going to try and help all of you.
Articles in this series will include:
- The basics of how source netcode works (You Are Here)
- How the source engine compensates for an imperfect environment
- Understanding the Netgraph
- Optimization Guide
- Everything else advanced and so far not covered
How the Source Netcode Works
Here is the simplified version of how the source engine netcode works on a very basic level:
Connection is client-server. Meaning a client communicates directly with the game server via small packets, rather than communicating player-player or players-player-server. This means the only person that matters is you in your connection to the server. Other clients will not affect your net performance in a normal situation. Sounds great, right?
It is, in theory. Consider the perfect world and pe
rfect server environment - The server would send you updates and you would send the server updates at infinity times/second. Translation: what you see on your screen is exactly what is happening in the server at that moment. No lag, no delay, no registration issues. A perfect world.
Sadly, we do not live in a perfect world. Network bandwidth is limited and client connections are as diverse as the population. Accordingly, the server must take snapshots and send them to the players at Xtimes/second and you send snapshots back at Ytimes/second. These packets take time to travel to the client and then the client takes time to send them back.
To help compensate for these delays, the source engine employs primarily interpolation and prediction, but it also uses compression and compensation.
Practical Goodness
Now that I’ve bombarded you with a bunch of theory, I’m going to weave some practicality into this article. Most of this will still be theory. Practicality will come with the optimization article of this series.
Basic Server Side Variables
Tick - Ticks are a measurement of time in the source engine. At each tick, the game is simulated; IE users commands are processed, the physical game is updated, object positions are updated, etc.
Tickrate - Tickrate is how often the server simulates the game each second.
Combine the two and you have an explanation of 100 Tick, 66 Tick, and 33 Tick servers. 100 Tick servers simulate the game environment 100 times/second, so on and so forth.
There is a catch. The higher the tickrate, the more CPU and bandwidth intensive the server becomes. Too high of a tickrate and neither the server nor the player could handle the incoming data. Hence, the imperfect world.
Yes, sv_maxupdaterate, sv_minupdaterate, and the plethora of new sv netcode commands Valve recently introduced also affect the game. I realize this, but because this is a basic introduction, I will cover them in a later article.
All of the above are server side variables. Clients are unable to control these variables, yet they may be inadequate for some players. This client variables come into play.
Client Side Variables (Server to Client)
Rate - By far the most important client variable in relation to client net based performance. Rate tells the server just how much incoming data to accept (in bytes/second).
cl_updaterate - The cl_updaterate is very similar to the Rate command, except it is in Ticks/Second rather than bytes/second. Translation: this controls how many of the 100, 66, or 33 ticks/second you are allowed to receive.
Regardless of what you set the two aforementioned commands, they will not exceed the
Rate and updaterate are only half of the equation. Those control how much the server sends you. cl_cmdrate and client fps control how often you send updates to the server.
Client Side Variables (Client to Server)
cl_cmdrate - Controls how many ticks(updates)/second you will send to the server. Allows the server to calculate what you are doing as a client.
client FPS - Believe it or not, the source engine uses your client FPS to determine how many times/second it will check for client input. If there is a disparity between your cmdrate setting and your current fps, you are likely to encounter choke. This is partly why fps_max exists.
fps_max - Directly relating to client fps. This limits your client FPS, and thus how
often the engine checks for player input. A common setting for those with higher end computers is fps_max 101. Providing the client never dips below 100 fps, this setting combined with cl_cmdrate 101 will yield the absolute maximum client to server connection.
Keep in mind, though. If there is a disparity between the Client FPS and cl_cmdrate, (there often is) things can and will go awry. More of that to come in the optimization article.
Yowza
That was a lot to cover in one article. If I drove you to tears with boredom, I apologize. Still, you should have a comprehensive basic understanding of the source netcode. This basic understanding will be essential for the next articles in the series; I will assume you already understand the basics of source netcode in the next few articles.
Tomorrow I will be covering how the source engine compensates for the imperfect world aside from the aforementioned variables. Specifically, I will be taking an in depth look at Interpolation, Input Prediction, and Lag compensation.





