The other thing that often eats frame rate is overly complex collision geometry. This can both affect client frame rates, and in extreme situations cause lag by using all the available CPU on the server. This gets far less attention than clean brushwork and r_speeds, but can be very significant.
When you compile your map, all the drawing geometry is turned into triangles, but the brushes are kept for collision detection (this isn’t just for players, but for detecting where shots hit etc. Even nodraw/nonsolid brushes are kept and tested.) Both triangles and brushes are associated with BSP leafs.
Traces (the function used for collision detection) use the BSP to figure out which leafs they need to interact with, but within each leaf essentially do a linear test against every possible brush. There are early outs, but it is still costly. That means that if you for example, make a complex terrain which is all detail, with a large blocksize, you can get very poor performance because every frame has to look at every brush. While researching this, I made a map where a single player, in a single room with ~12 drawing triangles and ~16000 nodraw/nonsolid brushes brought my athlon 64 3000 down to < 50 fps on the client, and overloaded the CPU on an athlon 1.6 ghz server. The higher the client frame rate (regardless of maxpackets) the more load each client puts on the server. One client getting 333 fps on a ‘bad’ part of oasis used something like 11 percent of available CPU on the above mentioned server.
The lesson from this is that vis is important for more than just keeping triangles from being drawn. It should also be used to isolate complex geometry. However, this is a trade off too, because excess vis data has it’s own cost (I haven’t done detailed measurements, but some tuning I did on someone else’s map showed it to be significant. If you use the 2MB which is the max vis data, that gets touched every frame. Clearly, that will completely thrash your cache and put a big load on memory bandwidth.)
Another lesson is that using models and simple clip brushes can have a big performance gain. If you have complex geometry which isn’t reachable, you should use models.
Finally, maps can be ‘laggy’ on large servers if all the players are in each others PVS a the same time. A 64 player server hits the max rate a lot in this situation, even at the practical limit of 25000.
ps: good to see you again Gerbil!