Library
24/7 sessions and reconnection
BonkSession keeps rooms alive with a single account, recreating any that go down.
To run one or several rooms unattended, use BonkSession. It shares authentication (a single login call), applies a throttle between creations and recreates rooms that go down.
ts
import { BonkSession } from 'bonktools';
const session = new BonkSession({
auth: { type: 'registered', username: '...', password: '...' },
throttle: {
capacity: 3, // maximum burst of creations
refillPerSec: 0.5, // 1 slot refilled every 2 s
},
});
await session.getToken(); // authenticates once; the token is reused
session.on('room-added', (localId) => {
const { room } = session.rooms.get(localId)!;
console.log('room active:', room.shareLink);
});
session.on('room-dead-terminal', ({ localId, reason }) => {
console.error('room lost for good:', localId, reason);
});Declarative mode: startFromConfig()
Creates every room in a list, with a delay (and some randomness) between creations. The configurations are registered in the 60 s reconcile, a safety net that recreates rooms that went down silently.
ts
await session.startFromConfig({
rooms: [
{ id: 'sala-1', name: 'Room One', maxPlayers: 6, mode: 'b', rounds: 3 },
{ id: 'sala-2', name: 'Room Two', maxPlayers: 8, mode: 'ar', rounds: 5 },
],
throttle: {
maxConcurrentRooms: 10,
roomCreationDelayMs: 3000, // minimum wait between creations
roomCreationJitterMs: 2000, // + random up to 2 s
},
});Imperative mode
ts
const localId = await session.addRoom({ id: 'sala-3', name: 'HERMES', maxPlayers: 4, mode: 'sp', rounds: 3 });
const { room, status } = session.rooms.get(localId)!;
room.chat('Hello!');
await session.removeRoom(localId);
await session.destroy(); // ends the whole session (idempotent)RoomConfig
| Field | Default | Description |
|---|---|---|
id | — | Unique identifier (used by the reconcile) |
name | — | Room name |
password | '' | Password |
maxPlayers | 6 | Players |
mode | 'b' | Game mode |
rounds | 3 | Rounds |
hidden | false | Hides it from the public list |
map | — | LZ-String blob of the map |
Status of a room in the pool
| Status | Meaning |
|---|---|
starting | createRoom() hasn't resolved yet |
active | Room created and alive |
dead-transient | Went down; will be recreated with throttling |
dead-terminal | Lost for good (ban, full room, retries exhausted) |
Automatic reconnection
BonkRoom reconnects on its own after transient failures (socket dropped, server restarted), with exponential backoff and jitter:
ts
const room = await createRoom({
auth,
desiredState: { /* ... */ },
reconnectPolicy: {
maxAttempts: 10, // default
initialDelayMs: 1000, // default: 1 s
maxDelayMs: 30_000, // default: 30 s
multiplier: 1.5, // default
jitter: true, // recommended
},
});| Cause | Type | What happens |
|---|---|---|
socket-disconnect | transient | Reconnects with backoff |
status-banned | terminal | No retry |
status-room_full | terminal (only when trying to join) | No retry |
max-retries-exceeded | terminal | No retry |
On reconnect, the room-rebuilt event carries the new room link, and settings such as the team lock are reapplied.