# terminal-chess Network Protocol

The network protocol for terminal-chess is designed in an interoperable manner,
allowing for playing chess with other clients that implement the same protocol.

This document describes the protocol in detail, including the message formats
and the expected behavior of clients and the server.

The current protocol version is 24.

## Message Format

The terminal-chess network protocol has two different message types:

* a code consisting of a single byte
* a message composed of a single byte indicating the type plus a payload

An example implementation covering both types is the following struct:

```C
struct message {
    unsigned char code;
    unsigned char message[]; // flexible array member
}
```

A table with all message codes can be found [below](#message-code-table).

The datatypes used in the message payloads are as follows:

* BYTE — a single byte
* WORD — two bytes integer (big-endian)
* DWORD — four bytes integer (big-endian)
* MOVE — a data structure describing a move, consisting of
  * a DWORD for the elapsed move time in seconds
  * a DWORD for additional elapsed move time in microseconds
  * a BYTE describing the moved piece (see below)
  * a BYTE index for the file the piece was moved from
  * a BYTE index for the row the piece was moved from
  * a BYTE index for the file the piece was moved to
  * a BYTE index for the row the piece was moved to
  * a BYTE describing the selected piece for promotion (otherwise zero)

The following table shows the possible values for the BYTEs describing a piece.

| Piece        | Value (Hex) |
|--------------|-------------|
| White Pawn   | 0x11        |
| White Rook   | 0x12        |
| White Knight | 0x13        |
| White Bishop | 0x14        |
| White Queen  | 0x15        |
| White King   | 0x16        |
| Black Pawn   | 0x21        |
| Black Rook   | 0x22        |
| Black Knight | 0x23        |
| Black Bishop | 0x24        |
| Black Queen  | 0x25        |
| Black King   | 0x26        |

## Handshake

Immediately after a connection between a server and a client is established,
the server SHALL send one single byte denoting the protocol version to the
client.
The client SHALL then immediately answer with their protocol version.
After both parties have sent their version to the other party, they SHALL both
compare their own version with the received version.
When the versions do not match, both parties SHALL terminate the connection.
The users SHOULD be informed about the protocol mismatch.

## Game Setup

After a successful handshake, the server SHALL send the client information about
the game they want to play. The server can set up a completely new game or
continue an unfinished game.

### Starting a New Game

When the server wants to start a new game, they SHALL send a `NETCODE_GAMEINFO`
message. The payload of this message is as follows:
* one BYTE denoting the color the server wants to play
  (16 or 0x10 = white, 32 or 0x20 = black)
* one BYTE indicating if the game is played with time control (1 = yes, 0 = no)
* one WORD for the initial clock time in seconds
* one WORD for the number of seconds that are added per move
* one WORD for the delay in seconds for each move

When the game is played without time control, the last three WORDs MAY be
left uninitialized, but they SHALL be sent anyway.

### Continuing a Game

When the server wants to continue a game, they SHALL send a `NETCODE_PGNDATA`
message. The payload of this message is as follows:
* the same two BYTES and three WORDS as in `NETCODE_GAMEINFO`, followed by
* 

### Clock Setup

For clock synchronization, the following rules SHALL be applied:

* the clock of each player starts after their first move
* the _increment_ is added _after_ a move, except…
* … when the initial clock is zero, then the clock starts with the increment
* when the used time for a move is less than the delay, the move costs no time
* the delay is always subtracted from the actual move time

## Message Code Table

The following table shows the definitions of the network codes.

| Code Name            | Byte | With Payload |
|----------------------|------|--------------|
| NETCODE_ACCEPT       | 0x02 | no           |
| NETCODE_DECLINE      | 0x04 | no           |
| NETCODE_DECLINE_MOVE | 0x05 | yes          |
| NETCODE_GAMEINFO     | 0x10 | yes          |
| NETCODE_PGNDATA      | 0x11 | yes          |
| NETCODE_MOVE         | 0x20 | yes          |
| NETCODE_CHECK        | 0x22 | no           |
| NETCODE_CHECKMATE    | 0x23 | no           |
| NETCODE_STALEMATE    | 0x28 | no           |
| NETCODE_NOMATERIAL   | 0x29 | no           |
| NETCODE_THREEFOLD    | 0x30 | no           |
| NETCODE_RESIGN       | 0x41 | no           |
| NETCODE_REMIS        | 0x42 | no           |
| NETCODE_TAUNT        | 0x43 | no           |
| NETCODE_TIMEOVER     | 0x44 | no           |

The following codes are reserved for implementation.
They are not used during transmissions and can be used as return values
for functions to indicate errors.

| Code Name            | Byte |
|----------------------|------|
| NETCODE_AGAIN        | 0x70 | 
| NETCODE_CONNLOST     | 0x80 |
| NETCODE_ERROR        | 0xFF |


