Because we've got people already clamouring to make third party clients (see I *told* you there was a reason my client stinks - it's to encourage others to write a better one!), I've been forced to release this spec before it's fully baked.
This is the state of the protocol as it is now, not as it'll be in a month or whatever. Pasting from a text file, so it'll be ugly.
Please submit suggestions.
THUDGAME:
=========
Miscellany
----------
This is a quick and dirty summary of the client-server dialog as it stands at the moment.
In common with RFCs, various phrases are common throughout:
MUST, MUST NOT - the specification must be adhered to. Failure may cause the client to fail, or is very impolite.
SHOULD, SHOULD NOT - the specification is a very good thing to adhere to. Failing to do so will have significant downsides, is probably impolite, but will still work.
MAY - the specification described is completely optional.
The plural of "Troll" is "Trolls". The plural of "Dwarf" is "Dwarfs" (NOT Dwarves).
"Koom Valley", "Thud", "Dwarf", and "Troll" SHOULD always be spelled with initial capitals.
Koom Valley rules are not supported in the move/replay parts of this dialog yet.
Lots of stuff won't work. If you have any problems getting it to work the way it's documented here, then when in doubt, ask. It's most likely just a bug in the server.
If you spot a bug or inconsistency anywhere, please do report it. We can't fix what we don't know about.
Suggestions for improvements to any part of this specification are welcomed and strongly encouraged. Suggestions SHOULD be made! ![]()
Overview
--------
The server is built upon a minimal implementation of IRCD.
General IRCD user-level commands MAY be available to clients, but MUST NOT be relied on.
Statefulness (such as it is) is maintained within a database.
This system allows for complete scalability, and zero-downtime server-changes.
The game server protocol is the middelware between the database an the various clients. It is provided by a bot running on the IRC server.
The client MUST NOT assume that the bot is always running.
The game sever bot runs, at the time of writing, in the channel #Thudgame, on the server 66.197.210.71 port 8080 with the name is "GameServ". The client SHOULD NOT assume that these are constants.
The client SHOULD have some way of changing these details on the hosting server. For example, the Java1.1 applet allows them to be passed in as parameters: <param name="host" value="66.197.210.71"> <param name="port" value="8080">
The client MAY assume that the server IP is the same as the one it was hosted on.
To IRC Server:
--------------
The following messages are to be sent to the server:
PONG :<key>
Response to the PING command.
MUST be sent in response (or the server will disconnect the client).
<key> whatever key was passed after the ping command, if any.
NICK
JOIN
PRIVMSG
See RFC1459 for details and syntax on these.
Beware, this is a very slim and quiet IRC server, and you will likely not see some responses that you are used to.
From IRC Server:
----------------
The following messages may come from the server, and need to be dealt with. See RFC1459 for full details.
Throughout, <nickmask> is the nickmask of the source of the command, as "nick!user@host", which will be composed of
zero or one "@" or "+" characters
The client's nick (see section on nicks)
one ! character
a unix-style alphanumeric username
one @ character
a hostname or IP.
<nickmask> 353 <junk> <junk> <channel> :<name>
A numeric indicating that the client has entered a channel, and listing the users already there.
The client SHOULD use this to build a nick list of users on the channel. Note that nicks in this list might be prefixed with '@' or '+': these characters MUST be stripped.
Nickmask will be the client's.
<nickmask> PING: <key>
A command to check if the client is awake. May be sent at any time, usually every N minutes.
Pings MUST NOT be relied on to keep the client awake or connected as they may never happen.
Nickmask will be the client's.
<nickmask> NICK :<new nick>
This command indicates that someone has changed ther name.
The client SHOULD update any displayed lists of names.
Nickmask will be that of the user changing their nick.
<nickmask> JOIN
This command indicates that someone has changed ther name.
The client SHOULD update any displayed lists of names.
Nickmask will be that of the user entering.
<nickmask> QUIT <junk> :<message>
<nickmask> PART <junk> :<message>
This command indicates that someone has leftthe channel or server.
The client SHOULD update any displayed lists of names.
Nickmask will be that of the user departing.
<nickmask> PRIVMSG <channel> :<message>
<nickmask> NOTICE <channel> :<message>
These are public messages to the channel.
Clients SHOULD NOT allow notices to be sent to channels.
Clients SHOULD make PRIVMSG to the channel the default mode of communication between users.
<nickmask> PRIVMSG <client nick> :<message>
<nickmask> NOTICE <client nick> :<message>
This is a privately displayed message from another user to the client.
The exception is PRIVMSG from a gameserv, which is a game server command.
These are dealt with in their own section below.
Clients SHOULD NOT display commands from a gameserv.
Clients SHOULD display all other private messages.
Clients MAY allow players to respond privately.
Clients MUST NOT auto-respond to NOTICE.
Clients MAY auto-respond to PRIVMSG, but away messages etc MUST NOT be sent to gameserv.
From GameServe:
---------------
The following will be sent by one of the gameservees as private messages to the client.
They may be uppercase or lowercase.
The client MUST check the command names case insensitively.
The client MUST check the command parameters case insensitively, but MAY display them case sensitively.
So "t/d" means one of "T", "t", "D", or "d". If the client wishes to display that, it can either use only the upper or lowercase version, or
For the exceptions, see the sections on data transfer, string encodings, and nicks, below.
The command will arrive as:
<gameserv's nickmask> PRIVMSG <client nick> :<command> <parameters>
HAVENAME <name>
Offer a name.
The client MUST change the nick with an IRC "/nick" command.
If it is a guest* name, [bot]* name or a name for which it has the password, the client SHOULD then send an IDENTIFY for this name.
<name> - a valid nick. See notes on nicks, below.
May be sent in response to a GUESTME, or randomly.
BADNAME <name>
Reject an IDENTIFY.
This may be because of a bad name, or a bad password.
The client SHOULD then change to a guest name, or another known name.
<name> - a string. May include spaces. May be in non-ascii encoding. See notes on encodings, below.
May be sent in response to an IDENTIFY, or randomly.
GOODNAME <name>
Confirm that the user is connected to the game server using name <name>.
<name> - a valid nick. See notes on nicks, below.
If <name> is different to the users current name, the client MUST consider that the user's name from now on.
This feature allows me to log in as Dewi Morgan, dewimorgan, or as the username, and still always appear as Dewi Morgan.
Sent in response to an IDENTIFY.
NOTONCHANNEL <chan>
If a user attempts to communicate with the game server but is not visible to that server in one of the channels it occupies, then the server MAY send this message.
<chan> - a valid channel.
The client SHOULD then attempt to join the channel <chan>
The server may send this message randomly as a response to prettymuch any message.
NOTLOGGEDIN
If a user attempts to communicate with the game server but has not sent an IDENTIFY for the name, then the server MAY send this message.
If the gameserver bot has crashed and reconnected, it will also send this message to all users at some point, as it does not know if they are logged in.
The server may send this message randomly as a response to prettymuch any message, other than GUESTME and IDENTIFY.
CHALLENGING <opponent>
Confirm to challenger that the server has successfully received the challenge and forwarded it to <opponent>.
<opponent> - a valid nick. See notes on nicks, below.
Does not guarantee that the opponent has received the challenge.
Sent in response to a CHALLENGE.
CHALLENGEFROM <gameID> <opponent> T/D <board>
Inform the client that another client has challenged it.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
<opponent> - a valid nick. See notes on nicks, below.
<t/d> - the team the opponent would like to play t=trolls, d=dwarfs
<board> - a string identifying the board suggested by the opponent.
Sent in response to a CHALLENGE from <opponent>
CANCELCHALLENGE <opponent>
Inform any client that the ongoing challenge to or from <opponent> has been cancelled.
<opponent> - a valid nick. See notes on nicks, below.
Sent in response to any event that could interrupt a challenge, such as the opponent disconnecting, etc.
REJECTEDCHALLENGE <opponent>
Inform the client that that the server has successfully received the challengerejection and forwarded it to the challenger.
<opponent> - a valid nick. See notes on nicks, below.
Sent in response to a REJECTCHALLENGE from the client.
PLAY <gameID> <opponent> T/D <board>
Inform both challenger and opponent that the challenge has been accepted.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
<opponent> - a valid nick. See notes on nicks, below.
<t/d> - the team the client will be playing. t=trolls, d=dwarfs
<board> - a string identifying the board the client SHOULD use.
Sent in response to a REJECTCHALLENGE from the opponent.
MESSAGE <message>...
A message from the server.
<message> - a string. May include spaces. May be in non-ascii encoding. See notes on encodings, below.
May be sent at any time.
ACCEPTEDRESIGN <gameid>
Inform the client that that opponent has accepted their resignation of <gameid>
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
Sent in response to ACCEPTRESIGN from the opponent.
REJECTEDRESIGN <gameid>
Inform the client that that opponent has rejected their resignation of <gameid>
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
Sent in response to REJECTRESIGN from the opponent.
MOVE <gameid> T/D <score> <x1> <y1> <x2> <y2>
Perform the described move.
*** WARNING *** This command is due to be drastically changed.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
"t" - player is trolls
"d" - player is dwarfs
<score> - score after the move for the moving team.
<x1> - x coordinate onboard to move from. Ascii decimal integer 1 to 15.
<y1> - y coordinate onboard to move from. Ascii decimal integer 1 to 15.
<x2> - x coordinate onboard to move to. Ascii decimal integer 1 to 15.
<y2> - y coordinate onboard to move to. Ascii decimal integer 1 to 15.
If a troll moves, all dwarfs ajacent to its position are assumed to have been taken.
This will be changing.
sent in response to a MOVE from the opponent.
MOVEREJECTED <gameid> <reason>
The requested move was rejected for some reason.
*** WARNING **** Renamed to REJECTEDMOVE in the next version of the server.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
<reason> - an ascii string showing the reason.
Sent in response to a MOVE from the client.
GAMEOVER <gameid>
The server has detected score=32 for one half of the game, or some other situation has been reached that forces an endgame.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
Sent at any random time, but usually in response to a MOVE from either player.
HOLDGAME <gameid>
The game has been suspended.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
Sent in response to a SUSPENDGAME from the opponent, or detecting that the opponent has disconnected, or random other reasons.
RESIGNING <gameid>
The oppoent has requested to resign the game.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
Sent in response to a RESIGN from the opponent.
CONTINUING <opponent> <game_id>
Confirmation to continue-challenger that continue has been sent.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
CONTINUEFROM <gameID> <opponent> <board>
sent to opponent when challenging to continue.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
REJECTEDCONTINUE <username>
sent to challenger when opponent rejects.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
ACCEPTEDCONTINUE <gameID> <username> T/D <board>
sent to both to begin a continued game.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
WEBUPDATE <gameid> UPDATE/REPLAY/SKIN <url>
Provide a URL where requested data can be obtained.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
"UPDATE" - this is a response to a REQUESTUPDATE
"REPLAY" - this is a response to a REQUESTREPLAY
"SKIN" - this is a response to a REQUESTSKIN
<url> - URL at which the data can be found.
DATA <gameid> UPDATE/REPLAY/SKIN <slice> <numslices> <data>
Provide a chunk of the requested data.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
"UPDATE" - this is a response to a REQUESTUPDATE
"REPLAY" - this is a response to a REQUESTREPLAY or CONTINUE
"SKIN" - this is a response to a REQUESTSKIN
<slice> - the number of the slice, from 1 to numslices as a decimal ascii integer
<numslices> - the number of the slice, from 1 to numslices as a decimal ascii integer
<data> - a chunk of base-64 encoded bzipped data. See note on data transfer, below.
GAMEINFO <gameid> <opponent> <T/D-which you are> <T/D-who's move> <score-t> <score-d> <board>
Provide information on a game in progress.
The syntax of this command is still relatively fluid.
Note that it does not provide sufficient scoring information for a complete game.
Note that it does not say what half of the game it is.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
<opponent> - a valid nick. See notes on nicks, below.
<t/d-which you are> - the team that the requestor is playing.
<t/d-who's move> - the team that will take the next move.
<score-t> - decimal ascii integer, troll score for current half of game
<score-d> - decimal ascii integer, troll score for current half of game
Sent in response to a REQUESTGAMEINFO, REQUESTUPDATE, or REQUESTREPLAY from the client.
PLAYERINFO <player> <portrait> <rank> <otherinfo>
Provide information on a player.
The syntax of this command is still relatively fluid.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
<player> - a valid nick. See notes on nicks, below.
<rank> - an ascii string with no spaces.
<otherinfo> - an ascii string, possibly with spaces.
Sent in response to a REQUESTPLAYERINFO from the client.
AREYOUSURE <recipient> <quantity> <item>...
RECEIVING <item>...
ACCEPTEDWAGER <gameid> <quantity> <item>...
CANCELLEDWAGER <gameid> <quantity> <item>...
REJECTEDWAGER <gameid> <quantity> <item>...
WAGERED <gameid> <quantity> <item>...
Trading/wagering commands. As yet, they are undocumented and unsupported.
Client SHOULD be written in such a way that a trading/wagering interface that uses these commands can be introduced at a later date.
To GameServ:
------------
The following messages are sent to the one of the game servers such as GameServ in a private message, as:
GUESTME
Ask for a guest name, guaranteed free of nick collisions.
Sent when connecting.
IDENTIFY <password>
Register our presence with the game server.
<password> - a valid ascii string. May contain spaces.
The password may be anything for users connecting with a guest nick.
Sent when connecting, and in response to any NOTLOGGEDIN or HAVENAME message.
CHALLENGE <username> T/D/? <board>
Challenge <username> to a game.
<username> - a valid nick. See notes on nicks, below.
"t" - user would like to play trolls.
"d" - user would like to play drawfs.
"?" - user doen't care what team they play.
<board> - the board the player would like to play on.
Sent in response to a user action.
ACCEPTCHALLENGE <gameID> <opponent> T/D <board>
Accept a challenge.
Request to play "t"-trolls or "d"-dwarfs.
Note: this usally means the challenged player gets to choose the team, though the server gets the final say.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
<opponent> - a valid nick. See notes on nicks, below.
"t" - user would like to play trolls.
"d" - user would like to play drawfs.
<board> - the board the player would like to play on.
Sent in response to CHALLENGEFROM, or CONTINUEFROM, following a user prompt.
If sent in response to CONTINUEFROM, this will create a new game, aborting their old game.
REJECTCHALLENGE <username> <gameID>
Reject a challenge.
<username> - a valid nick. See notes on nicks, below.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
Sent in response to CHALLENGEFROM, following a user prompt.
ACCEPTCONTINUE <gameID> <opponent> <board>
Accept a continuation challenge.
<username> - a valid nick. See notes on nicks, below.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
<board> - the board the player would like to play on.
Sent in response to CONTINUEFROM, following a user prompt.
REJECTCONTINUE <username> <gameID>
Reject a continuation challenge.
<username> - a valid nick. See notes on nicks, below.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
Sent in response to CONTINUEFROM, following a user prompt.
MOVE <gameid> T/D <x1> <y1> <x2> <y2>
Move a piece.
Sent in response to user action.
*** WARNING *** This command is due to change drastically.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
"t" - player is trolls
"d" - player is dwarfs
<x1> - x coordinate onboard to move from. Ascii decimal integer 1 to 15.
<y1> - y coordinate onboard to move from. Ascii decimal integer 1 to 15.
<x2> - x coordinate onboard to move to. Ascii decimal integer 1 to 15.
<y2> - y coordinate onboard to move to. Ascii decimal integer 1 to 15.
RESIGN <gameid>
Request to resign a game in progress.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
Sent in response to user action.
POSTPONE <gameid>
Postpone a game in progress.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
Sent in response to user action.
Such actions may include closing the window, closing the application, etc.
Where possible, the client SHOULD send this whenever the user leaves the game for any reason.
Not sending it may leave opponents unaware that the user has left.
ACCEPTRESIGN <gameid>
Accept the opponent's resignation.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
Sent in response to RESIGNING, following a user prompt.
REJECTRESIGN <gameid>
Reject the opponent's resignation.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
Sent in response to RESIGNING, following a user prompt.
REQUESTUPDATE <gameid> WEB/DATA
Request the current layout from the server, either as a URL or as inline bzipped data in messages.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
"web" - client would like the data as a URL to downlod it from. See notes on data transfer, below.
"data" - client would like the data through messaged data. See notes on data transfer, below.
Sent by the client whenever necessary.
This command is here to allow the client to resynchronise itself with the server, and SHOULD NOT be used to update after every move.
REQUESTREPLAY <gameid> WEB/DATA
Request the entire game history for <gameid> from the game server.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
"web" - client would like the data as a URL to downlod it from. See notes on data transfer, below.
"data" - client would like the data through messaged data. See notes on data transfer, below.
Sent whenever the client wants to replay a game.
REQUESTSKIN <gameid> WEB/DATA
Request a game board skin from the server.
This command is not yet implemented.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
"web" - client would like the data as a URL to downlod it from. See notes on data transfer, below.
"data" - client would like the data through messaged data. See notes on data transfer, below.
Sent at the beginning of a game, or when the user wants to change skins to a skin that is not cached by the client.
REQUESTGAMEINFO <gameid>
Request general game information from the server.
<gameid> - an decimal ascii long int uniquely identifying the game in the history of the server.
Sent whenever the client wants.
REQUESTPLAYERINFO <player>
Request general player information from the server.
<player> - a valid nick. See notes on nicks, below.
Sent whenever the client wants.
GIVE <recipient> <quantity> <item>...
YESGIVE <recipient> <quantity> <item>...
WAGER <gameid> <quantity> <item>...
ACCEPTWAGER <gameid> <quantity> <item>...
REJECTWAGER <gameid> <quantity> <item>...
Trading/wagering commands. As yet, they are undocumented and unsupported.
Client SHOULD be written in such a way that a trading/wagering interface that uses these commands can be introduced at a later date.
Security
--------
Passwords SHOULD be displayed as asterisks.
Reasonable efforts SHOULD be made to prevent multiple copies of the client running on the same machine. For Java, this means checking static class variables to check that only one client is running per JVM. For languages with a greater access to the computer, greater steps can be taken.
Nicks and passwords
-------------------
Clients SHOULD prevent users entering invalid usernames or passwords.
Clients SHOULD hide all Gameserv nicks from being displayed in lists.
Clients MUST NOT permit gameserv nicks to be challenged or otherwise treated as users.
Passwords may be up to 20 characters and may contain any ascii character 32 to 126 inclusive.
Nicks MAY contain upper and lowercase letters, numbers, and miscellaneous other ascii characters.
Nicks MAY NOT contain characters under 33 decimal. This means nicks MAY NOT include the space character.
Nicks also MAY NOT contain any of the characters ":!@+" as these are needed in the IRC protocol to denote different areas of nickmasks.
Since the permitted characters within nicks may change (currently alphanumerics plus ^-{[`]}\ in accordance with RFC1459) clients SHOULD accept any non-forbidden characters with byte values higher than decimal 32.
In violation of RFC1459, nicks MAY be up to 22 characters (RCF1459 sets a limit of 9).
In another violation of RFC1459, two nicks are considered equivalent if, once lowercased, they contain the same ascii alphanumeric characters, so there will be only one "dewimorgan"/"Dewi^Morgan". (RFC1459 says non-alphanumeric characters are significant in this). All nicks MUST be unique.
To represent the space character, the '^' carat character (Ascii 94 decimal) is used instead. Clients SHOULD display this character as a space when used in nicks.
Nicks from Guest1001 to Guest8999 (possibly higher and lower numbers later) are reserved for guests.
Nicks from Bot1001 upwards are suggested as nicks for "bot"s and AI constructs to differentiate them from real users. Cyborgs are a tricky problem, and may be considered cheating.
Nicks containing the word "serv" are all reserved.
Nicks beginning with the word "gameserv" are valid game servers.
Clients MUST communicate with a gameserv in their channel.
Clients SHOULD communicate with GameServ if it is in their channel.
Clients SHOULD communicate with the case-insensitive alphabetically last gameserv in their channel (so, communicate with "GameServzzzz" rather than "GameServa" if both are in the channel, unless "GameServ" is there also).
Encodings
---------
The following character encodings are supported for strings:
ASCII - All commands and arguments use 7-bit US ASCII values between 33 and 126, inclusive. The space character, ascii 32, is used to delimit arguments. Clients MUST support ASCII.
ISO8859-1 - This is the default for all strings which do not contain a BOM. This is basically an extension of 7-bit US ASCII. Clients SHOULD support this.
UTF-8 - All strings that begin with the byte sequence 0xEF,BB,BF. This is the encoding that clients SHOULD support and SHOULD use for multibyte strings. Clients SHOULD NOT use this if single-byte ISO8859-1 can be used for the whole string.
Data - see Data Transfer section, below.
UTF-16/UCS-2, little endian - All strings that begin with the byte sequence 0xFE,FF. This tends to be Microsoft's preferred encoding. Clients MAY support this, but SHOULD NOT use it where UTF-8 is feasible.
UTF-16/UCS-2, big endian - All strings that begin with the byte sequence 0xFF,FE. Clients MAY support this, but SHOULD NOT use it where UTF-8 is feasible.
UTF-32/UCS-4, little endian - All strings that begin with the byte sequence 0xFF,FE,00,00. Clients MAY support this, but SHOULD NOT use it where UTF-8 is feasible.
UTF-32/UCS-4, big-endian - All strings that begin with the byte sequence 0x00,00,FE,FF. Clients MAY support this, but SHOULD NOT use it where UTF-8 is feasible.
Data Transfer
-------------
Clients MUST support one or the other of these transfer schemes for each of SKIN, UPDATE, and REPLAY. Clients MAY support both.
Data transfer by URLS ("WEBUPDATE") is currently not implemented, but will work like any other web data download, with compression available if declared as supported in the request headers.
Data transfer over the IRC network ("DATA") is performed by sending messages containing Base-64-encoded, BZIPped data chunks.
This Base64 implementation uses the characters: standard Base64 encoding, A-Za-z0-9+/ with = as padding for solitary single/double bytes. This is, by a happy coincidence, the same version that PHP uses.
Concatenate all chunks before base-64 decoding, then un-bzip to get the required data.
Update Syntax
-------------
For "UPDATE", the board layout for the regular game (not Koom Valley yet) is given as follows:
The layout data is 80 bytes long precisely.
Pieces at 0,0 are "taken". Apart from that special case, positions are specified from 1 to 15 x and y.
Data is passed as bytes[dwarf1x, dwarf1y, dwarf2x..., troll1x, troll1y...].
The position of the rock is *not given*.
Replay Syntax
-------------
*** WARNING *** The following is likely to change totally when the move syntax changes ("takes" will be included), and when multilevel undo is implemented (it will become a tree instead of linear), and when people can add anotations to moves, and so on. The solution to this is likely to be to use the SGF format, or some modification of it - see discussion on the thudgame forums and the SGF mailing list.
For "REPLAY", the replay is sent as a linear sequence of moves. At each move, all pieces that could have been taken are assumed to have been taken.
Each move is made of four byte-value coordinates from 1 to 15 (yes, I know you could fit two coords in a single byte if you wanted - but I'm trying to make it EASY for programmers to write a client!).
Coordinates are specified as source-x, source-y, destination-x, destination-y.
The byte sequence 0,0,0,1 marks the end of the first half.
The byte sequence 0,0,0,2 marks the end of the game.
Dialog stories
==============
These are a basic run-through of how things SHOULD go. If neither server nor client ever deviates from these guidelines, then everything should go smoothly. But the majority of the message parsing code on both client and server is devoted to dealing with cases where people do NOT stick to the correct flow: behaviour in these cases is unfortunately largely undocumented, though it should be either a sane guess at what was wanted, or an sane error.
Progress key:
[No annotation] = Completely done.
+ = Clientside done. Changes needed in server.
* = Server done. Changes needed in client
X = will not be implemented at this point in time.
- = just a way to indent.
Registering:
-Not documented or implemented or designed yet.
-(not a server dialog feature)
Skinning:
-Not documented or implemented or designed yet.
-(not a server dialog feature)
Buying items:
-Not documented or implemented or designed yet.
-(not a server dialog feature)
Logging in:
#-Not documented yet.
Wagering:
*-Not documented or implemented clientside yet.
Transfering items:
*-Not documented or implemented clientside yet.
Starting a new game/Loading an old game:
-When a userame is selected in the player client, and the "challenge" button is pressed.
-Player client sends challenge to server.
-Server checks for validity.
-If invalid (at any point in this dialog), server sends a message plus:
--CANCELCHALLENGE <opponent>
-Server checks for existing game.
--*If not found, forwards challenge to opponent:
----CHALLENGEFROM <game_id> <name> <team> <board>
---And lets player know it's been done, with the game id (pointless?):
----CHALLENGING <opponent> <game_id>
---Opponent client popup asks if they wish to start a new game with the player.
---If they cancel:
----Opponent client sends:
-----REJECTCHALLENGE <username> <gameID> - reject a challenge, to server
----Existing game windows against them remain open.
----The server forwards the rejection to the player:
-----REJECTEDCHALLENGE <username>
---If they create a new game,
----Opponent client sends:
-----ACCEPTCHALLENGE <gameID> <opponent> <t/d> <board>
----The server then sends, to player and opponent:
-----PLAY <game_id> <opponent> <t/d> <board>
----A new board is created on player machine.
----A new board is created on opponent machine.
--*If existing game found, forwards challenge to opponent:
----CONTINUEFROM <gameID> <opponent> <t/d> <board>
---And lets player know it's been done, with the game id (pointless?):
----CONTINUING <opponent> <game_id>
---Opponent client popup asks if they wish to continue the current game, or start anew.
---If they cancel:
----Opponent client sends:
-----REJECTCONTINUE <username> <gameID> - reject a challenge, to server
X----Existing game windows against them remain open.
----The server forwards the rejection to the player:
-----REJECTEDCONTINUE <username>
---If they continue:
----Opponent client sends:
-----ACCEPTCONTINUE <gameID> <opponent> <board>
----Server sends to the player and the opponent:
-----ACCEPTEDCONTINUE <gameID> <username> <t/d> <board>
-----DATA <gameID> replay <slice> <numslices> <data>
----The game is reloaded on both machines, from the data.
X----Existing windows are reused to retain chat history.
---If they create a new game:
----Opponent client sends:
-----ACCEPTCHALLENGE <gameID> <opponent> <t/d> <board>
X----Any incomplete game history is wiped from the server.
----The server then sends, to player and opponent:
-----PLAY <game_id> <opponent> <t/d> <board>
-----A new board is created on player machine,
X------reusing any window so you retain chat history.
-----A new board is created on opponent machine,
X------reusing any window so you retain chat history.
Saving a game:
-Done automatically with each move.
-Chat ISN'T saved to server (privacy, diskspace) or client (insecurity), so can't be recovered #once you close a window.
Changing sides (ending first half):
-When player presses "end game" button, and they're playing the first half.
-Player client sends:
--RESIGN <game_id>
-Server checks if the game is in progress and the player is playing it.
--If not, server sends to player:
----HOLDGAME <game_id>
--Server ends processing.
-Server sends request to opponent.
--RESIGNING <game_id>
-If opponent client is not playing that gameid, it sends:
---POSTPONE <game_id>
-If playing a game, opponent client popup asks if it's OK to change sides.
-If opponent rejects:
--Opponent client sends:
---REJECTRESIGN <game_id>
--Server forwards rejection to player.
---REJECTEDRESIGN <game_id>
--Player client displays message.
--Game is continued.
-If opponent accepts:
*--Opponent client destroys existing game board display, creates a new one.
--Opponent client sends acceptance to server.
---ACCEPTRESIGN <game_id>
--Server adds "board change" as a move to the move history. (00 00 00 01)
*--[Clients can parse "board change" as a move] (board.replayFromData switch statement)
--Server updates layout to be the initial layout.
+--Server stores first-half score.
--Server forwards acceptance to player.
---ACCEPTEDRESIGN <game_id>
*--Player client destroys existing game board display, creates a new one.
+--Server sends halftime summary message to player and opponent.
Ending a game (second half):
-When player presses "end game" button, and they're playing the second half.
-Player client sends:
--RESIGN <game_id>
-Server checks if the game is in progress and the player is playing it.
--If not, server sends to player:
----HOLDGAME <game_id>
--Server ends processing.
-Server sends request to opponent.
--RESIGNING <game_id>
-If opponent client is not playing that gameid, it sends:
---POSTPONE <game_id>
-If playing a game, opponent client popup asks if it's OK to end the game.
-If opponent rejects, Opponent client sends:
----REJECTRESIGN <game_id>
--Server forwards rejection to player:
---REJECTEDRESIGN <game_id>
--Player client displays message.
--Game is continued.
-If opponent accepts:
*--Opponent client clears all pieces from game board.
--Opponent client sends acceptance to server.
---ACCEPTRESIGN <game_id>
--Server adds "end game" as a move to the move history. (00 00 00 02)
+--Server stores second-half score, and total score.
+--Server marks game as no longer being played.
+--Server stores game in permanent storage.
--Server forwards acceptance to player.
---ACCEPTEDRESIGN <game_id>
*--Player client clears all pieces from game board.
+--Server sends final summary message to player and opponent.
Making a move (including bad moves):
-Not documented yet. Due to be redesigned.
X-Undoing a move:
X--When undo button is pressed.
X--Request is sent to opponent.
X--If rejected, rejection message is sent to player.
X--If accepted, the server:
X---removes last move from savegame,
X---recreates the board state from the savegame,
X---sends a refresh to the player,
X---sends a refresh to the opponent.
X-Refreshing a game:
X--When clicking "refresh" button, or in situations where board may be out of synch.
X--Client sends refresh request to server (or server decides it's needed).
X--Server sends refreshed board and game data.
X--Client parses and displays refreshed board.
X-Closing a window:
X--Done by getting a close window message from the server, or by clicking the [x] button.
X--Board, window, components and game history are freed from memory.
X--If closure was not requested by server (or maybe always),
X---Client sends "window closing" message to server
X--If player is in a game on that window,
X---Server marks game as postponed (if necessary),
X---Server sends close window message to opponent.
Replaying a historical game:
-Not documented or implemented or designed yet.
Keeping score:
-Not documented or implemented yet.











