Understanding and tweaking your Connection
So you want to play a game of Counter-Strike, eh? You load up
your machine, connect to a server, and you are go about your business
fraggin and baggin. It all seems quite simple; see an enemy, shoot
the enemy. What can be so complicated about that? Read on to find
out exactly how complex it is.
1. Packets, packets, packets
Let's think about the example I gave above. How complex can it
be? Two players in a map shooting at each other. Pretty simple,
right? Well, in order to accomplish that simple little scenario
your CS client needs to send and receive hundreds of 'packets'
of information per second. What kind of information, you ask?
Everything from your position on the map (x,y,z) to your orientation,
the other player's position and orientation, his speed, the weapon
he's carrying, server entities, ammo, shots fired.... But all
of that comes later. To start with, lets look at a packet:
0000110001101011000000010001101001100101001010010111001
1111010010001001011110101001001110001000001111111101001
0010101001011110000010100010111001010000111101010001101
0101110100000101000001110100101011111110011111110100011
1101010010011010100101010100101010000100000111101010011
1010101111
Pretty neat huh? Believe it or not, this is actually what is
being sent over the net in every packet of information between
you and the game server. To us it's just a bunch of 1's and 0's,
but to the computer, this is all of the info it needs. It breaks
these 1's and 0's down into information that it uses to show you
the game you are playing. Each 1 or 0 is a 'bit', and 8 'bits'
is a 'byte'. 1024 'bytes' is a 'kilobyte' and so on and so forth.
The first 32 'bits' in the packet above are actually the KORT
server's IP address (check it if you don't believe me), and
this is how the packet knows where it's going. More specifically,
it's how the routers out on the internet in between you and the
server know where to send it. This will have importance later.
2. Half-life net code
OK, so now we have a bunch of packets, that we know are being
sent back and forth between your client and the game server. In
a perfect world (or in a LAN game), the transmission of these
packets would be instantaneous. We would all be seeing the action
in real time. Unfortunately, this is not the case. It takes time
for each of the routers I mentioned above on the internet to send
the information on to it's destination. On average, your packet
will go to 10 or 12 different routers on its way to the game server.
The amount of time it takes for your packets to reach the game
server is referred to as your latency, or ping.
A ping of 100 means that it takes 100 milliseconds, or 1/10th
of a second, for your packets to reach the server.
Fortunately, the good folks over at Valve did their homework,
and gave us the miracle that is Half-life net code. The game server
knows that your packets are delayed a bit, and compensates for
this by sending you information that is relative to your latency.
Didn't catch that? OK, look at the example below, and maybe it
will seem clearer:
I join a game and I have a 100 ping, which means I am 100 milliseconds
behind what the server considers real time. An enemy passes in
front of me, so I turn and fire, but I am seeing the action delayed
by 100 milliseconds. That player is not where I think he is, he's
actually 100 milliseconds ahead of where I think he is. This is
where the net code comes in. To compensate for the delay, the
server knows that I am 100 ms behind the action, so it sends me
info that is 100 ms old. That way, what is being displayed on
my screen is the position of the enemy player relative to my delay.
Basically, I am telling the server "Hey, I'm 100ms behind
the action, please tell me where everyone else was 100ms ago."
Cool? Cool.
3. Latency and Bandwidth, or "Why does my ping suck?"
So now that we know how the server and client communicate, we
can take a look at the options that Counter-Strike gives us to
optimize that communication. Lets start with the 2 most important
factors in determining your game experience: Latency, and
Bandwidth.
Latency, also referred to as PING, is the amount
of time that it takes your information to reach the game server.
Bandwidth is the amount of data (packets) that your connection
can send and receive at a given time. The less latency between
you and the server means the closer you are to real time. Higher
bandwidth means you can send and receive more packets from the
server, and this keeps your game running smoothly. Latency is
out of your control, for the most part, so we will focus on optimizing
your bandwidth. Got a calculator? Good, you might need it.
Lets go back to those packets for a second. The packets that
are sent back and forth between you and the server vary in size,
but seem to average about 64 bytes. Half-life allows you to control
the number of bytes that you can send and receive from the server
through the rate and cl_rate commands. All of the
commands that we discussed are entered through the console.
The rate command controls the amount of bandwidth sent
from you to the server (upload) and from the server to you (download).
The cl_rate command controls only upload bandwidth. Both
commands have a maximum value of 9999, which is representative
of the number of bytes per second that your client is allowed
to send/receive. I would suggest setting this no higher than the
maximum rate that the server can send/receive, which in the case
of the KORT game server is 7000. To set the variables,
simply pull down your console while in game and enter:
rate x
cl_rate x
Replace 'x' with whatever value you want to use. So now we have
told our client "Don't, under any circumstances try to send
or receive more than x bytes per second.". Now we need to
tell it how many packets to send us per second so that we can
stay current. The two commands we use for this are cl_updaterate
and cl_cmdrate. cl_updaterate controls how many
packets the server will send us per second maximum, and cl_cmdrate
controls how many packets we will send the server per second maximum.
The maximum values for both of these commands are 99.
The relationship between cl_updaterate, cl_cmdrate and the rate
variable is very important. Still have that calculator with you?
Good. We already know that the packets that we use to communicate
with the server are about 64 bytes. Lets say we tell the server
to send us 90 packets per second. 90 x 64 = 5760. So right there
we are using about 5.6Kilbytes of bandwidth one way. We could
very well be using another 5.6Kilobytes of bandwidth to send info
to the server as well. This is all well and good if your connection
can handle this kind of bandwidth, but some of us can't. 56k connections
max out at about 5Kilobytes a second, and are best suited to handle
a constant stream of about 3Kilobytes. Knowing that, you can see
that it is best to lower your rate and cl_rate to about 3000,
and your cl_updaterate and cl_cmdrate to about 30 - 40. It's all
about testing your settings.
4. Net_graph
So how do I test my settings? Easy, by turning on the net_graph.
net_graph allows you to see the number of packets sent and received
from the server, and the resulting choke and loss.
Choke refers to packets that your client is trying to send,
but that it can't because your bandwidth is not high enough. It's
like trying to fire 100 gallons of water out of a garden hose.
The gallons of water are like your packets, and the hose is your
bandwidth. The hose will only allow you to send one packet, err,
gallon at a time, so the rest have to wait their turn. They are
CHOKED off. Get it? Loss refers to packets that the server
is trying to send to you that are lost because you are not allowing
them in. If the server is using a fire hose to shoot 200 gallons
a second at you, you can't expect to catch all of the water in
a 5 gallon bucket. Most of the water will be LOST. Same with your
connection. If you are requesting 90 packets a second from the
server, but you only have enough bandwidth to receive 60, what
do you think happens to those other 30 packets?
So what does all this mean? Well, if net_graph shows that you
have a high choke, try turning your cl_cmdrate down, or your rate
up. Alter those settings until the choke goes away, and your connection
remains stable. If net_graph shows that you have high loss, try
turning your cl_updaterate down, or your rate up, until the loss
disappears.
5. Real Time? I AM Real time!
Unfortunately, none of the bandwidth tweaks listed above will
help with your ping, but what they will do is ensure that you
are using your bandwidth efficiently, and that your game runs
as smooth as possible. Of course, high choke or loss can increase
your ping, but in the end you really can't make your connection
any faster than it is. However, if you already have a ping that
is 40 or less, then you may benefit by having the server send
you real time updates, instead of the lag compensated updates
described above. There are 2 commands that you can use, cl_lc
and cl_lw, to control if you are interacting with the server in
real time. cl_lc stands for lagless client and cl_lw stands for
lagless weapon. Turning lagless client off by setting cl_lc 0
in console will cause the server to send you current information,
i.e. the server does not care how much latency you have, you will
always get real time info. With a ping of 40 milliseconds or less,
you would not notice the difference with this on or off, so it
is best to keep this off. Lagless weapon is a bit different. It
relies on server confirmation of your shots fired before displaying
those shots on your screen. With lagless weapon on, your gun will
fire on your screen the instant you press the trigger. In actuality,
this is only how you see it. The server has to wait for the packet
containing your shot to reach it, and in some circumstances, this
packet might be choked off or dropped and never reach the server
at all. Turning lagless weapon off by setting cl_lw 0 in the console
will require the server to confirm all of your shots before they
are displayed on your screen. This ensures that you see things
exactly as the server sees them, and that all your shots are confirmed.
6. Tips of the trade
As a rule of thumb, while adjusting your cl_updaterate and cl_cmdrate
settings, you should try to get them to be a multiple of your
frames-per-second, plus 1. I.e. If your FPS is 80, try setting
your cl_updaterate to:
81 (FPS / 1 + 1)
41 (FPS / 2 + 1)
21 (FPS / 4 + 1)
Also, make sure that if you turn cl_lc off that you also turn
cl_lw off. I would not do them independently.
Note: This tutorial was written
by SlightCrazed. A big thank you to him, boy does this guy KNOW
this stuff!
|