|
[an error occurred while processing this directive]
|
|
Home > Counter-Strike Source Guides & Tips > CS:S
Netcode Tales
CS:S Netcode Tales
Writen By: Bomberm@n

I've been playing around with CS:Source servers recently to try and understand
how the game actually works and hopefully to find out some things that are
useful to know when playing. What follows is what I've found. Some of it's
complicated, some of it's simple, some of it's interesting but most of it is
boring
There are three situations that I am going to explain.
1. You strafe out from behind a box/wall and back again quickly, you
don't see the opponent fire, yet you take damage after you're back in cover.
2. You run round a corner straight into an opponent, unload a whole clip
at him and die. When you open the console it says you hit him twice even though
you emptied your gun at him from point blank range.
3. A player strafes or runs across you, you fire and see blood on the
player model, yet the hit doesn't register and they don't receive any damage.
I've done a lot of testing over the course of a week or so to try and work out
why these situations occur (and whether they're bugs or not). The conclusions
I've reached come from what I've seen during the course of that testing, my
general knowledge of latent systems, digging around in the SDK, and
occasionally just using my head to think about shit. I've tried to keep it as
simple as possible and have included some helpful pics to illustrate my
explanations.
First a few definitions:
Latency (ping) - The time delay between your computer sending a packet
of information or update, and the server receiving it (and vice versa).
Server - The CS:Source server engine, usually running on some computer
on the internet.
Client - The game running on your computer. The thing with guns, sounds
and people running around
Shot Trajectory - The line between the end of your barrel and where the
bullet you fired hits something.
Hitbox - Player models in CS:Source are divided up into
"hitboxes", which are block type areas of the model. If a shot hits a
hitbox it scores a hit. You can view model hitboxes by opening the player
models in a model viewer.
CS:Source - The basics
As with any online shooter the main problem that needs to be overcome is
latency. Each player needs to feel like they and their opponents are moving
freely and smoothly when in fact the game only updates periodically and there
are large time delays between sending updates and them arriving at their
destination.
Some simple stuff first:
Your position on your client, on the server, and on other players' clients is
never in sync. This is because of the delay between you sending your position
to the server, the server simulating a "frame" of the game and
updating your position, the server sending out an update of your position to
the other clients, and them receiving it. Couple this with the fact that on
your client you are able to move smoothly (not just on sending updates) and you
get one messy situation when it comes to working out where people are and
whether shots that are fired should hit them.
The way that this situation is dealt with leads to some confusing effects that
can sometimes be seen in the game.
Situation 1: *The laggy hitbox*
You strafe out from behind a box/wall and back again quickly, you don't see the
opponent fire, yet you take damage after you're back in cover.
The Explanation:
To explain what's happening we have to consider what's happening on your client
(player 1), the server, and the enemy's client (player 2).
Things you need to know before I go any further:
1. Actual hits (hitbox positions, if you like) are calculated on the
server. The client also keeps track of the hitboxes for client only effects
(like sparks off a helmet), but I will talk more about this in situation 3.
2. I assume a round trip update time of 30ms (there is a delay of 30ms
for you to update the server and the server to update you. This number is not
actually important, only the fact that there is delay caused by the time it
takes for packets to wing their way down the wire is). In reality, this number
is actually a bit higher (regardless of ping).
3. The time it takes the server/client to process an update is small
enough to be ignored.
The situation occurs because of the "lag compensation" that is built
into the game engine. To fully appreciate why you need it, we'll look first at
what would happen if there wasn't any lag correction.
0ms (snapshot 1)
Player 1: hits strafe key -> moves out from behind box -> spots
player 2 (who is stationary for simplicity)
Server: nothing (update has not reached it yet)
Player 2: nothing -> stays still, waiting for player 1 to pop out
30ms (snapshot 2)
player 1: Hits opposite strafe key -> moves behind box
server: Receives update from player one (snapshot 1) positions player as
in the open and sends an update to player 2
Player 2: Nothing (remember the server update will take 30ms to reach
him)
60ms (snapshot 3)
Player 1: Is behind box on his client
Server: receives update from snapshot 3, puts player 1 position behind
box (so player 1 and server are in sync)
Player 2: Gets the snapshot 1 update from the server -> sees player 1
-> fires gun on target at player 1 -> hits thin air
When the server receives player 2's shot, player 1's position is behind the box
so the shot misses. This isn't very fair, because on player 2's screen player 1
was in the open and the shot was on target, however on the server player 1 is
somewhere else. hmmmm, not good.
So how do you solve this problem? Well what the source engine seems to do is to
apply a clever bit of maths that takes the trajectory of player 2's shot and
translates (moves) it so that if it was on target on player 2's client, it hits
player 1 in whatever position they are now in. The server calculates the exact
amount to "move" the trajectory based on each client's latency
(ping).
The red "hitbox" shows where the player model was on the client when
I fired. The blue hitbox shows where the player model was on the server when it
got my "shot" update. The red block on the hitbox shows where my shot
hit the player model on my client, the blue block on the blue hitbox shows the
position that the server cleverly translated my shot to based on my ping. Note
that on the other player's client, their position is probably the same distance
again ahead of the blue hitbox. Confusing!
So *with* lag correction, the scenario goes like this:
0ms (snapshot 1)
Player 1: hits strafe key -> moves out from behind box -> sees
player 2.
Server: nothing (update has not reached it yet)
Player 2: nothing -> stays still, waiting for player 1 to pop out
30ms (snapshot 2)
Player 1: Hits opposite strafe key -> moves behind box.
Server: Receives snapshot 1 update -> positions player in the open
(nobody else has seen player 1 move yet)
Player 2: Nothing
60ms (snapshot 3)
Player 1: is behind box
Server : Gets snapshot 2 update -> positions player behind box ->
with lag compensation in effect: the hits that hit player 1's position in
snapshot 2 will be translated to their position behind the box.
Player 2: Gets snapshot 1 update from server -> sees player 1 ->
fires on target -> when the server receives the shot, it checks player 2's
current latency, applies the magic translation formula (which puts the shot
straight through their position behind the box) and therefore concludes that
the shot was on target. The damage is sent to player 1, who gets confused
because they are behind the box/wall.
Now *this* is fair, although on his client player 1 is safe behind the box,
player 2 shot the second he *saw* player 1, and so it's fair that he should
expect to land a hit. The only problem is that player 1 gets the damage whilst
he is behind the box which can be confusing. So what the lag compensation has
done is allow player 2 to hit player 1 regardless of the delay between him
moving and player 2 *seeing* him move. Nice one.
Other benefits to this kind of lag compensation are that you don't need to
"lead" your target to land a hit, and when two players meet each
other head on after going round a corner, the player with the lower ping
doesn't get an advantage.
Have a look at these screenshots (taken with sv_showimpacts 1), that show the
difference between client (red) and server (blue) player positions, and the way
that shot trajectories are moved from the client to the server position (the
position that the shot hit is shown with a red or blue block):
Situation 2: *That's bollocks, I hit him 15 times*
You run round a corner straight into an opponent, unload a whole clip at him
and die. When you open the console it says you hit him twice even though you
emptied your gun at him from point blank range.
Explanation:
This situation arises (similarly to the first situation) because of the latency
(delay) between things happening on the server and you seeing them on your
client. The reasons behind it and the explanation are very similar to those for
situation 1.
The most important thing to remember here, is that things happen on the server
*before* you see them on your client. For the sake of simplicity, we are going
to assume that both clients have the same latency so you don't have to worry
about how lag compensation fits in.
As you approach the corner, both clients are aware that the opponent is around
the corner, so there is no delay to them appearing. As soon as the other
appears, they both start firing. Now because of the delay, it will take 60ms
(using the same assumed numbers as in situation 1) for each client to see the
other firing, and for any damage to be sent from the server to the clients.
What this means is that in the time it takes for the server to calculate hits
and send damage, you might have fired 10 rounds. Now if your opponent fired a
split second before you (or if he fired after and he got a headshot), on the
server you are probably already dead but your client won't know that you're
dead for at least 60ms after you first saw the opponent. So although you appear
to keep firing, the server just ignores the shots that you fire between it
working out that you're dead and the client acknowledging it and killing you.
Situation 3: *The "no damage" hit*
A player strafes or runs across you, you fire and see blood on the player
model, yet the hit doesn't register and they don't receive any damage.
This one is to do with the way that the server translates your shot trajectory
to its new server side position. Not only does the server keep track of all the
object and model positions, but in the case of player models it also runs the
animations (like running, walking etc). When you fire, and the shot trajectory
is translated on the server, it tests for hits on the model in whatever
"pose" the animation is at. Because of the latency between client and
server, the player models on both are very rarely in sync. I.e. They are very
rarely on the same frame of animation, so the model's "pose" at a
given point in time is different on each. Animations like run and strafe cause
a fairly large amount of movement over the whole model. The head bobs, as do
the arms, and the legs "run". The problem this causes is that a shot
that on the client narrowly hits the arm, leg or head has its position
translated on the server, the server model can be in a very different pose,
i.e. the head could be lower, or the leg in a different position, so the shot
actually misses.
Here is a screenshot that shows that the player model in a different
"pose" on the client to the one on the server:
Notice in particular the position of the legs, which are very different between
the red and the blue. A shot that hit on the client at the position marked as A
(red), would not register on the server because the player's leg is in a lower
position (a different frame of the run animation).
Here's a typical shot that doesn't register - I hit right on the edge of the
back (which was in a diff pos on the server due to the "bob") and the
blue block is on the wall behind (with no blue hitbox) as the server did not
register the hit:
This isn't so much a bug as a necessary shortcut that needs to be taken for
performance reasons. In order to test for hits with the same model pose as is
on the client at any given time, the server would need to keep track of or
calculate all the delayed model positions for every player on the server.
On a 16 man server this would mean:
16 x 15=240 model positions that need to be calculated and hit tested if all
the players where in the same area and firing at the same time (the worst
case).
So it is probably just not feasible to do this.
Note that the opposite of this situation also happens (you miss on the client,
but you hit on the server) so it all evens out nicely anyway.
Summary of Useful Info/Conclusions
1. sv_showimpacts is the daddy of all server commands. It allows you to
see where exactly your shots land on both player models and objects giving you
ultimate feedback on your aim. It also allows you to test which objects and
walls can be shot through with which guns. By shooting at walls, you can
examine the bullet patterns and accuracies of each gun at short, medium and
long range whilst standing/crouching/running etc. Each gun has a different
pattern and the first shot on some is not the most accurate. Use the command to
hone your burst firing to the optimum number of shots for accuracy.
2. If you want to be guaranteed a hit then you need to hit the player
models nice and in the middle. Arms and leg shots are the worst for registry
because they have the most difference between client and server (you get about
70% registry). The very top or back of the head is not great either as the head
bobs.
3. Blood splats on the model are client side, and do not indicate a
"true" hit. Blood splats that land on the walls/floor etc are done
server side and are the best indication of a registered hit. Sparks that fly
off the helmet are also done client side.
4. You don't need to lead/trail your target. If you aim straight at them
and fire you *will* get a hit (unless you hit an arm, leg or the top of the
head while they are running/strafing, in which case you've got about 70% chance
of registering a hit).
5. A high ping (as long as it is not accompanied by choke or loss) is
not much of a disadvantage within reasonable limits because of the lag
compensation. I can't tell you what the limits are (100? 150?) because I have
no way of getting a high ping to a server that's in the next room in order to
run tests.

Previous Page
|
|