(Most of) Counter-Strike 2’s cq_netgraph explained (out-of-date)
· read · counter-strike, cq_netgraph, rant
Warning 2: The netgraph has been deleted from Counter-Strike, and this entire thing is now out of date.
Warning: Everything I say here is my best guess. I’ve done no reverse engineering and I do not care to.
When you press a key or a mouse button, your client doesn’t immediately send it to the server. It takes what action that key’s bound to, the moment you pressed that key, and (if it was the shooty kind of action) where your mouse was pointed at the time that action was activated, and it stuffs all of these into the next command frame.
When the server receives a command frame, it doesn’t immediately execute it, either. It throws it into that players’ command queue for later use.
Every server tick, the server takes the oldest command frame in each players’ command queue and simulates the effect of that command frame. Then, it sends each player the entire world state (or equivalently, a delta from the previous world state—I’m not going to get into that now, though(!)), and also the health of that players’ command queue—the latest command frame it’s simulated and how many command frames are left in the queue.
The netgraph shows server ticks horizontally. For each tick, it if there were too many command frames, it displays the amount vertically as boxes; the color of these boxes fades from cyan to green every sixty-four server ticks.
If there were too few command frames, it instead displays a single red box, signalling that the server had to synthesize a command frame. The server could reuse previous command frame, or it could assume that you didn’t do anything that frame, or it could simply not simulate that player for that frame. (I think the server skips simulation sometimes, but not always.)
Your client doesn’t simply draw the latest world state, though. When rendering anything that you’re not immediately controlling, it’s interpolating between previous world states using the interp
queue! If you don’t know what interp
is, it’s that thing that instantly makes you better at Spy, and that is all you need to know.
But for your own player model and the camera, your client’s doing something much more interesting: it’s extrapolating!
Every server tick, your client re-simulates every command frame that the world state doesn’t reflect, or put another way, every command frame that’s in-flight. Some (roughly half) will be in-flight client-to-server, and the rest will be worldstates in-flight from the server to your client. This means that 128-tick is actually very bad for low-end PCs: not only do they have to simulate more every frame, they have to simulate more work as latency increases.
The client meddles with time, in an attempt to keep the command queue healthy. If it ever runs dry, inputs are dropped, and the larger it grows the more people complain on r/GlobalOffensive. When there’s a red background that means your client is running client ticks slower, and a blue background means that client ticks are at that moment slightly sped up. I’m not sure at what point the time scaling is from, however: it might be the time of the command frame that was sent to the server, or it might be the time of the next client tick.
And finally: I have no idea what the pink horizontal line is.