HDP.md

September 4, 2015 · View on GitHub

The Protocol

The HDP protocol consists on 5 different messages types that share a common header with some basic user information. The protocol is defined with BNFs where ALL_CAPS_IMPLY_CONSTANTS, camelCaseImplyPrimitives and the '&' is used to denote "bitwise or" (super intuitive right?) while '|' denotes that one of multiple options can be chosen.

The Client Message Header

Prefixes all client originated messages

ClientHeader => Flags MessageID ClientTime SerpentId Message
Flags => uchar => MessageType
MessageType => PING | INFO | JOIN | ACTION
PING => 1
INFO => 2
JOIN => 3
ACTION => 4
MessageID => uint
ClientTime => ushort
SerpentId => uint
Message => PingRequest | GamesInfoRequest | GameInfoRequest
FieldDescription
FlagsFor now, only used to specify the message type
MessageIDIf the command requires a reply, the game will resend this ID to the client. During the game, this ID is expected to be the current tick of the client's game
ClientTimeThe game will return this value as is on every response
SerpentIdThe SerpentId the game provides when joining a game, 0 otherwise

The Server Message Header

Prefixes all server messages, both server originated and the replies.

ServerHeader => Flags MessageID Time Message
Flags => uchar => Success & MessageType
Success => SUCCEEDED | ERROR
SUCCEEDED => 128
ERROR => 0
MessageType => PING_RESPONSE | INFO_RESPONSE | JOIN_RESPONSE | GAME_UPDATE
PING_RESPONSE => 1
INFO_RESPONSE => 2
JOIN_RESPONSE => 3
GAME_UPDATE => 4
MessageID => uint
Time => ushort
Message => PingResponse | GamesInfoResponse | GameInfoResponse
FieldDescription
FlagsFor now, only used to specify the message type
MessageIDThe same message ID the client sent if a reply or an unique server generated ID
TimeIn the case of a response, the value sent by the client, otherwise, this is the current tick

Ping Request

The most simple message there is, it's just the header with no message at all.

PingRequest => Ø

Ping Response

Also just a header.

PingResponse => Ø

Game Info Request

If no game is specified, returns a list of the known games in the server with some basic information, if a GameId is specified, it returns more information about that specific game.

GamesInfoRequest => Ø
  • An empty message will return information about all games.

    GameInfoRequest => GameId GameId => ushort

FieldDescription
GameIdThe GameId to request info from

Games Info Response

Returns information of all known games.

GamesInfoResponse => GameCount [GameInfo]
GameCount => ushort
GameInfo => GameId Name State CurrentSerpents MaxSerpents
GameId => ushort
Name => StringSize bytes
StringSize => uchar
State => uchar => CREATED | COUNTDOWN | STARTED | FINISHED
CREATED => 0
COUNTDOWN => 1
STARTED => 2
FINISHED => 4
CurrentSerpents => uchar
MaxSerpents => uchar
FieldDescription
GameCountThe amount of running games
GameIdThe game's id
NameThe game's name as it should appear on screens
StateThe game state
CurrentSerpentsHow many serpents are currently in the game
MaxSerpentsThe maximum amount of serpents allowed in this game

Game Info Response

Returns information on a single game.

GameInfoResponse => GameId Name State Flags Cols Rows TickRate Countdown Rounds InitialFood MaxSerpents Walls Serpents
GameId => ushort
State => uchar => CREATED | COUNTDOWN | STARTED | FINISHED
CREATED => 0
COUNTDOWN => 1
STARTED => 2
FINISHED => 4
Flags => uchar => Walls & FoodVariation
Walls => WITH_WALLS | NO_WALLS
WITH_WALLS => 1
NO_WALLS => 0
FoodVariation => NONE | RANDOM | LINEAR | RANDOM_INCREMENT
NONE => 0
RANDOM => 2
LINEAR => 4
RANDOM_INCREMENT => 6
Cols => uchar
Rows => uchar
TickRate => uchar
Countdown => uchar
Rounds => uint
InitialFood => uchar
MaxSerpents => uchar
Walls => NumWalls [Cell]
NumWalls => ushort
Cell => Row Col
Row => uchar
Col => uchar
Serpents => CurrentSerpents [Serpent]
CurrentSerpents => uchar
Serpent => SerpentID Name
SerpentID => uint
Name => StringSize bytes
StringSize => uchar
FieldDescription
GameIdThe game's id
StateThe game state
Cols/RowsIndicate the size of the map
TickRateThe game's tick rate (i.e. the # of updates per second, regardless of the actual game speed)
CountdownThe game's countdown length (in ticks)
RoundsThe game max length (in ticks) - 0 means no limit
InitialFoodHow much food is in the serpents belly when they join
MaxSerpentsThe maximum amount of serpents allowed in this game
NumWallsNumber of walls in the board
Row1-based row index
Col1-based col index
CurrentSerpentsHow many serpents are currently in the game
NameAny string, this is either the game or the serpent name

Join Request

Joins a game.

JoinRequest => GameId Name
GameId => ushort
Name => StringSize bytes
StringSize => uchar
FieldDescription
GameIdThe game's id
NameAny string, this will be the serpent name

Join Response

Returns either an error or the game info if the join was successful. Note that this relies on the SUCCEEDED flag in the header to help with parsing. If this is not received, the client will still receive the game updates and it's up to the client to request the game info again.

JoinResponse => Error | Success
Error => GameId Reason
GameId => ushort
Reason => StringSize bytes
StringSize => uchar
Success => SerpentID GameInfoResponse
SerpentID => uint
FieldDescription
GameIdThe game's id
ReasonAny string, this is basically a small user friendly description of the error (usually "full" or "started")
SerpentIdThe ID the game assigned to the client
GameInfoResponseThe exact same format as the Game Info Response

Client Update

Notifies the server that the player moved its serpent and informs the last update that was received.

ClientUpdate => LastServerTick Direction
LastServerTick => ushort
Direction => LEFT | RIGHT | UP | DOWN
LEFT => 1
RIGHT => 2
UP => 4
DOWN => 8
FieldDescription
LastServerTickShould be the last tick received from the server
DirectionThe desired serpent direction

Server Update

Sent every server tick (50 times per second) with any updates the game had.

ServerUpdate => Tick NumDiffs [GameDiff]
Tick => ushort
NumDiffs => uchar
GameDiff => DiffType DiffData
DiffType => uchar => STATE | COUNTDOWN | ROUNDS | SERPENTS | FRUIT
STATE => 0
COUNTDOWN => 1
ROUNDS => 2
SERPENTS => 3
FRUIT => 4
DiffData => State | Countdown | Rounds | Serpents | Fruit
State => uchar => CREATED | COUNTDOWN | STARTED | FINISHED
CREATED => 0
COUNTDOWN => 1
STARTED => 2
FINISHED => 4
Countdown => ushort
Rounds => uint
Serpents => NumSerpents [Serpent]
NumSerpents => uchar
Serpent => SerpentID BodyLength [Cell]
SerpentID => uint
BodyLength => ushort
Fruit => Food Cell
Food => uchar
Cell => Row Col
Row => uchar
Col => uchar
FieldDescription
TickAm increasing value the client should use as LastServerTick
NumDiffsNumber of GameDiffs included in this update
StateThe game state
CountdownCountdown rounds until the game starts
Rounds# of Rounds until the game ends
FoodHow many new cells will be added to the serpent body when a serpent eats this fruit
BodyLengthThe number of cells that compose the serpent body
Row1-based row index
Col1-based col index