Server:
- Reset nextSnapshotTime for active clients after seek so
SV_SendClientMessages doesn't skip sending (was comparing
future nextSnapshotTime against past svs.time)
- First frame always a keyframe (beginning seekable)
- Keyframes during normal playback only reset delta state,
no SNAPFLAG_RESET_ENTITIES (no visual glitch every 5 sec)
Engine client:
- Reset cl.oldFrameServerTime on SERVERCOUNT toggle to prevent
"time went backwards" error in CL_SetCGameTime
cgame:
- Handle backwards time in CG_ProcessSnapshots for demo seek:
accept the time jump, reset cg.time, clear all entity state
(currentValid, interpolate, time-dependent fields), clear
local entities (particles, gibs, smoke), wait for next snapshot
- Prevents CG_InterpolateEntityPosition NULL nextSnap error
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
On unpause, toggle SNAPFLAG_SERVERCOUNT and set SNAPFLAG_RESET_ENTITIES.
In CL_ParseSnapshot, detect SERVERCOUNT toggle and hard-reset
cl.serverTimeDelta instead of letting CL_AdjustTimeDelta slowly drift.
During pause, the delta drifted because snapshots had frozen serverTime
while cls.realtime advanced. Without the hard reset, it took 1-2 seconds
of choppy interpolation to re-sync.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
cgame runs its own PmoveSingle for the free camera using real time,
independent of server time. Solves pause freezing — camera moves
smoothly while svs.time is frozen.
Changes:
- usercmd_t: add optional origin[3] with 1-bit flag (zero cost for
normal gameplay, 13 bytes during demo viewing)
- msg.c: serialize optional origin in usercmd delta encoding
- CG_SETCLIENTORIGIN trap: cgame sends camera origin to engine
- cl_input.c: CL_FinishMove writes cgame origin into usercmd
- cg_predict.c: CG_PredictPlayerState runs local PmoveSingle for
free camera in svDemo mode, sends origin via trap for PVS
- cg_snapshot.c: detect follow→free camera transition, init camera
from last known position
- cg_main.c: detect svDemo mode from CS_SVDEMO configstring,
lazy-init camera from first snapshot's spectator spawn
- g_main.c: G_InitGame sets CS_SVDEMO configstring, G_RunFrame
copies cmd.origin to ps.origin for PVS instead of ClientThink_real
- bg_public.h: CS_SVDEMO configstring index (26)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>