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 theClient
and theServer
, either aEvent
orNotification
, can consist of multiple WebSocket framesEvent
: a message sent from aPlayer
orSpectator
to theServer
Notification
: a message sent from theServer
to aPlayer
orSpectator
GameEvent
: a domain specific event, like a player joined the game emitted by theServer
. This will be translated into a ZRPNotification
and 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
Player
order
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
,Notifications
andMessages
added role
Bot
made the ZRP offline ready
differentiate between username and player ids (to avoid username collisions)
smaller cleanup changes
Removed
wins
property 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
wins
property 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
wins
property toscore
on codes 100; 109, 116, 231, 237 - use
Card
type in 300, 304, 306, 307, 308, 311, 315