Notes:

Short Range: 1 - 500 units.

Medium Range: 501 - 1000 units.

Long Range: 1001 - 1500 units.

Armoured/Unarmoured: Opponents armour status.

Running: Movement speed is weapon maximum.

Standing: Movement speed is 0.

Tap Shooting: Pause between each shot (effectively ignores firing inaccuracy).

Spam: Fire as fast as possible.

Ignore Inaccuracy: Show raw damage values, ignoring probability of hitting the target.

Damage/Time: Y axis scale is amount of damage as a function of time (i.e. amount of time required to fire 10,000 rounds).

Damage/Weapon Cost: Y axis scale is damage as a function of weapon cost.

Penalize smaller mags: Damage amount is penalized by smaller magazine size.

Penalize less ammo overall: Damage amount is penalized for weapons that have less ammo overall.

n.b. dualies have the most ammo, so the above two all relative to them.

Fix accuracy axis: Use a constant scale for the x-axis, making it easier to compare across different variables.

Fix damage axis: Use a constant scale for the y-axis.



Accuracy Calculation

This is the probability of hitting a circular target of radius 6 units (12 units diameter), across the various ranges, and under the various conditions. In game, 1 unit = 1 inch, so 12 units is 1ft/roughly a 30cm circle.

In the plot, less accurate weapons have smaller circles while more accurate weapons have bigger ones. The x-axis represents accuracy. If you want to compare across ranges, enable the "Fix accuracy axis" option.

Accuracy has been determined by collecting 10,000 sample pistol shots from a simulation of the CS:GO shoot mechanics I developed in python. Most of the raw mechanics information came from a document by reddit user Altimor, which detailed the various formulas and how they are applied.

The source code of CS:GO is not available, so some liberties have to be taken. I can't be 100% confident the data is a true reflection of actual game mechanics, but at the least, any bias or innacuracy present would be applied to each weapon equally, which should enable reasonable relative comparisions.

The only missing thing I am aware of is weapon reload time, as I don't have accurate data. I don't think it really matters so much as you generally don't reload in the middle of firefights.

I also do not model recoil, it effectively assumes perfect recoil control while spamming, but the model does include the inherent randomness applied to all shots fired.

Damage

The default y-axis shows damage as a function of time. Weapons delivering more damage are redder in color, while weapons doing less damage are bluer in color.

The actual damage values aren't particularly interpretable, the goal of the plot is to show a relative comparison of all the pistols under different circumstances. Weapons that are close perform similarly, weapons far away have large differences.

The data is the average for each pistol over 10,000 shots, and firing times vary considerably. The quickest is the CZ at 100ms (the same rate as the AK-47 rifle), and the longest is the revolver at 500ms. Displaying damage per time is convenient way of controlling for different firing speeds.

You can also use damage per the in-game weapon cost. All the pistols are relatively cheap, and I dont feel its particularly accurate measure but was easy to add so threw it in there.

When "Ingore Inaccuracy" is left un-checked, the damage values are multipled by the probability of landing a shot (i.e. accuracy), giving some measure of the expected value of each pistol under the other conditions (range, shooting mode etc)

Comments

In general, I think what these plots show are inline with the accepted meta. Which pleases me, as it means I probably haven't stuffed up majorly along the way.

The dualies (elite) are very strong against unarmoured opponents. They fire very quickly and have a lot of ammo, good for running & gunning. Tec9 is the best against armoured opponents, even considering magazine sizes.

The revolver packs a hell of a lot of punch, which tends to override most other factors. The deagle has a large movement penalty, but when standing and tap shooting it performs in-line with the revolver.

Unsolved Mysteries

There's a couple of things I am still not sure about, or don't really make sense. If you know the answers please get in touch.

First is how the reported weapon accuracy ranges are derived.

Lets say I fire the AK-47 standing still, which gives 6.41 + 0.6 = 7.01 mm inaccuracy.

If i go in-game and turn on cl_weapon_debug_print_accuracy, it says its accurate range is 30.7m to guaranteed hit a 30cm target.

It is not clear to me how the game gets from inaccuracy (spread + standing + firing + moving) to that distance.

I thought that perhaps that is the inaccuracy radius, so 2x would be the diameter of the inaccuracy circle, and to hit a 30cm (0.3m) plate we would have to be within:

0.3 / (2 * 0.00701) = max accurate distance = 21.4m

If we flip it round, we know the base inaccuracy is 7.01 and effective range is 30.7m, so the game is using 2 * 0.00701 * 30.7 = 0.4304 m target, or 43 cm and roughly 17 units, a lot bigger than 30cm. If you skip the 2x part it gives 0.2152 m, which is still a long way from 30cm really.

The second mystery is in the display for debug_print_accuracy, the value of SpreadDistance seems to be (Inaccuracy + Spread) * 320. I don't know where that 320 value comes from.

Contact

You can find me on twitter here

You can email me pete dot werner at gmail

Thanks for reading!