OVERVIEW

A client opens a TCP connection to the server, and they remain connected for the duration of the game. Clients send requests to the server. The server sends messages to the players. All requests and messages are plain text, terminated by a newline. The requests are not RPCs. The client should never wait for a reply to a specific request. Instead, the client should always be ready to process any message that it receives from the server.

For example: A player uses a client's GUI to drag a card from his hand and drop it on his play area. The client should not change the list of cards in the player's hand or play area. Instead, the client should request that the server move the card from the player's hand to his play area. This will cause the server to send a message (to all players) which says to move the card. Each client should process this message when it gets it, regardlss of whether the client was the one that sent the request that caused the message.

REQUESTS

hello value:%d
Informs the server what version of this protocol the client is using.

set-player-name name:%s
Tells the server the client's player name.

set-player-value key:%s value:%d
Associates a (key, value) pair with the player.

join name:%s
Sit down at a virtual table on the server. If there is a game in progress, watch the game. If a game is forming, then the client can join the game by sending a set-deck request.

set-deck cards:{%s %s %s ...}
Sends the client's deck for the next game. Each string is the number of copies of the card, followed by a space, followed by the full card name in UTF8 format.  (This request has no effect on the current game, if a game is currently in progress).

set-sideboard cards:{%s %s %s ...}
See set-deck.

shuffle zone:%d
Requests that the server shuffle the client's given zone. After a shuffle, the zone contains the exact same cids in the exact same order, but each cid may represent a different one of the cards that were in the zone.

message text:%s pid:%d tag:%s
Sends the given message to the given player. If pid is zero, then it is a public message sent to all players. If a tag is specified, then the server sends the tag value along with the message.

move-card cid:%d pid:%d zone:%d x:%d y:%d loc:%d
See p2p protocol.

rearrange-zone cid:%d pid:%d zone:%d value:%d
See p2p protocol.

set-card-value cid:%d key:%s value:%d
See p2p protocol.

send-ping pid:%d
Requests that the server send a ping message to the given player. If pid is zero, then the server replies to the ping message.

return-ping pid:%d
Requests that the server tell the given player that a ping has been received.

show-zone zone:%d size:%d pid:%d
Requests that the server reveal the top size cards of the given zone to the given player. If size is zero, reveal the whole zone. If pid is zero, reveal to all players.

flip-coin
Requests that the server flip a coin for the client.

roll-die value:%d
Requests that the server roll a die with value sides.

show-random zone:%d
Requests that the server reveal a randomly selected card from the given zone to all players.

add-card name:%s zone:%d
Adds a new card (which is not in any player's deck) to the game. The card is placed at the end of the given zone.

request-new-game value:%d
If value is non-zero, tells the server that the player is ready to start a new game. When all players are ready to start a new game, the server empties all zones and sends a reset-game message to each player. Then it initializes the private zones.

MESSAGES

hello value:%d name:%s
Tells the client what version of this protocol the server is using. Also sends the server application version string, which is not the same thing as the protocol version.

set-player-name pid:%d name:%s
Tells the client the given player's name.

set-player-value pid:%d key:%s value:%d
Associates a (key, value) pair with the player.

join pid:%d
Response to a join request. Tells the client his player identifier at the table.

player-connect pid:%d value:%d
If value is zero, the player has disconnected. Otherwise, the player has (re) connected.

set-zone pid:%d zone:%d cids:(%d %d %d ...)
Resets the ordered list of pids in the given player's given zone. cids[0] is the "bottom" card, and cids[n] is the "top" card.

shuffle pid:%d zone:%d
Tells the client that the server has shuffled the given player's given zone.

message pid:%d text:%s tag:%s
Delivers a message from the given player. If the pid is zero, then the message is from the server itself. The client can use tag to differentiate between public conversations, private conversations, and game-state information.

reveal cid:%d name:%s
Tells the client what card is represented by a cid. The server is responsible for remembering which cids have been revealed to which players, and for revealing each cid *before* sending a message that the cid has been moved to a public zone.

move-card cid:%d pid:%d zone:%d x:%d y:%d loc:%d who:%d
See p2p protocol. who is the pid who requested the move.

rearrange-zone cid:%d pid:%d zone:%d value:%d who:%d
See p2p protocol.

set-card-value pid:%d cid:%d key:%s value:%d
Tells the client that the given player has set the given flag on the given card.

send-ping pid:%d
Asks the client to send a return-ping request. The client should include the given pid in its response.

return-ping pid:%d
Tells the client that the given player has returned a ping.

show-zone who:%d zone:%d size:%d pid:%d
Tells the client that player who has revealed size cards in the zone zone to player pid.

flip-coin pid:%d value:%d
Tells the client that the server has flipped a coin for the given player, and the result was value (zero or one).

roll-die pid:%d x:%d value:%d
Tells the client that the server has rolled an x-sided die for the given player, and the result was value (non-zero).

show-random cid:%d
Tells the client to display the given card to the user. (The card should have already been revealed from the server to the client.)

add-card pid:%d zone:%d cid:%d
Tells the client that the given player has added a card to his deck, and the card has been added to the end of the given zone.

request-new-game pid:%d value:%d
Tells the client that the given player has started or stopped requesting a new game.

reset-game
Tells the client that the server has emptied all zones and will reset the initial card lists in zones #1 and #2.

HANDSHAKE PROTOCOL

  1. Client connects to server.
  2. Server sends "version-number". (Client records its pid.)
  3. Client sends "version-number".
  4. If a game is either forming or in-progress, then the server sends the pids (player-connect) and player names (set-player-name) of all of the connected players.
  5. If a game is in-progress, the server sends the complete game state.
  6. While waiting for the next game to start, the client should send its name, deck, sideboard, and the "request-new-game" request.
  7. While waiting for the next game to start, the server may send "set-player-name", "set-deck", "set-sideboard", and "request-new-game" messages.
  8. Finally, the server sends "reset-game".
  9. The server sends initial zone sizes, the clients send initial life totals and shuffles, and the game begins.