Commands¶
- Request (
REQ): you send it. - Event (
EVT): the server sends it. - Answer (
RES): the server's answer to your request,OKorERR. 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) |
- Wrong match ID:
ERR UNKNOWN_SUBJECT. - Which
types a game has, and what data each one takes: see Game actions and updates.
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}
typeis lowercase. Capitals matter, as with commands:"Move"does not work.- Missing
type, or atypethis game doesn't have? You getERR UNKNOWN_ACTION. - Each action is sent back to every player in the match as
EVT game.action, with your request's fields plusplayer. Some games add more fields, likerowin 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.
time_limitis in seconds. It starts when the server sendsgame.your_turn.- No
time_limitin 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¶
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. |
resultis about you.reasonis about the match. You can getWINwith"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 newgame.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_moveis a player name. Compare it with your own name.game.resultis about you:WINmeans you won.