Shared hooks
These hooks work inside any BetaGamerProvider regardless of game type. Import from @beta-gamer/react or @beta-gamer/react-native.
useGameState()
Returns live game state, updated automatically as socket events arrive.
| Field | Type | Description |
|---|---|---|
status | "waiting" | "playing" | "ended" | Current game lifecycle state |
players | Player[] | Both players โ id, displayName, color |
currentTurn | string | playerId of whoever moves next |
winner | string | null | undefined | Set when status is "ended". null = draw |
reason | string | undefined | End reason, e.g. "checkmate", "afk_timeout" |
import { useGameState } from '@beta-gamer/react';
function StatusBar() {
const { status, currentTurn, winner, reason } = useGameState();
if (status === 'ended') {
return <p>{winner ? `${winner} wins by ${reason}` : `Draw โ ${reason}`}</p>;
}
return <p>{status === 'waiting' ? 'Finding opponentโฆ' : `${currentTurn}'s turn`}</p>;
}useSession()
Returns the decoded session metadata from the JWT token. This is the authoritative source of the current player's identity โ always use players[0].id for winner comparison, never a display name.
| Field | Type | Description |
|---|---|---|
sessionId | string | Unique session identifier |
game | "chess" | "checkers" | "connect4" | โฆ | Game type |
matchType | "matchmaking" | "bot" | "private" | How the match was created |
players | Player[] | Players encoded in the token. See Player type below. |
theme | ThemeTokens | Theme values from your dashboard |
Player type
| Field | Type | Description |
|---|---|---|
id | string | Your tenant's user ID โ set when creating the session. This is what game:over.winner contains. Use this for all winner/loser comparisons. |
displayName | string | The name shown in the game UI. Tenant-controlled and separate from id โ a user can change their display name without affecting winner identification. |
import { useSession } from '@beta-gamer/react';
import { useGameState } from '@beta-gamer/react';
function ResultScreen() {
const { players } = useSession();
const { winner, reason } = useGameState();
const myId = players[0].id; // tenant userId โ compare against winner
const myName = players[0].displayName; // shown in UI only
if (!winner) return <p>Draw โ {reason}</p>;
return (
<p>
{winner === myId
? `๐ You won, ${myName}!`
: `๐ You lost โ ${reason}`}
</p>
);
}useSocket()
Returns the raw Socket instance. Use this when you need to emit custom events or listen to events not covered by the built-in components. The socket is null until the connection is established โ always guard with if (!socket) return.
import { useEffect } from 'react';
import { useSocket } from '@beta-gamer/react';
function CustomListener() {
const socket = useSocket();
useEffect(() => {
if (!socket) return;
socket.on('chess:afk_warning', ({ playerId, secondsRemaining }) => {
// show a countdown banner
});
return () => { socket.off('chess:afk_warning'); };
}, [socket]);
return null;
}useTheme()
Returns the active theme token object. Values come from your dashboard and are embedded in the session token. See Theming for the full token list.
import { useTheme } from '@beta-gamer/react';
function CustomBoard() {
const { boardLight, boardDark, primaryColor } = useTheme();
return (
<div style={{ '--board-light': boardLight, '--board-dark': boardDark } as React.CSSProperties}>
{/* board cells */}
</div>
);
}