CS2 converts raw mouse counts to view angles in float32 as yaw −= counts × zoom × sensitivity × m_yaw and pitch += countsY × zoom × sensitivity × sensitivity_y_scale × m_pitch, with m_yaw and m_pitch both defaulting to 0.022. Angles are normalized to ±180 natively and the command pitch is limited to ±89. When you are scoped, the extra factor is zoom_sensitivity_ratio × activeFov / referenceFov, applied after an integer truncation — so scoped sensitivity is not a smooth function of your zoom level.
Transcribed from the current CS2 client binary (manifest 5183754434502602414) with the exact float32 vectors pinned by unit tests; convar defaults read from the current build's convar list.
Aim conversion is the kind of mechanic where a formula that is nearly right is worse than no formula, because the error only shows up as a drift you cannot see in a single flick. So this one was transcribed from the client binary rather than fitted, function by function, and the exact float32 vectors are pinned by tests so a refactor cannot quietly change the arithmetic.
Two details differ from the obvious model. The yaw term is sign-flipped relative to the pitch term, and the vertical axis carries its own extra scale factor rather than sharing the horizontal one. Normalization and the pitch clamp happen in the native order, which matters at the boundaries.
Scope behaviour is where the guesses had been worst. The real levels are 90 → 40 → 10 for the AWP and 90 → 40 → 15 for the SSG08 — an earlier inferred second level of 15 for the AWP was simply wrong. Standard scopes interpolate with an integer smoothstep over times that come from the weapon data; manual unzoom starts 70% of the way back toward 90; and firing a scoped AWP or SSG unzooms over 0.05 s then auto-rezooms over 0.1 s once the weapon is ready. The AUG and SG use a different path entirely, approaching 45 with a bias curve.
The honest limit is at the input end. Everything above describes what the game does with a mouse count once it has one. Whether a browser receives the same physical counts a native client does is a separate question, and a working Pointer Lock implementation is not proof that it does.
Located through the client input class's vtable slot and followed into the conversion functions; the arithmetic transcribed as float32 and pinned by unit tests.
Evidence
Exact float32 vectors are committed as test goldens. The 0.022 defaults come from the current build's convar list.
Current scope and input FOV: AWP 90 → 40 → 10, SSG08 90 → 40 → 15; standard scopes use an integer smoothstep with weapon-data zoom times; manual unzoom starts 70% toward 90; AWP and SSG shot-unzoom 0.05 s then auto-rezoom 0.1 s; AUG and SG approach 45 with a bias curve; nominal 90 is 73.7397919° vertical
Value
40 → 10 (AWP), 40 → 15 (SSG08)
Confidence tier
TRANSCRIBED (T3), integrated 2026-07-22
How it was derived
Read from both the client and server binaries of the current build together with the current weapon data, then pinned as bit-exact goldens.
Evidence
Supersedes an inferred 15° AWP second level and a hand-chosen 70° viewer field of view — both of which were estimates that this transcription replaced.
Open questions — what is not known
Physical count delivery is unverified.
The conversion law is exact. Whether a browser receives the same raw counts a native client receives is not established, and a successful Pointer Lock capture is not evidence about HID counts.
Last updated 2026-07-22 — the date of the measurement, not of this
page's rendering. What the confidence tiers mean. Memorin is not affiliated
with or endorsed by Valve; Counter-Strike 2 is a trademark of Valve Corporation.