Fight Arena
Real-time, 1v1 up to 3v3. Architecturally different from every other game documented here — no discrete moves, no turn order. The server runs a fixed-rate simulation; you stream continuous input and receive continuous state.
game:move exists here — it doesn't. This game speaks game:input and realtime:snapshot instead, shared with any future real-time game on this platform, not Fight Arena specific event names.Session creation
{ "game": "fight-arena", "matchType": "matchmaking", "players": [{ "id": "user_1" }] }Team size (1–3 per side, 2 teams) comes from matchConfig at the platform level, not a fight-arena-specific field — see the Sessions page.
Types
interface FightArenaInput {
moveX: number; // -1 to 1
moveY: number; // -1 to 1
firing: boolean;
}
interface FightArenaConfig {
bounds: { width: number; height: number }; // 800×450, fixed
friendlyFire: boolean; // off by default
}The input/snapshot loop
Send input continuously — every frame, or on every meaningful change. The server ticks at a fixed rate and broadcasts a full state snapshot each tick.
// Client → server, as often as your input actually changes
socket.emit('game:input', {
roomId,
input: { moveX: 0.8, moveY: 0, firing: true },
});
// Server → client, every tick
socket.on('realtime:snapshot', (state) => {
// full simulation state — positions, health, everything
renderFrame(state);
});Socket events
| Event | Direction | Payload |
|---|---|---|
fight:start | client → server | none — signals readiness once connected |
fight:started | server → client | { roomId, waiting: boolean } |
game:input | client → server | { roomId, input: FightArenaInput } |
realtime:snapshot | server → client | Full state snapshot — sent every server tick, not on demand |
game:state | server → client | Sent on discrete state changes, distinct from the per-tick snapshot above |
player:hit | server → client | { byId, targetId, damage, targetHealthAfter } |
player:disconnected | server → client | { socketId } |
player:reconnected | server → client | { playerId } |
game:reconnect | client → server | { playerId } |
game:reconnected | server → client | Full current simulation state, to rehydrate after reconnecting |
game:over | server → client | Result object, same shape as the game.ended webhook |
No AFK timeout
Real-time rooms don't run the turn-based AFK system — there's no "turn" to time out. A disconnected player is handled purely through player:disconnected / reconnection, not a forfeit timer.
Hosted matchmaking
Supports hosted matchmaking via both direct socket events and the REST endpoints. One addition specific to Fight Arena's variable team size:
socket.emit('hosted:rebalance_pool');
socket.on('hosted:pool_rebalanced', ({ groups }) => { /* ... */ });Rebalances currently-staged players into valid team groups on demand — useful when players are trickling into a lobby and team sizes aren't fixed in advance.