fix(games): stop spectator broadcast from overwriting player state
Some checks failed
Deploy to Production / test (push) Failing after 36s

Players subscribe to the room pub/sub channel and also receive direct
GAME_STATE messages. The GAME_STARTED and GAME_UPDATE broadcasts carry
the spectator view (no myColor/legalMoves), and were blindly overwriting
gameState — making isPlayerView() return false and disabling all
interaction. Now these broadcast handlers only update gameState for
spectators; players rely exclusively on the direct GAME_STATE message.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
syntaxbullet
2026-04-05 17:30:45 +02:00
parent 0d8152914a
commit 4f89ed3082

View File

@@ -60,6 +60,7 @@ export function useGameRoom(roomId: string, userId: string, role?: string, prefe
break;
case "GAME_STATE":
// Authoritative player view — sent directly to this player
setState(prev => ({
...prev,
gameState: msg.state,
@@ -68,11 +69,18 @@ export function useGameRoom(roomId: string, userId: string, role?: string, prefe
break;
case "GAME_STARTED":
setState(prev => ({ ...prev, gameState: msg.state, roomStatus: "playing" }));
// Broadcast with spectator view — only use for state if we're a spectator
// (players get their own GAME_STATE via direct send)
setState(prev => ({
...prev,
gameState: prev.isSpectator ? msg.state : prev.gameState,
roomStatus: "playing",
}));
break;
case "GAME_UPDATE":
setState(prev => ({ ...prev, gameState: msg.state }));
// Broadcast with spectator view — only update state for spectators
setState(prev => prev.isSpectator ? { ...prev, gameState: msg.state } : prev);
break;
case "PLAYER_JOINED":