Repository navigation
POV demos: a shot right after a reload plays its firing sound instead of an empty click (#1029) - #1040
Merged
4 commits merged intoOct 26, 2026
Merged
POV demos: a shot right after a reload plays its firing sound instead of an empty click (#1029)#1040 4 commits merged into
4 commits merged into
Conversation
A POV demo's own gunshots are the recorder's predicted fire events, and playback replays only those: weapon prediction does not run during a demo (HUD_PostRunCmd is never called), so the client never plays its empty click there either. A round the server fired that the recorder's client did not predict (fire pressed a moment before the gun was ready) has no event and plays nothing. ds_sound_fix_pov_dry_fire (default 1) watches the server's clip count (CurWeapon), pairs each drop with the recorded shot sound just before it, and plays the gun's own fire handler for a round with none: sound, muzzle flash, shell and fire animation. POV demos only; a real empty press drops no clip and is left alone. Also adds the probe and survey used to find it (153 POV demos, 34 recorder names: 220 of 33,937 shots have no recorded event). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…or seeks Checked against the same logic run over 153 POV demos (the survey's SIM lines): a multi-round drop is a weapon taken at the round's end, the first count after a weapon is put away is no round, and the engine clock runs smooth through the demo player's stepped seek. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 25, 2026
Closed
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.
Release note: Fixed: in POV demos, a Garand or K98 shot fired right after a reload no longer plays an empty-gun click instead of the shot (ds_sound_fix_pov_dry_fire, on by default).
Closes #1029
What was wrong
In a POV demo, the recording player's own gunshots are the events his game predicted. The demo saves those events, and playback replays them and nothing else: the game's weapon prediction doesn't run during a demo (
HUD_PostRunCmdis never called). That's also why the empty-gun click (357_cock1.wav) never plays in playback, real or not.A round the server fired that the recorder's game didn't predict has no event, so it plays nothing at all: no sound, no muzzle flash, no recoil. That's the "click". It happens when fire is pressed a moment before the gun is ready (all 4 cases in the known demo were 40-110 ms early).
It's about 1 shot in 360 (94 of 33,807 shots, 153 POV demos, 34 recorder names). Full findings are on #1029.
What this does
ds_sound_fix_pov_dry_fire(default 1;2logs every round), new modulegoldsrc-hooks/src/pov_dry_fire.rs.CurWeapon.missing_shotsalready notes.missing_shotsgainsplay_fire_event, andEventArgsis shared.Checked offline with the same logic over the 153 demos (
pov_dry_fire_survey'sSIMlines):Decisions
verify_*_offsets.py.CurWeapon's handler comes frommsglog's table, whichverify_msglog_table.pychecks (passes). The fire handlers are noted at runtime. client.dll only, so both builds.cfg_scan/command_suggest.jstier. Tiers are for pipeline-internal commands. This is an ordinary user setting, allowed everywhere, likeds_player_fix_model_flicker.dodcrate's id table: the rest (British guns, MGs), which no surveyed demo fired.ds_spec_match_pov; HLTV is untouched (IsSpectateOnly()).Test done
All on
ktps8w3-dyelife_ih_anzio_h1with this branch's DLL andds_sound_fix_pov_dry_fire 2, Brain account.POST (probe
local\game-probe\20261025-005939):ds_sound_fix_pov_dry_fire 0, then 850 → 859 s: no rounds played.local\review-images\1029\post_fix_on_855_8.png,post_fix_off_855_8.png). In HLAE'ssound.wav, an onset at 855.84 s that isn't there with it off.PRE (probe
local\game-probe\20261025-010145):pre_fix_on_855_8.png) and a sound onset at 855.87 s.R&D build, POST (logs every client sound,
HUD_PostRunCmdandHUD_TxferPredictionData; probes20261024-231648and20261024-233046):HUD_PostRunCmdis never called during playback;357_cock1.wavnever plays;Builds and tests:
cargo test -p goldsrc-hooks: 782 passed, 9 of them new;-D warningsfor host, i686 andanalysisexamples;cargo fmt --check;npm run test:unit: 854 passed;app-boot.spec.js: 3 passed;verify_msglog_table.py: OK.Your test
Test DLL:
local\test-1029\dodstudio_goldsrc_hooks.dll(pick1029in the Hooks DLL dropdown).viewdemo ktps8w3-dyelife_ih_anzio_h1, thends_demo_seek_to 849.7, and let it play.ds_sound_fix_pov_dry_fire 0, then seek back to 849.7. The 855.7 shot is silent again, as stock.Other open PRs touching the same files
commands.rs/lib.rs/ Commands.txt /docs/dodstudio_commands.md/console_commands_data.js: Weapon list stays hidden in POV playback with hud_fastswitch 1 (#1032) #1034, Rename any player in a demo from the console, any length, everywhere their name shows (part of #1021) #1030, Kill feed: change who got a kill, who died or the weapon, or hide one kill, from the console (part of #1021) #1026, Kill feed: an even layout where every weapon icon has the same height and nothing is cut off (#1022) #1023, Kill feed: outline the names and put boxes behind lines or names (part of #562) #1000, R&D: show the overview map in POV demos (part of #897) #906, Render while capturing: each clip renders as soon as it's recorded, and a long batch waits for space instead of filling the drive (#861) #885, R&D: a restyled health readout drawn by the hook (part of #849) #882, Review highlights: console commands can't move the demo or the camera while a review runs (#855) #880, While a demo loads, the demo player bar shows how far along it is (#465) #758, Hide server HUD text and engine centre text (part of #677) #717.msglog.rs: Rename any player in a demo from the console, any length, everywhere their name shows (part of #1021) #1030 and Hide server HUD text and engine centre text (part of #677) #717.analysis/examples/README.md: Weapon list stays hidden in POV playback with hud_fastswitch 1 (#1032) #1034.Whichever merges second regenerates
console_commands_data.js.🤖 Generated with Claude Code