--- a/src/mpgame/Game_network.cpp
+++ b/src/mpgame/Game_network.cpp
@@ -1067,6 +1067,7 @@
 void idGameLocal::RepeaterWriteSnapshot( int clientNum, int sequence, idBitMsg &msg, dword *clientInPVS, int numPVSClients, const userOrigin_t &pvs_origin, int lastSnapshotFrame ) {
 	int i;
 	idBounds bounds;
+	const bool fullStatePlayback = demoState == DEMO_PLAYING && serverDemo;
 
 	// if the client is spectating a valid player
 	if ( pvs_origin.followClient >= 0 && pvs_origin.followClient < MAX_CLIENTS && entities[ pvs_origin.followClient ] && entities[ pvs_origin.followClient ]->IsType( idPlayer::GetClassType() ) ) {
@@ -1084,10 +1085,11 @@
 		viewerUnreliableMessages[ clientNum ],
 		sequence,
 		msg,
-		viewers[ clientNum ].nopvs ? -1 : (pvs_origin.followClient >= 0 ? pvs_origin.followClient : ENTITYNUM_NONE ),
+		( viewers[ clientNum ].nopvs || fullStatePlayback ) ? -1 :
+			( pvs_origin.followClient >= 0 ? pvs_origin.followClient : ENTITYNUM_NONE ),
 		ENTITYNUM_NONE,
 		0,
-		viewers[ clientNum ].nopvs ? false : true,
+		!( viewers[ clientNum ].nopvs || fullStatePlayback ),
 		bounds,
 		lastSnapshotFrame
 	);
@@ -3293,7 +3295,8 @@
 			continue;
 		}
 
-		if ( clientNum != -1 && viewers[ icl ].origin.followClient != clientNum && !viewers[ icl ].nopvs ) {
+		if ( clientNum != -1 && viewers[ icl ].origin.followClient != clientNum &&
+			!viewers[ icl ].nopvs && !( demoState == DEMO_PLAYING && serverDemo ) ) {
 			// not global, not to the followed client
 
 			// not following anyone
@@ -3399,7 +3402,7 @@
 		}
 
 		// if no areas are given, this is a global emit; also always emit for repeaters
-		if ( numAreas && !viewers[ icl ].nopvs ) {
+		if ( numAreas && !viewers[ icl ].nopvs && !( demoState == DEMO_PLAYING && serverDemo ) ) {
 			// only send if pvs says this client can see it
 			for ( i = 0; i < numAreas; i++ ) {
 				if ( pvs.InCurrentPVS( pvsHandle[ i ], viewers[ icl ].pvsArea ) ) {
