diff --git a/src/components/game/IdleWorkerButton.tsx b/src/components/game/IdleWorkerButton.tsx index d085e029..0b229c39 100644 --- a/src/components/game/IdleWorkerButton.tsx +++ b/src/components/game/IdleWorkerButton.tsx @@ -18,8 +18,11 @@ export function IdleWorkerButton() { // Update idle worker count via event-driven approach + throttled polling // Note: Hooks must be called unconditionally, so spectator check is after all hooks useEffect(() => { - // Skip for spectators - if (isSpectator) return; + // Skip for spectators and reset count + if (isSpectator) { + setIdleWorkerCount(0); + return; + } const bridge = getWorkerBridge(); if (!bridge) return; diff --git a/src/components/game/WebGPUGameCanvas.tsx b/src/components/game/WebGPUGameCanvas.tsx index 04040c58..538f8374 100644 --- a/src/components/game/WebGPUGameCanvas.tsx +++ b/src/components/game/WebGPUGameCanvas.tsx @@ -232,6 +232,8 @@ export function WebGPUGameCanvas() { const handleLoadingComplete = useCallback(() => { setIsLoading(false); useGameStore.getState().setGameReady(true); + // Sync playerId with game setup (handles spectator mode where localPlayerId is null) + useGameStore.getState().syncWithGameSetup(); setTimeout(() => { const eventBus = workerBridgeRef.current?.eventBus; diff --git a/src/store/gameStore.ts b/src/store/gameStore.ts index 9fac69fd..96a5120d 100644 --- a/src/store/gameStore.ts +++ b/src/store/gameStore.ts @@ -447,9 +447,9 @@ export const useGameStore = create((set, get) => ({ syncWithGameSetup: () => { const localPlayerId = getLocalPlayerId(); - if (localPlayerId) { - set({ playerId: localPlayerId }); - } + // Set playerId to local player, or empty string if spectating + // This ensures we don't keep showing player1's data when spectating + set({ playerId: localPlayerId ?? '' }); }, reset: () => set(initialState),