Netcode Explained Again
by Cameron Lloyd
This article is basically just a backup to Jon Mellin's GotFrag article, but I'll be telling you how to get a correct ex_interp and cl_updaterate without knowing the servers maxrates and correcting the cl_cmdrate command.
cl_cmdrate:
Mellin states that "Ideally, this value should equal the server's fps (NOT the client fps as some people originally thought). If you update the server more times than the server calculates frames over the same time period, the extra updates are most likely just dropped by the server. Therefore, too high of a cl_cmdrate shouldn't be too harmful, but will waste your bandwidth."
cl_cmdrate IS a factor of your client FPS. To prove this, simply connect to your favourite server and type net_graph 1. Ok, look at your currect fps. If your cl_cmdrate is LOWER then your fps, then you will notice red dots being displayed in the bottom.
Then change your cl_cmdrate to slightly higher then your FPS and watch the dots vanish.
Valve writes that "The final area is the light blue and ( sometimes ) red line at the very bottom of the netgraph. This line is based on your framerate and your cl_cmdrate setting. For every frame where a command packet is actually send out onto the wire, a light blue dot is placed on the graph. If commands are accumulated for deferred sending, you'll see a red dot instead. Try setting cl_cmdrate to half your framerate to see the effect."
Well Im pretty sure Valve have taken out the light blue dots cause I cant see any of them. Anway, the red dots mean that your cl_cmdrate is too low and commands are being accumulated for sending because you have a higher FPS.
Recommendation:
Set your cl_cmdrate slightly (5) over your fps. This will ensure that you are sending out as many commands as possible. If your connection cant handle that and you start to lag, then simply set your cl_cmdrate as HIGH as possible until you dont lag in messy situations (gunbattle). We want to send as much data to the server as possible. It's that simple. Another note is that it dosen't have to 'match' the servers fps because if were sending out our MAX commands then the server will drop the commands that it cant handle.
cl_updaterate and ex_interp
Mellin is correct on this one. Our cl_updaterate should be equal to the servers sv_maxupdaterate. This works in the same way as I explained cl_cmdrate. We want the MAX commands as possible. So setting this to the servers MAX rate will accomplish this.
Valve writes in relation to the netgraph that "Area four is correlated to how quickly the client is rendering frames. For each frame rendered, the graph indicates how much interpolation was used in drawing objects in the world. If you are not getting a sufficient number of server updates ( < 10 second ) or you drop enough packets, then the client won't be able to interpolate any more and will have to extrapolate instead. In that case, you'll see the lower part of the graph go above the grayish line ( above the dark blue area ) and turn yellow to orange / red depending upon how far out of date your data becomes."
So using Valves information we should be able to set the right cl_updaterate which will untimately set our ex_interp to its correct value (only if its set to ex_interp 0, will it be automatically set).
But how to find it when we dont know rcon? Simple. Load up your game and connect to your favourtite server. Once again type net_graph 1.

Our cl_updaterate is set to 51. We set our ex_interp to 0. It automatically sets our interp to whatever value. BUT, look at the graph. We are recieving orange/yellow dots, which means we are extrapolating. It does this because we are receiving 51 packets, when the server can only send 30 (sv_maxupdaterate 30). Therefore, we are dropping packets and extrapolating (using packets in the history, or previous packets). We dont want this so we change our cl_updaterate to 40, and our ex_interp is set automatically again. We get this.
See how the yellow dots are lower then the cl_updaterate 51 picture. This is because we are still dropping packets because we are only receiveing 30 from the server. This makes our interp wrong again. So we change our cl_updaterate to 30 and interp sets automatically. We get this.
Horay, we are receiving the max packets from the server as POSSIBLE and therefore arn't dropping any. This therefore sets our ex_interp to the correct value.
In conclusion, we want our cl_updaterate to match the servers sv_maxupdaterate so that we can correctly interpolate player movements based on ACTUAL packets we recieve and not dropped packets aswell.
rate
Well, all we have to do with rate is gradually raise it until we are recieving no choke in gun battles. This will guarantee that all our packets/commands are being sent and recieved. I personally like to keep rate as small as possible but still high enough to have no choke. It is very important that we have no choke or else our ex_interp will be incorrect at that time.
cl_smoothtime
Valve write that "Corrections of prediction errors can be quite noticeable and will cause your view to jump a bit. To visually smooth that effect, the prediction error is corrected gradually over a short amount of time ( cl_smoothtime )."
Personally, I would set this to 0. In the case that we dont actually recieve all the packets/commands from the server in the case a lag spike, a bad server, etc we want to see the interpolation of the ACTUAL packets recieved. Therefore, if we set cl_smoothtime to 0, our interpolation wont be 'smoothed' or corrected and we will see the actual position of the players. Note that this will cause a jump in the players movements, but they will be correct.
Conclusion
Have fun.
References
Jon Mellin, CS Netcode Explained, 2004
Valves document on netgraph, available in Half-Life SDK.
Valves document on source's network traffic, available at http://www.valve-erc.com/srcsdk/general/multiplayer_networking.html.
*Note* Valves document on source was only used for cl_smoothtime, which still does the same thing in 1.6. ALL other information is still correct to 1.6.