🎮 Beta Gamer

Connect 4 — Spectate

Any active PvP (non-bot) Connect 4 game can be watched in real time. Use the spectate lobby or connect directly via socket.

List live games

const res = await fetch('https://api.beta-gamer.com/v1/rooms?game=connect4');
const { rooms } = await res.json();

// rooms: [{ roomId, players: [{ id, username }], moveCount }]

Connect as spectator

import { io } from 'socket.io-client';

const socket = io('https://api.beta-gamer.com/connect4', {
  path: '/socket.io',
  transports: ['websocket', 'polling'],
});

socket.on('connect', () => {
  socket.emit('game:spectate', { roomId: 'room_abc123', username: 'Spectator' });
});

socket.on('game:spectate:joined', ({ players, board, currentTurn, moveHistory }) => {
  // render board — board is a flat (string|null)[] of length rows×cols
});

socket.on('game:move:made', ({ board, currentTurn, lastMove }) => {
  // update board
});

socket.on('game:over', ({ winner, reason, winningCells }) => {
  // game ended
});

Using the React SDK to spectate

No session token needed for spectating. Connect the raw socket directly — the Connect4Board component requires a BetaGamerProvider token, so for spectating you manage board state via the raw socket and render your own read-only board.

import { useEffect, useState } from 'react';
import { io } from 'socket.io-client';

export default function SpectateRoom({ roomId }: { roomId: string }) {
  const [board, setBoard] = useState<(string | null)[]>(Array(42).fill(null));
  const [players, setPlayers] = useState<any[]>([]);
  const [currentTurn, setCurrentTurn] = useState(0);

  useEffect(() => {
    const socket = io(window.location.origin + '/connect4', {
      path: '/api/socket/io',
      transports: ['websocket', 'polling'],
    });

    socket.on('connect', () => {
      socket.emit('game:spectate', { roomId, username: 'Spectator' });
    });

    socket.on('game:spectate:joined', ({ players: p, board: b, currentTurn: t }) => {
      setPlayers(p);
      setBoard(b);
      setCurrentTurn(t);
    });

    socket.on('game:move:made', ({ board: b, currentTurn: t }) => {
      setBoard(b);
      setCurrentTurn(t);
    });

    socket.on('game:over', ({ winner, reason, winningCells }) => {
      console.log('Game ended:', reason, winner);
    });

    return () => { socket.disconnect(); };
  }, [roomId]);

  // Render a read-only board — no column click handlers
  return null;
}

Event reference

EventDirectionPayload
game:spectate→ server{ roomId, username }
game:spectate:joined← server{ roomId, players, board, currentTurn, moveHistory }
game:move:made← server{ column, position, board, currentTurn, lastMove }
game:over← server{ winner?, reason, winningCells? }
💡 Only PvP games (no bots) are listed. Bot games are excluded from the spectate lobby.
Beta Gamer GaaS API — questions? support@beta-gamer.com