Repository navigation
Make footstep sounds consistent - #2264
Open
sunmachine wants to merge 12 commits into
Open
sunmachine wants to merge 12 commits into
sunmachine wants to merge 12 commits into
Conversation
sunmachine
commented
Oct 18, 2026
sunmachine
commented
Oct 18, 2026
sunmachine
force-pushed
the
footsteps/sound-consistency
branch
5 times, most recently
from
October 18, 2026 20:46
5e81a24 to
c12601f
Compare
sunmachine
force-pushed
the
footsteps/sound-consistency
branch
from
October 22, 2026 01:22
c12601f to
ca7d929
Compare
sunmachine
force-pushed
the
footsteps/sound-consistency
branch
from
October 24, 2026 01:41
ca7d929 to
17745e0
Compare
sunmachine
force-pushed
the
footsteps/sound-consistency
branch
3 times, most recently
from
October 24, 2026 21:26
30d1500 to
4b55936
Compare
No behaviour change. UpdateStepSound keeps a CNEO_Player pointer instead of casting inline, the per-surface quiet and loud volumes move into CNEO_Player::GetSurfaceStepVolume with the quiet flag passed in, and the SDK's 65% crouched scale gets a name, NEO_FS_CROUCH_VOLUME_SCALE. The SDK switch stays under #else for non-NEO builds.
No behaviour change. IsInSilentMoveMode names master's walk-or-aim condition, the two class speed branches collapse into one check, and the 50 u/s floor gets a name, FS_MIN_STEP_SPEED.
The engine defines FL_ANIMDUCKING for a crouch in progress, but nothing in this codebase set it. CGameMovement::Duck now sets it while the crouch key is down and clears it on release. It travels in m_fFlags, so every client can tell a crouch that is starting before FL_DUCKING arrives 0.4 s later. Nothing reads it yet; footsteps use it in a later commit.
Since NeotokyoRebuild#2151 UpdateStepSound reached SetStepSoundTime while the player was airborne, because the silent check could no longer return early. The step timer restarted every tick in the air, so the first step after a landing came at a random phase up to half a second late. Return before the timer is reset when off the ground and out of water, as the SDK does, so the timer waits at zero and the step lands on the tick the player does. Ladders are unaffected.
Crouching alone was never silent: only crouch with aim or walk was, below 0.7x the class crouch speed, so a plain crouch walk at 120 to 150 u/s made footsteps. Crouched steps are now silent while ground speed is at or below FS_SILENT_MOVE_THRESHOLD, 0.825, of the player's run speed with the weapon, which is their crouch walk speed plus 10%. The weapon is on both sides, so the headroom is the same with every gun. Crouch sprinting, slides and pushes stay above it. Ladders are always audible: climb speed is 200 u/s whatever the posture and ground speed is near zero while climbing. Ground speed rather than full speed, because other clients estimate vertical speed from origin changes on stairs. This takes a side on parity: the original game plays crouched steps above 60 u/s.
Standing walk and aim were silent below 0.7x the class run speed, which ignores the weapon, so the headroom swung from about 10% to 38% by gun and walking with the BALC was always audible. Walk speed is the same number as crouch walk speed, so both now use the crouched rule: silent at or below FS_SILENT_MOVE_THRESHOLD of run speed with the weapon. With a 0.85 weapon the standing limit is unchanged; slower weapons get the same 10% as crouching; the BALC becomes silent while walking. Aim moves at 0.6x and keeps about 37% headroom, as before.
Holding a movement key while turning the view builds speed toward the new direction faster than friction removes the old one, so turning really raises ground speed, by up to about 50% of crouch walk speed at 180 to 360 degrees per second. That is more than the 10% headroom, so looking around while crouch walking made footsteps. Track the view turn rate from the eye yaw, which every client receives, holding its peak and decaying over friction's time constant, and add up to FS_TURN_HEADROOM to the threshold as the rate approaches FS_TURN_RATE_FOR_FULL_HEADROOM. Sprinting gets no headroom, so crouch sprinting stays audible mid-turn. A yaw change over FS_TURN_SNAP_DEGREES in one sample is a snap, such as a respawn or a remote player leaving dormancy, and is ignored.
Switching movement keys, W+D to W+A, raises ground speed the same way turning does but without moving the view, so the turn headroom cannot see it. Once a player has been crouched, walking or aiming on the ground for FS_FORGIVENESS_SETTLE_TIME and is not sprinting, the first step that is over the threshold but under FS_FORGIVENESS_MAX_SPEED is skipped. The next one plays, and the skip comes back after FS_FORGIVENESS_RECHARGE_TIME under the threshold, so a brief wiggle stays silent and repeating it does not. The settle time keeps slides from a run and landings audible.
The SDK plays the quiet or loud step volume by comparing speed against 80 u/s crouched and 220 u/s standing, tuned for its third speed crouch. Every NEO crouch is above 80, so crouched steps played at 0.325, louder than a standing run at 0.2, and a heavy weapon could drop a standing sprint under 220 to the quiet volume. Sprinting now picks the loud volume and everything else the quiet one, then the SDK's crouched scale applies: run 0.2, sprint 0.5, crouch sprint 0.325, other audible crouched steps 0.13. The step interval still follows speed.
The game only counts a player as crouched once the 0.4 s crouch animation ends, and they keep run speed until then, so a running step almost always played after pressing crouch. Walk and aim raise the threshold at once but can catch a step the same way. Pressing any of the three now arms the next audible step: it is held instead of played, dropped once the player has settled into the quiet mode, and played if they are still loud FS_HELD_STEP_SETTLE_TIME after the mode took effect, as in a slide, a push or a crouch sprint. Letting go of the arming key while the step is held plays it. Each key arms from its own press, so crouch pressed while still aiming counts. Leaving the ground or grabbing a ladder forgets the held step. A held step plays at the volume for how the player moves when it plays, and keeps the next step at least FS_HELD_STEP_MIN_GAP_MS away without restarting the cadence. Crouch is read from FL_ANIMDUCKING so other clients see the press. On its own this lets a player tap crouch, settle, release about every 0.7 s and drop one step per cycle while moving at run speed for most of it. The next commit closes that.
Completes the previous commit's design. A held step that was dropped on settling now plays if the arming key is released within one step interval of the drop, unless another quiet mode is still held, so going from crouch to walk is not a tap. A dropped step then always costs a real step's worth of quiet movement: tapping crouch, walk or aim can delay a step but never skip one.
A flat jump falls too slowly for the engine's landing sound, so the footstep players hear on landing is the regular step whose timer ran out in the air. With crouching a quiet mode, a crouched landing at walk speed made no sound. After at least FS_LANDING_MIN_AIR_TIME off the ground, the next step decision is never silent, whatever the posture. Shorter is a stair edge or a bump. A standing jump in place still makes nothing, since speed is under the 50 u/s floor.
sunmachine
force-pushed
the
footsteps/sound-consistency
branch
from
October 25, 2026 00:30
4b55936 to
2b7cd16
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Tip
Read here for more in-depth info: Footstep Consistency Audit. It covers the diagrams, how the current rule came about, and the test logs.
Footstep sounds were inconsistent, mostly around crouching. This makes crouching quiet, gives crouch, walk and aim one rule, and closes a few ways steps leaked out. Movement speeds are untouched; only whether, when and how loud a step plays changes.
The rule: mode picks the threshold, speed decides the step. Quiet is opt-in.
The weapon is on both sides, so a quiet mode is silent whenever its stance modifier is at or below
SILENT_MOVE_THRESHOLD(0.825): crouch and walk at 0.75, aim at 0.6. On master the threshold wasGetNormSpeed * 0.7with no weapon term, so the headroom changed with the gun.Changes
Volumes (recon on concrete, assault matches)
Unchanged
Testing: ~15 play passes against a
bot_mimicbot with temporary logging (kept on a separate branch). Every commit builds on its own.Toolchain
Linked Issues