Latest Topics

Team Ministry
Team Extreme
Team Storm
CS:S Netcode
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.

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:

{short description of image}

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.


TEAM PRO-HL | S@NDM@N 750 | Treb 816 | rosso 732 | Delta 789 | Sy- 39 | dp 513 | CH|EF 0

-|MOD|- Eddie 64
-|MOD|- ash :D 252
-|MOD|- Rhaz 75
-|MOD|- [R]4WRCH1CK3N 596
-|MOD|- Crowth  
-|MOD|- Jamesta 128
-|MOD|- Metta 630

-|MOD|- Davis 197
-|MOD|- nS 197
-|MOD|- ToByB  
-|MOD|- Syphon 277
-|MOD|- Lut  

-|MOD|- DreS 139
-|MOD|- SlaYeR  
-|MOD|- Dan' 178
-|MOD|- LT^ 135
-|MOD|- Gumpster 48
-|MOD|- Krabzzz  

Clan Base
Enermy Down
Esports Heaven
Electronic Sports League
Electronic Sports World Cup
Universal Gaming League
World Cyber Games
Crosshair Guide
Setting Your Rates
Ranking System
TEC9 Weapon Guide
MP7 Weapon Guide
P90 Weapon Guide
Famas Weapon Guide
Galil Weapon Guide
M4a1 Weapon Guide
AK47 Weapon Guide
AWP Weapon Guide
Nuke Map Guide

Netcode Guide
DE Maps
CS Maps
AWP Maps
AIM Maps
AWP ProHL Yard
Trumanzi Interview
Turgid Interview

Opposing Force
DeathMatch Maps

Half-Life & AG
Scripts & Configs
AG Console Commands
DeathMatch Maps
Asia Carrera Interview
Opposing Force

Pro-HL Player Search
Pro-HL Admin Log-in
Legit-Proof Search
Steam ID Finder

Pro-HL Blacklisted
VAC Banned
Steam Bans
Source Bans
{short description of image}