Chess — Spectate
Any active PvP (non-bot) chess game can be watched in real time. Use the spectate lobby to browse live games, or connect directly via socket.
List live games
const res = await fetch('https://api.beta-gamer.com/v1/rooms?game=chess');
const { rooms } = await res.json();
// rooms: Array of active PvP games
// [
// {
// roomId: "room_abc123",
// players: [{ id: "p1", username: "Alice" }, { id: "p2", username: "Bob" }],
// moveCount: 14
// },
// …
// ]Connect as spectator
Connect directly to the /chess namespace — no session token required for spectating.
import { io } from 'socket.io-client';
const socket = io('https://api.beta-gamer.com/chess', {
path: '/socket.io',
transports: ['websocket', 'polling'],
});
socket.on('connect', () => {
socket.emit('game:spectate', { roomId: 'room_abc123', username: 'Spectator' });
});
// Receive the current game state immediately
socket.on('game:spectate:joined', ({ roomId, players, fen, currentTurn, moveHistory }) => {
// render the board at fen
// moveHistory: [{ move: { from, to, san }, playerId, timestamp }]
});
// Live updates — same events as a normal game
socket.on('game:move:made', ({ move, fen, currentTurn, moveHistory }) => {
// update board
});
socket.on('game:over', ({ winner, reason, pgn }) => {
// game ended — show result
});Using the React SDK to spectate
You don't need a session token to spectate — connect the raw socket directly and use game:spectate:joined to get the initial board state. The ChessBoard component requires a BetaGamerProvider with a token, so for spectating you manage board state manually via useSocket() and render your own board, or use the raw socket approach below.
import { useEffect, useRef, useState } from 'react';
import { io } from 'socket.io-client';
export default function SpectateRoom({ roomId }: { roomId: string }) {
const [fen, setFen] = useState('');
const [players, setPlayers] = useState<any[]>([]);
const [moveHistory, setMoveHistory] = useState<any[]>([]);
const socketRef = useRef<any>(null);
useEffect(() => {
const socket = io(window.location.origin + '/chess', {
path: '/api/socket/io',
transports: ['websocket', 'polling'],
});
socketRef.current = socket;
socket.on('connect', () => {
socket.emit('game:spectate', { roomId, username: 'Spectator' });
});
socket.on('game:spectate:joined', ({ players: p, fen: f, moveHistory: h }) => {
setPlayers(p);
setFen(f);
setMoveHistory(h);
});
socket.on('game:move:made', ({ fen: f, moveHistory: h }) => {
setFen(f);
setMoveHistory(h);
});
socket.on('game:over', ({ winner, reason }) => {
console.log('Game ended:', reason, winner);
});
return () => { socket.disconnect(); };
}, [roomId]);
// Render your own read-only board using fen, players, moveHistory
return null;
}Event reference
| Event | Direction | Payload |
|---|---|---|
game:spectate | → server | { roomId, username } |
game:spectate:joined | ← server | { roomId, players, fen, currentTurn, moveHistory } |
game:move:made | ← server | { move: { from, to, san, piece }, fen, currentTurn, moveHistory } |
game:over | ← server | { winner?, reason, pgn } |
💡 Only PvP games (no bots) are listed. Bot games are excluded from the spectate lobby.
Beta Gamer GaaS API — questions? support@beta-gamer.com