ZRP (Zwoo Request Protocol)
The ZRP is used for Communication between the game server an a playing client.
Its a simple protocol on top of WebSockets using JSON as data format.
Definitions:
Server: the zwoo game serverClient: a player or spectator connected to the serverPlayer: all players of a game (bots act as normal players)Host: a special type ofPlayer, he can change settings and start the gameSpectator: watches the game but does not participateBot: special type ofPlayer, its controlled by an algorithm. It can't attend states like Disconnected or Spectator.Message: a logical unit of communication between theClientand theServer, either aEventorNotification, can consist of multiple WebSocket framesEvent: a message sent from aPlayerorSpectatorto theServerNotification: a message sent from theServerto aPlayerorSpectatorGameEvent: a domain specific event, like a player joined the game emitted by theServer. This will be translated into a ZRPNotificationand sent to theClient.
Current Version: 5.0.0
Message Structure
code,<data>The Code is a number, used to identify the type of the message. The data is a JSON object, containing the actual payload of the message.
General Types
Roles
Every client has a role, which defines what he can do in the game.
enum ZRPRole {
Host = 1,
Player = 2,
Spectator = 3,
Bot = 4
}Player State
The connection state of a client. This applies to Players and Spectators, Bots are always connected.
enum ZRPPlayerState {
Connected = 1,
Disconnected = 2
}Card Color [v5.0.0]
All possible card colors in the game.
public enum CardColor
{
None = 0,
Red = 1,
Yellow = 2,
Blue = 3,
Green = 4,
Black = 5
}Card Type [v5.0.0]
All possible card types in the game.
public enum CardType
{
None = 0,
Zero = 1,
One = 2,
Two = 3,
Three = 4,
Four = 5,
Five = 6,
Six = 7,
Seven = 8,
Eight = 9,
Nine = 10,
Skip = 11,
Reverse = 12,
DrawTwo = 13,
Wild = 14,
WildFour = 15
}Card [v5.0.0]
A card is a common object, used in multiple Events and Notifications.
{
"color": <card color enum: number>,
"type": <card type enum: number>
}Decision Type
The type of a decision, which can be requested from a player.
enum DecisionType {
SelectColor = 1,
SelectPlayer = 2
}Settings Type
The data type of a setting.
enum SettingType {
Readonly = 0,
Numeric = 1,
Boolean = 2
}UIFeedback
GameEvents can trigger visual feedback for the user. This feedback consists of 3 integral parts: type, kind, arguments.
kind: defines which arguments should be used in which waytype: which feedback should be displayedarguments: provide context for the feedback, like which players are involved
UIFeedbackType
enum UIFeedbackType {
Skipped = 1,
DirectionChanged = 2,
PlayerHasDrawn = 3,
MissedLast = 4,
DeckSwapped = 5,
ColorChanged = 6,
}UIFeedbackKind
enum UIFeedbackKind {
Individual = 1, // single user involved
Interaction = 2, // interaction between two users
Unaffected = 3 // no user directly involved
}UIFeedbackArguments
The core arguments are the following, these indicate, that the client can safely resolve usernames from them.
- Individual:
{target: <id> } - Interaction:
{target: <id>,origin: <id> } - Unaffected:
{}
Besides these, each Feedback Event may define further arguments, other well known one are:
{ amount: <a transferred amount of cards> }
GameProfileGroup [deprecated v5.0.0]
enum GameProfileGroup {
System = 1,
User = 2,
}Codes
General (1xx)
100 PlayerJoinedNotification
A Player joined the game.
{
"id": <player game id: number>, [v4.0.0]
"username": <player username: string>,
"isBot": <player is bot: boolean>, [v4.0.0]
"score": <player score: number>, [v5.0.0]
// "wins": <player wins: number> [deprecated v2.0.0]
// "id": <player public id: string> [deprecated v4.0.0]
// "wins": <player wins: number>, [v4.0.0, deprecated v5.0.0]
}101 SpectatorJoinedNotification
A Spectator joined the game.
{
"id": <player game id: number>, [v4.0.0]
"username": <player username: string>,
// "wins": <player wins: number> [deprecated: v2.0.0]
// "id": <player public id: string> [deprecated v4.0.0]
}102 PlayerLeftNotification
A Player left the game.
{
"id": <player game id: number>, [v4.0.0]
// "username": <player username: string> [deprecated: v2.0.0]
// "id": <player public id: string> [v2.0.0] [deprecated: v4.0.0]
}103 SpectatorLeftNotification
A Spectator left the game.
{
"id": <player game id: number>, [v4.0.0]
// "username": <spectator username: string> [deprecated: v2.0.0]
// "id": <player public id: string> [v2.0.0] [deprecated: v4.0.0]
}104 ChatMessageEvent
Roles: Host, Player, Spectator, Bot
A client wants to send a message in the chat.
{
"message": <message content: string>
}105 ChatMessageNotification
The Server forwards a chat message from a client to all other clients.
{
"id": <sender game id: number>, [v4.0.0]
"message": <message: string>,
// "role": <senders role: number> [deprecated v4.0.0]
// "username": <sender username: string> [deprecated v4.0.0]
}106 LeaveEvent
Roles: Host, Player, Spectator
A client wants to leave the game.
{}108 GetLobbyEvent
Roles: Host, Player, Spectator, Bot
A client wants to get all players and spectators in the current lobby.
{}109 GetLobbyNotification
Sends all clients in the current Lobby to the Callers[#108].
{
"players": [
{
"id": <player game id: number>, [v4.0.0]
"username": <username: string>,
"role": <user role: number>,
"state": <player state: number>, [v1.5.0]
"score": <player score: number>, [v5.0.0]
// "wins": <wins: number> [deprecated v2.0.0]
// "id": <player public id: string> [v2.0.0] [deprecated v4.0.0]
// "wins": <player wins: number> [v4.0.0, detracted v5.0.0]
}
]
}110 SpectatorToPlayerEvent
Roles: Spectator
A Spectator wants to join the game and play.
{}111 PlayerToSpectatorEvent
Roles: Player
A Player wants to stop playing and but keep spectating.
{
"id": <player game id: number>, [v4.0.0]
// "username": <player username: string> [deprecated: v2.0.0]
// "id": <player public id: string> [v2.0.0] [deprecated v4.0.0]
}112 PlayerToHostEvent
Roles: Host
The Host wants to give his host role to another Player.
{
"id": <player game id: number>, [v4.0.0]
// "username": <player username: string> [deprecated: v2.0.0]
// "id": <player public id: string> [v2.0.0] [deprecated v4.0.0]
}113 YouAreHostNotification
Notifies a Player that he is now the host of the game.
{}114 NewHostNotification
Notifies all Players and Spectators of a game that the game has a new Host
{
"id": <player game id: number>, [v4.0.0]
// "username": <player username: string> [deprecated: v2.0.0]
// "id": <player public id: string> [v2.0.0] [deprecated v4.0.0]
}115 KickPlayerEvent
Roles: Host
The Host removes a Player or Spectator from the game.
{
"id": <player game id: number>, [v4.0.0]
// "username": <player username: string> [deprecated: v2.0.0]
// "id": <player public id: string> [v2.0.0] [deprecated v4.0.0]
}116 PlayerChangedRoleNotification
Notifies all clients that a another client changed its role.
{
"id": <player game id: number>, [v4.0.0]
"role": <player role: number>,
"score": <player score: number>, [v5.0.0]
// "username": <player username: string> [deprecated: v2.0.0]
// "id": <player public id: string> [v2.0.0] [deprecated v4.0.0]
// "wins": <player wins: string> [deprecated v2.0.0]
// "wins": <player wins: number> [v4.0.0, deprecated v5.0.0]
}117 PlayerDisconnectedNotification [v1.4.0]
Notifies all clients of a game the a Player disconnected from the game without leaving.
{
"id": <player game id: number>, [v4.0.0]
// "username": <player username: string> [deprecated: v2.0.0]
// "id": <player public id: string> [v2.0.0] [deprecated v4.0.0]
}118 PlayerReconnectedNotification [v1.4.0]
Notifies all clients of a game the a Player who disconnected first now reconnected to the game.
{
"id": <player game id: number>, [v4.0.0]
// "username": <player username: string> [deprecated: v2.0.0]
// "id": <player public id: string> [v2.0.0] [deprecated v4.0.0]
}198 KeepAliveEvent [v1.1.0]
Roles: Host, Player, Spectator, Bot
Used to keep the websocket connections alive and timeouts.
{ }199 AckKeepAliveNotification [v1.1.0]
Acknowledge a keep alive event.
{ }Lobby (2xx)
Codes used for setting up the game in the lobby phase (mostly communication between Host and Server)
200 UpdateSettingEvent
Roles: Host
The Host changes a setting of the game.
{
"setting": <setting path: string>,
"value": <new value: string>
}201 SettingChangedNotification
Notifies all clients that a settings of the game changed.
{
"setting": <setting path: string>,
"value": <new value: string>
}202 GetSettingsEvent
Roles: Host, Player, Spectator, Bot
A client requests all current game settings.
{}203 AllSettingsNotification
Sends the Caller[#202] all game settings.
{
"settings": [
{
"setting": <setting path: string>,
"value": <setting value: number>,
"title": <setting title: string>, [v3.2.0]
"description": <setting description: string>, [v3.2.0]
"type": <setting type: SettingsType>, [v3.2.0]
"min": <numeric min value: number>, [v3.2.0]
"max": <numeric max value: number>, [v3.2.0]
"isReadonly": <whether the value can be changed: boolean> [v3.2.0]
}
]
}210 StartGameEvent
Roles: Host
The Host starts the game.
{}230 CreateBotEvent [v2.0.0]
Roles: Host
The Host creates a new bot for the game.
{
"username": <bot name: string>,
"config": {
"type": <config preset type: number>
}
}231 BotJoinedNotification [v2.0.0]
Notifies all clients that a new Bot joined the game.
{
"id": <bot game id: number>, [v4.0.0]
"username": <bot username: string>,
"score": <bot score: number>, [v5.0.0]
// "id": <player public id: string>, [deprecated: v4.0.0]
// "wins": <bot wins: number>, [v4.0.0. deprecated]
}232 BotLeftNotification [v2.0.0]
Notifies all clients that a Bot left the game.
{
"id": <bot game id: number>, [v4.0.0]
// "id": <bot public id: string> [deprecated v4.0.0]
}233 UpdateBotEvent [v2.0.0]
Roles: Host
The Host updates the configuration of a bot.
{
"id": <bot game id: number>, [v4.0.0]
"config": {
"type": <number>
}
// "id": <bot public id: string> [deprecated v4.0.0]
}[reserved|not implemented] 234 BotUpdatedNotification
[will be used to notify other clients about changes in bots]
235 DeleteBotEvent [v2.0.0]
Roles: Host
The Host removed a bot from the game.
{
"id": <bot game id: number>, [v4.0.0]
// "id": <bot public id: string> [deprecated v4.0.0]
}236 GetBotsEvent [v2.0.0]
Roles: Host
A a (new) Host requests the configuration off all current bots.
{}237 AllBotsNotification [v2.0.0]
Sends the Caller[#235] the configuration of all current bots.
{
"bots": [
{
"id": <bot game id: number>, [v4.0.0]
"username": <bot username: string>,
"config": {
"type": <number>
},
"score": <bot score: number>, [v5.0.0]
// "id": <bot public id: string> [deprecated v4.0.0]
// "wins": <bot wins: number> [v4.0.0, deprecated v5.0.0]
}
]
}Game (3xx)
All codes for the actual game.
300 GameStartedNotification
Broadcasted by the Server when the game started.
{
"players": [
{
"id": <player game id: number>,
"username": <player id path: string>,
"cards": <amount: number>,
"isActivePlayer": <isActive: boolean>,
"order": <orderInGame: number>
}
], [v4.0.0]
"hand": [<cards: Card[]>], [v5.0.0]
"pile": <Card>, [v5.0.0]
// "hand": [
// {
// "type": <card type: number>,
// "symbol": <card symbol: number>
// }
// ], [v4.0.0, deprecated v5.0.0]
// "pile": {
// "type": <card type: number>,
// "symbol": <card symbol: number>
// } [v4.0.0, deprecated v5.0.0]
}301 StartTurnNotification
Notifies a player that his turn started.
{}302 EndTurnNotification
Notifies a player that his turn ended.
{}303 RequestEndTurnEvent
Roles: Host, Player, Bot
A Player requests his turn to be ended.
{}304 PlaceCardEvent
Roles: Host, Player, Bot
Send by a Player when he wants to place a card.
{
"card": <placed card: Card>, [v5.0.0]
// "type": <card type: number>, [deprecated v5.0.0]
// "symbol": <card symbol: number> [deprecated v5.0.0]
}305 DrawCardEvent
Roles: Host, Player, Bot
A Player wants to draw a card from the pile.
{}306 SendCardsNotification
Sends a Player a new card.
{
"cards": [<cards: Card[]>], [v5.0.0]
// "cards": [
// {
// "type": <card type: number>,
// "symbol": <card symbol: number>
// }
// ] [v2.0.0, deprecated v5.0.0]
// "type": <card type: number> [deprecated v2.0.0]
// "symbol": <card symbol: number> [deprecated v2.0.0]
}307 RemoveCardNotification
Notifies a Player that one of his cards should be removed from is deck.
{
"cards": [<cards: Card[]>], [v5.0.0]
// "cards": [
// {
// "type": <card type: number>,
// "symbol": <card symbol: number>
// }
// ] [v3.3.0, deprecated v5.0.0]
// "type": <card type: number> [deprecated v3.3.0]
// "symbol": <card symbol: number> [deprecated v3.3.0]
}308 StateUpdateNotification
Notifies all Players and Spectators whenever the game state updates.
{
"activePlayer": <player game id: number>, [v4.0.0]
"cardAmounts": <card amounts of subset of players: Dictionary<number, number>>, [v4.0.0]
"currentDrawAmount": <amount active player would draw: number | null>, [v3.0.0]
"feedback": [
{
"type": <the feedbacks type: UIFeedbackType>,
"kind": <the feedbacks kind: UIFeedbackKind>,
"args": <the context, see UIFeedbackArguments>
}
], [v4.1.0]
"pileTop": <card: Card>, [v5.0.0]
// "activePlayerCardAmount": <amount: number> [deprecated v3.0.0]
// "lastPlayer": <player public id: string> [deprecated v3.0.0]
// "lastPlayerCardAmount": <amount: number> [deprecated v3.0.0]
// "activePlayer": <playerName: string> [deprecated v2.0.0]
// "lastPlayer": <playerName: string> [deprecated v2.0.0]
// "activePlayer": <player public id: string> [v2.0.0] [deprecated v4.0.0]
// "cardAmounts": <card amounts of subset of players: Dictionary<string, number>> [3.0.0] [deprecated v4.0.0]
// "pileTop": {
// "type": <card type: number>,
// "symbol": <card symbol: number>,
// } [deprecated v5.0.0]
}310 GetDeckEvent
Roles: Host, Player, Bot
Request all cards that the Caller has in its deck.
{}311 SendDeckNotification
Sends the Caller[#310] his current deck.
{
"hand": [<cards: Card[]>], [v5.0.0]
// "hand": [
// {
// "type": <card type: number>,
// "symbol": <card symbol: number>
// }
// ] [deprecated v5.0.0]
}312 GetPlayerStateEvent
Roles: Host, Player, Bot
Requests all active players amount of cards on their deck.
{}313 SendPlayerStateNotification
Sends the Caller[#312] the card amounts of all active players.
{
"players": [
{
"id": <player game id: number>, [v4.0.0]
"username": <player id path: string>,
"cards": <amount: number>,
"isActivePlayer": <isActive: boolean>,
"order": <orderInGame: number> [v1.2.0]
// "id": <player public id: string>, [v2.0.0] [deprecated v4.0.0]
}
]
}314 GetPileTopEvent
Roles: Host, Player, Bot
Request the current top most card on the stack.
{}315 SendPileTopNotification
Sends the Caller[#314] the current top most card.
{
"card": <card: Card> [v5.0.0]
// "type": <card type: number> [deprecated v5.0.0],
// "symbol": <card symbol: number> [deprecated v5.0.0]
}316 GetPlayerDecisionNotification
Roles: Host, Player, Bot
Request a decision from a Player.
{
"type": <modalType: number>,
"options": <availableOptions: string[]> [v3.1.0]
}317 PlayerDecisionEvent
Roles: Host, Player, Bot
Answers a Server[#316] request.
{
"type": <decision type: number>,
"decision": <decision result (index of options): number>
}as decision type currently only numbers are supported
the interpretation of these values is handled implicitly
399 PlayerWonNotification
The Server notifies all clients that a Player has won the game - the game is finished.
{
"id": <player game id: number>, [v4.0.0]
// "wins": <player wins: number> [deprecated: v2.0.0]
// "id": <player public id: string>, [v2.0.0] [deprecated v4.0.0]
// "username": <player username: string> [deprecated v4.0.0]
"summary": [
{
"id": <player game id: number>, [v4.0.0]
"position": <gameRank: number>, // counting from 1 (1., 2., ...)
"score": <gameScore: number>
// "id": <player public id: string>, [v2.0.0] [deprecated v4.0.0]
// "username": <playerName: string>, [deprecated v4.0.0]
}
]
}Errors (4xx)
informs the (mostly) client about failed or disallowed operations
400 GeneralErrorNotification
Sent when no matching error is available.
{
"message": <message: string>
}401 MessageToLongErrorNotification
Sent when the incoming message was too long
{
"code": <error code: number>,
"message": <message: string>
}420 AccessDeniedErrorNotification
Notifies a Player that he cant perform this operation (eg. a player sends Host scoped Events)
{
"code": <error code: number>,
"message": <message: string>
}421 LobbyFullErrorNotification [1.3.0]
Notify a player that he cant join the lobby because it is full.
{
"code": <error code: number>,
"message": <message: string>
}this error is primarily used for spectator to player role changes
425 BotNameExistsErrorNotification [v2.0.0]
Notify a host that he cant create a bot because the name is already used.
{
"code": <error code: number>,
"message": <message: string>
}426 EmptyPileErrorNotification [v4.2.1]
Notify a Host that the game cannot be started caused by as misconfiguration of the game.
{
"code": <error code: number>,
"message": <display message: string>
}[reserved|not implemented] 433 EndTurnErrorNotification
434 PlaceCardErrorNotification
Notify a Player that he cant place this card.
{
"code": <error code: number>,
"message": <display message: string>
}Changelog
v1.1.0
Added
- 198 KeepAlive (Player)
- 199 AckKeepAlive (Server)
v1.2.0
Added
- 313 Added
Playerorder
v1.3.0
Added
- 421 Lobby Full Error
v1.4.0
Added
- 117 PlayerDisconnected (Server)
- 118 PlayerReconnected (Server)
v1.5.0
introduced the concept of player states
Modified
- 109 Added Player State
v2.0.0
introduced the concept of technical players
introduced the defintion of
Events,NotificationsandMessagesadded role
Botmade the ZRP offline ready
differentiate between username and player ids (to avoid username collisions)
smaller cleanup changes
Removed
winsproperty on codes 100; 101; 109; 116; 399
Modified
- 306 is now capable of sending multiple cards at once
Added
- 230-237: Bot management in games
- 425: bot name collision error
v3.0.0
Modified
- 308 changed updating player card amounts, added property for current draw amount
Added
- 303 Request End Turn
v3.1.0
Modified
- 317 player decision notification can send options
Added
- Decision Type 2 (Select Player)
v3.2.0
Modified
- 203 rules/rule editing is configured by backend
v3.3.0
Modified
- 307 is now capable of sending multiple cards at once
v4.0.0
transform username based public ids to numeric game/lobby scoped ids
reintroduce wins property
Modified
- 300 send initial game state
- 399 remove username properties
v4.1.0
Introduced the concept of UIFeedback
Modified
- 308 send feedbacks
v4.2.0
Modified
- SettingType: add option Readonly
v4.2.1
Added
- 426: empty pile error
v4.3.0
Added
- 204, 205, 206, 207, 208, 209: Game Profiles Concept
v5.0.0
This breaking change removes the concept of Game Profiles from the ZRP, adds a common card object and introduces the actual card colors and types into the protocol. Also preparing for upcoming features, the
winsproperty was renamed toscore. Overall documentation cleanup.
Removed
- GameProfileGroup
- 204, 205, 206, 207, 208, 209: Game Profiles Concept
Game Profiles are now handled via the HTTP API and are not part of the ZRP anymore
Modified:
- renamed
winsproperty toscoreon codes 100; 109, 116, 231, 237 - use
Cardtype in 300, 304, 306, 307, 308, 311, 315