-
Notifications
You must be signed in to change notification settings - Fork 199
API Docs
The scribble.rs API consists of an HTTP interface and a WebSocket interface. The HTTP interface has two usecases. One being the server side rendered parts of the official web client and the other the REST-API usable by external applications.
All paths in the internal API start with ssr and resemble method names seen in programming.
The public HTTP offers two endpoints. One for creating a lobby and one for joining it.
This method creates a new lobby.
Parameters
| Query Parameter | Description | Type |
|---|---|---|
| username | Determines the username displayed ingame. If the name is too long, it gets trimmed. | A string of a length from 1 to 30. |
| language | Selects the word set used in the lobby. | One of english, italian or german, french, dutch. |
| max_players | Determines the maximum amount of people that can join | An integral number between 2 and 24. |
| drawing_time | Determines the amount of seconds that a player has time to choose a word. | An integral number between 60 and 300
|
| rounds | Amount of rounds that the game takes to complete. | An integral number between 1 and 20. |
| custom_words | Custom words to use instead of or on top of the word set. | A comma separated list of words. The words can contain any characters. |
| custom_words_chance | Determines how often the custom word pool gets accessed. | An integral number between 1 and 100. |
| enable_votekick | Decides whether players can kick each other by voting. | Either true or false. |
| clients_per_ip_limit | Decides how many players can have the same IP in one lobby. | An integral number between 1 and 24. |
| public | Decides whether this lobby is published on the lobby list. |
Answer
As a result you get a JSON object containing the following:
| Name | Value |
|---|---|
| lobbyId | ID of the newly created Lobby. |
| drawingBoardBaseWidth | The unscaled width of canvas in order to scale drawing instructions. |
| drawingBoardBaseHeight | The unscaled height of canvas in order to scale drawing instructions. |
On top of that the cookie usersession gets set.
Header
Entering a lobby as an existing player (rejoining) requires the header value usersession to be set to your previous user session value.
The lobby_id parameter must be set in the URI with a valid UUID returned by the API previously.
Query Parameters
| Name | Description | Type |
|---|---|---|
| lobby_id | Determines which lobby to join. | A valid UUID returned by the API previously. |
| username | Determines the username if no usersession was supplied | A string with a length between 1 and 30. |
Answer
As a result you get a JSON object containing the following:
| Name | Value |
|---|---|
| lobbyId | ID of the newly created Lobby. |
| drawingBoardBaseWidth | The unscaled width of canvas in order to scale drawing instructions. |
| drawingBoardBaseHeight | The unscaled height of canvas in order to scale drawing instructions. |
On top of that the cookie usersession gets set.
This endpoint establishes the WebSocket connection necessary for all major game functionality.
Header
This endpoint requires a valid user session in the usersession field of the header.
Paramters
All parameters must be set in the URI.
| Name | Description | Type |
|---|---|---|
| lobby_id | ID of the lobby to establish a websocket connection for. | A valid UUID previously sent by the API. |
The websocket API is required for all major game functionality such as receiving relevant events, drawing and guessing.
Each wordhint represents a letter of the currently chosen word. A word hint object looks like this:
| Name | Description |
|---|---|
| character | The character hinted or 0 if this character has not been revealed |
| underline | An indication whether this character should be displayed as underlined. Indicating that it is relevant for the word. Characters such as -, _ or should always be displayed.`. |
A player contains the following fields:
| Name | Description |
|---|---|
| id | The internal ID of this player. |
| name | The display name of this player. |
| score | The current score for this game. |
| connected | Whether the player is currently connected or disconnected. |
| lastScore | The score received last turn. An integral number between 0 and 0+. |
| rank | How the player currently ranks in comparison to other players score. |
| state | One of the following: guessing, drawing or standby. |
This represents the usage of the fill bucket on the canvas.
| Name | Description |
|---|---|
| x | The unscaled X coordinate on the canvas. |
| y | The unscaled Y coordinate on the canvas. |
| color | The color which to fill with. This is in the format #rrggbb. |
This represents a line drawn by a player.
| Name | Description |
|---|---|
| fromX | The unscaled X coordinate on the canvas where the line starts. |
| fromY | The unscaled Y coordinate on the canvas where the line starts. |
| toX | The unscaled X coordinate on the canvas where the line ends. |
| toY | The unscaled Y coordinate on the canvas where the line ends |
| color | The color which to draw the line with. This is in the format #rrggbb. |
| lineWidth | The thickness of the line. |
All events generally contain two fields on the root level. The type, determining the kind of the event and the data field, which content can be determined depending on the type field. There might also be events where the data field is empty.
The ready event sends you all relevant data right after the connection has been established.
| Name | Description |
|---|---|
| playerId | Your own player ID. |
| allowDrawing | A boolean indicating whether you are currently drawing. |
| votekickEnabled | Decides whether players can vote to kick others. |
| ownerId | ID of the player that owns the lobby (mostly the creator). |
| round | The current round (progression) of the lobby. |
| maxRound | The round after which the game ends. |
| roundEndTime | Amount of milliseconds before the current round runs out. |
| wordHints | An array of word hints. If these are not available or empty, it indicates that no word has been chosen. The order needs to be respected. |
| players | A list of all players in this lobby. |
| currentDrawing | An array of fill and line instructions in order to redraw what has been drawn before joining. If this field is not available or empty, ignore it, since nothing has been drawn. |
| gameState | One of: unstarted,gameOver or ongoing |
This event is basically a smaller version of the ready event and only contains the fields roundEndTime, players and round.
This event gives you an updated list of the currently participating players. This also contains disconnected players. The objects are of type Player.
This event is a personalized event and contains the word hints that you are allowed to see. It's an array of sorted word hints. The objects are of type Wordhint
This represents a message by a player that is not drawing and hasn't finished guessing. It contains the fields author and content, which are both strings.
This represents a message sent by a player that has either already guessed the word, or is the one who's been drawing it. Just like message, it contains an author field and a content field.
This represents a chat-message sent by the backend. The data field of the event contains the message content as a string.
See Line.
See Fill.
This event is received after sending the request-drawing event.
The return value is an array containing line and fill events that have to be applied to the canvas in order.
This event signals that the player that is currently drawing has cleared the canvas.
This event signals that it's not your turn to choose and draw a word. As soon as you received this event, you can send a [choose-word](#Choose word) event, after which you can start sending line and fill events.
Sent if any player guesses the word correctly. The event data is simply the players id.
This event is used to signal that one or more player wishes to kick another player from the lobby.
| Name | Description |
|---|---|
| playerId | Player to potentially kick. |
| playerName | The players name (convenience field) |
| voteCount | How many players currently wish to kick the player. |
| requiredVoteCount | How many votes are overall necessary to kick the player. |
If voteCount is bigger than or equal to requiredVoteCount, the player will get kicked and the event should be treated as such. A full player list update will be sent either way.
The start event contains no data-field and can only be sent by the lobby owner. Whether you are the owner or not can be found out by comparing your own ID to the owners ID. You receive both in the ready object.
The sendable drawing events are the same as the as the ones you receive. Meaning clear-drawing-board, line and fill.
This event will select the current word for the lobby. It can only be send by the lobbies drawer.
It expects the word to be selected by the index of the words presented in the your-turn event. The index starts at 0.
Example
socket.send(JSON.stringify({
type: "choose-word",
data: 0
}));This event allows you to change your own display name. In the web client, this name will be persisted in your browser in form of a cookie, so that upon the next connection, the server automatically reuses your previous name. The data field has to be your desired name.
Depending on your input, the server might manipulate your name. Names longer than 30 characters are truncated.
By passing an empty string in the data field, you can reset your name to a random pet name.
Valid control character sequences, such as <b> are escaped and might therefore internally increase the length of your name.
Example
socket.send(JSON.stringify({
type: "name-change",
data: "Kevin"
}));socket.send(JSON.stringify({
type: "name-change",
data: ""
}));This event can be sent if for some reason the drawing data on the client has been lost.
The data field can be left empty. The drawing will be sent in form of the drawing event.
This allows you to cast your vote in favour of kicking a fellow player.
The data field has to be filled with the targets playerId.
Example
socket.send(JSON.stringify({
type: "vote-kick",
data: "713efb69-95f2-4532-a093-ee37f100d0bf"
}));Here's a little example written in Go. It creates a new lobby and establishes a websocket connection.
package main
import (
"encoding/json"
"io/ioutil"
"log"
"net/http"
"net/url"
"github.com/gorilla/websocket"
)
type LobbyData struct {
LobbyID string `json:"lobbyId"`
DrawingBoardBaseWidth int `json:"drawingBoardBaseWidth"`
DrawingBoardBaseHeight int `json:"drawingBoardBaseHeight"`
}
func main() {
//This example doesn't do error handling!
//Create new lobby. This will return the ID of the newly created lobby.
r, _ := http.PostForm("http://localhost:8080/v1/lobby", url.Values{
"username": {"Marcel"},
"language": {"english"},
"max_players": {"24"},
"drawing_time": {"120"},
"rounds": {"5"},
"custom_words_chance": {"50"},
"enable_votekick": {"true"},
"clients_per_ip_limit": {"1"},
})
rawData, _ := ioutil.ReadAll(r.Body)
lobbyData := &LobbyData{}
json.Unmarshal(rawData, lobbyData)
//The usersession gets stored in a cookie
userSession := r.Cookies()[0].Value
log.Println("Created lobby: " + lobbyData.LobbyID)
log.Println("Usersession: " + userSession)
//Connecting the socket by setting the Usersession and dialing.
u := &url.URL{Scheme: "ws", Host: "localhost:8080", Path: "/v1/ws", RawQuery: "lobby_id=" + lobbyData.LobbyID}
header := make(http.Header)
header["Usersession"] = []string{userSession}
socketConnection, _, _ := websocket.DefaultDialer.Dial(u.String(), header)
defer socketConnection.Close()
//Do stuff with connection ...
}