Commit graph

8 commits

Author SHA1 Message Date
7141d941a3 Demo pause: freeze svs.time, hold demo data consumption
svdemo_pause toggles playback pause. When paused:
- svs.time frozen so entity trajectories freeze correctly
- No demo frames consumed (SVD_PlaybackFrame returns early)
- Game frame still runs at frozen time for spectator movement
- No time jump on unpause — svs.time resumes from where it was

Spectator movement degrades during pause (200ms PmoveSingle cap)
— will be resolved by client-owned camera in a future change.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 03:28:32 +08:00
0b4eb7b69f 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) <noreply@anthropic.com>
2026-03-23 23:46:46 +08:00
300e7c431a Pause demo playback when no spectators are watching
svdemo_pauseEmpty (default: 1) pauses frame processing when no
client is CS_ACTIVE during demo playback. Prevents the demo from
advancing with nobody watching. Time residual is cleared so the
demo resumes from where it paused when a spectator connects.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 06:25:16 +08:00
90b26dc2a1 Capture per-client chat commands for demo recording
Chat messages use per-client trap_SendServerCommand (not broadcast),
so they weren't captured. Move capture hook to SV_GameSendServerCommand
which is the game module boundary. Capture broadcasts (clientNum=-1)
and chat/tchat commands sent to client 0 (first in the per-client
loop, deduplicated by only capturing once).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 05:53:53 +08:00
4f0d46024b Record and replay broadcast server commands (chat, prints)
Capture broadcast server commands (chat, print, cp, etc.) from
SV_SendServerCommand when cl==NULL. Buffer up to 64 commands per
frame. Written after configstrings in the demo file, replayed to
the spectator client during playback.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 05:41:18 +08:00
a1167ff398 Fix 8 netdemo bugs found in code review
1. File handle leak: SVD_Play_f opened file twice, first handle leaked.
   Fix: memset demo state before opening.

2. svdemo_stop now handles both recording and playback via SVD_Stop_f.
   Playback stop disconnects client to return to menu.

3. Zombie client timeout: skip SV_CheckTimeouts during playback so
   reserved player slots aren't freed.

4. Buffer overflow: increase entity buffer to MAX_GENTITIES*300 and
   playerState buffer to MAX_CLIENTS*600 for worst-case first frame.
   Made static to avoid stack overflow.

5. svs.time jump: don't overwrite svs.time with recorded time.
   Server time advances normally, avoiding timeout/heartbeat issues.

6. map_restart: SVD_ResetDeltaState clears entity/player delta state
   so next frame writes full states, preventing corrupt deltas.

7. Demo end and manual stop both disconnect the client.

8. SV_Shutdown cleans up active recording/playback.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 05:03:33 +08:00
a8044aad8b Server-side demo recording and playback (netdemo)
Records full entity state array each server frame, enabling
free-camera demo playback from any viewpoint.

Recording:
- svdemo_record <name> / svdemo_stop
- Captures entityState_t + PVS fields (svFlags, linked,
  currentOrigin, absmin, absmax) for all active entities
- Records configstring changes per frame
- File format: svdemos/<name>.svdm

Playback:
- svdemo_play <name>
- Loads map with maxclients=64, reserves recorded player slots
  (CS_ZOMBIE with safe rate/timing) so spectator gets a high slot
- Injects recorded entities into sv.gentities each frame with
  SV_LinkEntity for PVS visibility
- Re-applies demo configstrings (CS_PLAYERS etc.) after map load,
  skipping CS_SERVERINFO/CS_SYSTEMINFO to avoid latch restarts
- Game module runs in demo mode (sv_demoplaying cvar): G_RunFrame
  only processes spectator movement, skips all entity logic
- Spectator forced to TEAM_SPECTATOR on connect (ClientBegin)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 04:28:55 +08:00
Sergei Shubin
4c57221941 Initial commit: Quake 3 1.32b GPL source 2026-03-18 13:32:24 +08:00