From 0b4eb7b69f45d480b921437a03886273ed1ae28a Mon Sep 17 00:00:00 2001 From: serge_shubin Date: Mon, 23 Mar 2026 23:46:46 +0800 Subject: [PATCH] Start demo playback only when spectator enters game Move pause check from SV_Frame (which blocked connection handshake) into SVD_PlaybackFrame. The server runs frames normally so clients can connect and load, but demo data isn't consumed until a client reaches CS_ACTIVE. The spectator sees the demo from the very first frame without missing any gameplay. Co-Authored-By: Claude Opus 4.6 (1M context) --- code/server/sv_main.c | 6 ------ code/server/sv_netdemo.c | 11 +++++++++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/code/server/sv_main.c b/code/server/sv_main.c index 7dc0274..da5e89a 100644 --- a/code/server/sv_main.c +++ b/code/server/sv_main.c @@ -828,12 +828,6 @@ void SV_Frame( int msec ) { if (com_dedicated->integer) SV_BotFrame( svs.time ); - // demo playback: pause if no spectators are watching - if ( SVD_IsPlaying() && SVD_ShouldPause() ) { - sv.timeResidual = 0; - return; - } - // run the game simulation in chunks while ( sv.timeResidual >= frameMsec ) { sv.timeResidual -= frameMsec; diff --git a/code/server/sv_netdemo.c b/code/server/sv_netdemo.c index ba6c411..090a74b 100644 --- a/code/server/sv_netdemo.c +++ b/code/server/sv_netdemo.c @@ -1007,6 +1007,13 @@ qboolean SVD_PlaybackFrame( void ) { return qfalse; } + // wait for a spectator to be fully in-game before starting playback. + // the server keeps running frames (so the connection handshake completes) + // but no demo data is consumed until someone is CS_ACTIVE. + if ( SVD_ShouldPause() ) { + return qfalse; + } + // apply recorded configstrings once after map load if ( demo.needConfigstrings ) { SVD_ApplyConfigstrings(); @@ -1047,8 +1054,8 @@ qboolean SVD_ShouldPause( void ) { } for ( i = 0; i < sv_maxclients->integer; i++ ) { - if ( svs.clients[i].state >= CS_CONNECTED ) { - return qfalse; // someone is connected or connecting + if ( svs.clients[i].state == CS_ACTIVE ) { + return qfalse; // someone is in-game and watching } }