Skip to content

Commands

  • Request (REQ): you send it.
  • Event (EVT): the server sends it.
  • Answer (RES): the server's answer to your request, OK or ERR. See Errors for the error codes.
  • <id>, <m> and the other placeholders: see Placeholders.

session: you and your connection

Command Type Line Answer
session.hello REQ REQ <id> session.hello {"version": 1} OK, OK {"session_token": "<session_token>"} (account on WebSocket) or ERR FATAL VERSION_MISMATCH
session.login (guest) REQ REQ <id> session.login {"player": "<name>"} OK {"session_token": "<session_token>"} or ERR AUTH_FAILED
session.login (account, telnet) REQ REQ <id> session.login {"account_token": "<account_token>"} OK {"session_token": "<session_token>"} or ERR AUTH_FAILED
session.reconnect REQ REQ <id> session.reconnect {"session_token": "<session_token>"} OK + missed events, ERR SESSION_EXPIRED or ERR AUTH_FAILED
session.logout REQ REQ <id> session.logout OK + server disconnects, or ERR IN_MATCH
session.error EVT EVT session.error {"reason": "<reason>"} server disconnects

lobby: finding a match

Command Type Line Answer
lobby.subscribe REQ REQ <id> lobby.subscribe {"game": "<game>"} OK, ERR UNKNOWN_GAME or ERR LOBBY_FULL
lobby.ready REQ REQ <id> lobby.ready OK or ERR AUTH_FAILED
lobby.update EVT EVT lobby.update {"players": [...], "ready": [...], "min": 3, "max": 9} -
lobby.countdown EVT EVT lobby.countdown {"seconds": 10} -

Games: tic-tac-toe, battleship, connect4.

game: things you send

Command Line Answer
game.action REQ <id> <m> game.action {"type": "<type>", ...} OK, ERR UNKNOWN_ACTION, ERR NOT_YOUR_TURN, ERR INVALID_MOVE or ERR INVALID_PLACEMENT
game.forfeit REQ <id> <m> game.forfeit OK (you give up)

game: things the server sends

Event Who gets it Data
game.match_started all players opponent or participants, to_move, game info
game.your_turn the player whose turn it is time_limit, only when the match has a turn time limit
game.action all players (you too) type, player, the action's data, game info
game.update depends on the type type, game info
game.result each player result (WIN, LOSS or DRAW), reason
game.opponent_disconnected other players player, timeout
game.opponent_reconnected other players player
game.match_restarted each player still in the match -

Game actions and updates

Everything that only one game has goes through two commands. All other game.* commands work the same in every game.

  • game.action: you do something the game's rules decide, like a move.
  • game.update: the game tells you something, like "place your ships".

The data always has a type. The other fields depend on the type.

C: REQ <id> <m> game.action {"type": "move", "move": 4}
S: RES <id> OK
S: EVT <m> game.action {"type": "move", "player": "<name>", "move": 4}
  • type is lowercase. Capitals matter, as with commands: "Move" does not work.
  • Missing type, or a type this game doesn't have? You get ERR UNKNOWN_ACTION.
  • Each action is sent back to every player in the match as EVT game.action, with your request's fields plus player. Some games add more fields, like row in Connect-4.
  • An action with secret information is not sent to the other players. The game's page says which ones.

Each game lists its own types:

Game Actions Updates
Tic-Tac-Toe move -
Connect-4 move -
Battleship place_fleet, move place_ships, opponent_ready

Turn time limit

Some matches give you a time limit per turn. Tournament matches always have one.

S: EVT <m> game.your_turn {"time_limit": 30}
  • time_limit is in seconds. It starts when the server sends game.your_turn.
  • No time_limit in the data? Then this match has no limit.
  • Time runs out? You lose the match, with reason "timeout".
  • In a tournament the timer also runs while you are disconnected. See Reconnecting in a tournament.

Match results

S: EVT <m> game.result {"result": "WIN", "reason": "normal"}
reason Why the match ended
normal The game ended by its own rules.
forfeit A player sent game.forfeit.
timeout A player's turn time limit ran out.
disconnect A player did not come back in time.
aborted The server could not restart the match. Everyone still in gets DRAW.
  • result is about you. reason is about the match. You can get WIN with "reason": "timeout" when the other player ran out of time.

Match restarts

Each game runs in a separate program next to the server. If that program stops, the server plays your match again from the start.

S: EVT <m> game.match_restarted
S: EVT <m> game.match_started {"opponent": "<other>", "to_move": "<name>"}
S: EVT <m> game.your_turn
  • The match ID <m> stays the same.
  • The board is empty again. Forget the moves you tracked.
  • The players are the same, in the same order. A player who already left with a result does not come back.
  • A request the server was still handling when the program stopped gets ERR GAME_UNAVAILABLE. It did nothing. Send it again after the new game.match_started.
  • A match restarts a few times at most. After that, or when too few players are left, it ends with reason "aborted".
  • Away from the match? Your waiting time keeps running, and you still get these events when you come back.

Good to know

  • The server decides whose turn it is.
  • to_move is a player name. Compare it with your own name.
  • game.result is about you: WIN means you won.