BGS Docs

Bot players

BGS has two different "AI" mechanisms that are easy to confuse:

Bot slots

A game supports bot slots when its engine exports moveAI. The game-server auto-detects this when an engine version is installed — it probes the entry point for a moveAI export and records the result as meta.bots on the game info. The creation UI then offers bot seats for that game (no bot seats for engines without moveAI). Because bots are only for testing, the bot-seat picker is a developer-only control: it's hidden unless the user has developer settings enabled on their device (the web app ANDs meta.bots with its developer-settings flag before showing it).

A bot slot is a player entry flagged isBot: true, with a placeholder id and a generated name ("Rob (bot 1)", "Ada (bot 2)", …). There is no user account behind it, so bots:

At least one seat must be human: the creator can't fill every seat with bots without joining the game themselves.

How bot moves are driven

After every move (and at game start), the game-server checks whether a bot is among the current players. If so, a detached driver loop runs — it never blocks the request that triggered it:

  1. wait ~1.5 seconds, so a human watching sees turns happen one at a time (and live updates arrive in order);
  2. re-read the game under the game lock and find the first current player flagged isBot;
  3. call moveAI(gameData, botIndex) — in the engine worker thread, like regular moves;
  4. run the result through the normal after-move flow (log, scores, clocks, notifications);
  5. repeat until no bot is current anymore (a bot move can leave the same or another bot to play).

One driver runs per game at a time, capped at 50 bot moves per run. If the engine has no moveAI, throws, or returns unusable data, the driver stops and leaves the game as-is — the bot is simply stuck and can be dropped like any player whose time ran out; the game is never wedged.

Bots don't get a free pass on the clock: a bot seat has a remainingTime like everyone else, but the inactivity sweep skips bots (a bot whose clock expired is a bug, not inactivity — it's left for an admin).

Engine requirements

To host bot players, your engine must:

Dropped players vs bot slots

When a human quits or is dropped on timeout, dropPlayer(data, player) is called on the engine and the player is flagged dropped on the platform side. What happens to their in-game persona is entirely up to your engine — most games convert them to an internal AI so the remaining players can finish. That AI is not a platform bot: the seat still belongs to the (dropped) user, no moveAI calls are scheduled for it, and its "moves" happen inside the engine as part of other players' move calls.

Design dropPlayer to be safe at any point of the game — it runs exactly when someone vanished mid-turn. See clocks & timing for when drops happen.