Smooth unpause: reset client time delta and entity interpolation

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>
This commit is contained in:
serge_shubin 2026-03-24 03:59:44 +08:00
parent 6e13c747ba
commit 490fcd9bde
2 changed files with 29 additions and 9 deletions

View file

@ -288,6 +288,9 @@ void CL_ParseSnapshot( msg_t *msg ) {
cl.snapshots[oldMessageNum & PACKET_MASK].valid = qfalse;
}
{
int oldSnapFlags = cl.snap.snapFlags;
// copy to the current good spot
cl.snap = newSnap;
cl.snap.ping = 999;
@ -299,6 +302,15 @@ void CL_ParseSnapshot( msg_t *msg ) {
break;
}
}
// if server count changed (map_restart or demo unpause), force-reset
// the time delta so the client doesn't slowly drift back to sync
if ( ( oldSnapFlags ^ newSnap.snapFlags ) & SNAPFLAG_SERVERCOUNT ) {
cl.serverTimeDelta = cl.snap.serverTime - cls.realtime;
cl.oldServerTime = cl.snap.serverTime;
cl.serverTime = cl.snap.serverTime;
}
}
// save the frame off in the backup array for later delta comparisons
cl.snapshots[cl.snap.messageNum & PACKET_MASK] = cl.snap;

View file

@ -994,6 +994,14 @@ void SVD_Pause_f( void ) {
return;
}
demo.paused = !demo.paused;
if ( !demo.paused ) {
// resuming — reset entities so client doesn't interpolate
// from frozen positions to post-pause positions.
// also toggle SERVERCOUNT to reset client snapshot timing
// (drifted during pause from identical serverTimes).
svs.snapFlagServerBit |= SNAPFLAG_RESET_ENTITIES;
svs.snapFlagServerBit ^= SNAPFLAG_SERVERCOUNT;
}
Com_Printf( "Demo playback %s.\n", demo.paused ? "paused" : "resumed" );
}