Kraty

Lobbies

Small, ad-hoc leaderboards, auto-matched by Kraty or pushed in from your own matchmaker, with progressive bot fill so they never look empty.

A lobby is a leaderboard for a subset of players. Reach for lobbies when the global leaderboard is too noisy, or when you want short-form, high-frequency competition.

Two ways to get one:

  • Auto-matched: set up matchmaking parameters on the event, and Kraty handles the queue.
  • External push: your own matchmaker (Steam, GameLift, Photon) picks the roster and tells Kraty.

Auto-matched lobbies

Kraty handles the queue. On the event, set:

FieldWhat it does
capacityHow many players make a "full" lobby.
fillTimeoutSecondsHow long to wait before starting underfilled.
fillBotsPad empty slots with bots when the timeout hits, or leave them open.

fillBy is the deadline computed from fillTimeoutSeconds: the absolute timestamp the SDK surfaces on the lobby once it starts forming.

When a player calls events.start, the SDK gets back either an attempt (the lobby was active) or a 202 with a lobbyId (the lobby is still forming, so poll lobbies.read(lobbyId) (or use pollLobbyUntilActive) until it is active, then call events.start again).

External lobbies

If your own matchmaker is the source of truth, POST the lobby up after match-make. Kraty creates the leaderboard, fills bots per the event config, and runs the rest:

POST /server/v1/games/{gameId}/events/{eventKey}/lobbies
Authorization: Bearer <server_integration api key>
Content-Type: application/json

{
  "key": "match-abc123",
  "externalPlayerIds": ["player_alice", "player_bob"],
  "fillBots": true
}

The key field is your studio's own idempotency token: POSTing twice with the same key returns the existing lobby.

See the Recipes → Push a lobby from your own matchmaker for the SDK wrapper of this endpoint.

Lifecycle

Lobbies move through forming → active → closed. The transitions fire webhooks (lobby.created, lobby.started, lobby.closed) so your game backend can spin up servers, set up chat channels, or record results when the time comes.

Progressive bot fill

When fillBots: true and the lobby is not filling with real players, Kraty drips bots in over time instead of waiting the full fillTimeoutSeconds and dropping them in all at once. Your "lobby waiting" UI gets a natural "filling up" animation rather than a 30-second wait followed by a flood.

You read it from the SDK like this:

final lobby = await kraty.lobbies.read(lobbyId);
print('${lobby.participantCount} humans + ${lobby.botSlots} bots'
      ' / ${lobby.capacity}');
print('filled (clamped): ${lobby.filledSlots}');
  • participantCount: real humans in the lobby.
  • botSlots: bots ready to join. This grows over time as more bots become available; poll or open an SSE stream to redraw the slot UI as it changes.
  • filledSlots: participantCount + botSlots, clamped to capacity so a brief clock skew cannot show "5/4".

Default drip cadence is one bot every 5 seconds. For a 4-cap lobby:

Time since the lobby formedbotSlots you will see
0–5s0
5–10s1
10–15s2
15–20s3
past fillBythe rest, all at once

The lobby starts (status: 'active') as soon as humans + bots reach capacity, either organically from the drip + new humans joining, or via the fillBy backstop.

In the Flutter sample app's Lobby view, filled slots render as green person icons (humans) followed by purple android icons (bots), with empty slots greyed out; the purple bots appear over time as the drip progresses.