Categorygithub.com/quibbble/quibbble-controller
repository
0.0.0-20241203024510-b02e21813d82
Repository: https://github.com/quibbble/quibbble-controller.git
Documentation: pkg.go.dev

# Packages

No description provided by the author
No description provided by the author
No description provided by the author

# README

Quibbble K8s Controller

The project allows Quibbble games to be run in a K8s cluster. Games are spun up as individual pods with their entire lifecycle handled by the Quibbble controller. This allows Quibbble to take advantage of the power of K8s, primarily the ability to scale as well as to seperate and self heal in the event of any single game failure.

Quick Start

Install NGINX

This controller currently requires the usage of NGINX to allow for dynamic routing of games. Meaning that if a game with key tictactoe and id example is created, then NGINX will handle the routing to that game over path /game/tictactoe/example.

helm upgrade --install ingress-nginx ingress-nginx \
    --repo https://kubernetes.github.io/ingress-nginx \
    --namespace ingress-nginx --create-namespace

Install Quibbble Controller

helm upgrade --install quibbble-controller quibbble-controller \
    --repo https://quibbble.github.io/quibbble-controller \
    --namespace quibbble --create-namespace

Contributing

All contributions are welcome. To get started take a look at additional docs on setting up a local environment.

Supported Games

Architecture

There are three main processes in this system.

  1. controller - Processes game create and delete requests.
  2. watcher - Periodically searches for and cleans up stale games.
  3. server - Runs a game instance.

Flows

Game Creation

  • Send POST https://<host>/game with some qqn such as [key "tictactoe"][id "example"][teams "red, blue"].
  • controller processes the request and, if valid, creates K8s ConfigMap, Pod, Service, and Ingress resources.
  • Game can now be accessed at https://<host>/game/tictactoe/example.

Game Connection

  • Join a game by connection to wss://<host>/game/tictactoe/example?name=<name> with websockets.
  • Connection should be open to a server instance and relevant game messages should be recieved.

Game Cleanup

  • watcher will kick off every X timeperiod.
  • Job requests data from all live games by calling GET https://<host>/game/<key>/<id>/activity for each game.
  • If there are no connected players and no recent updates then all K8s related resources are deleted.

REST API

POST /game (create a game)
Parameters
nametypedata typedescription
NonerequiredQGNQGN descibing the game to create
Responses
http codecontent-typeresponse
201text/plain;charset=UTF-8Created
400text/plain;charset=UTF-8Bad Request
409text/plain;charset=UTF-8Conflict
500text/plain;charset=UTF-8Internal Server Error
503text/plain;charset=UTF-8Service Unavailable
Example cURL
 curl -X POST -H "Content-Type: application/qgn" --data @post.qgn https://api.quibbble.com/game
PUT /game (load a game from storage)
Parameters
nametypedata typedescription
keyrequiredstringThe name of the game i.e. tictactoe or connect4
idrequiredstringThe unique id of the game instance to join
Responses
http codecontent-typeresponse
200text/plain;charset=UTF-8OK
400text/plain;charset=UTF-8Bad Request
404text/plain;charset=UTF-8Not Found
500text/plain;charset=UTF-8Internal Server Error
503text/plain;charset=UTF-8Service Unavailable
Example cURL
 curl -X PUT https://api.quibbble.com/game?key={key}&id={id}
DELETE /game?key={key}&id={id} (delete a game)
Parameters
nametypedata typedescription
keyrequiredstringThe name of the game i.e. tictactoe or connect4
idrequiredstringThe unique id of the game instance to join
Responses
http codecontent-typeresponse
200text/plain;charset=UTF-8OK
400text/plain;charset=UTF-8Bad Request
404text/plain;charset=UTF-8Not Found
500text/plain;charset=UTF-8Internal Server Error
Example cURL
 curl -X DELETE https://api.quibbble.com/game?key={key}&id={id}
WEBSOCKET /game/{key}/{id}?name={name} (connect to a game)
Parameters
nametypedata typedescription
keyrequiredstringThe name of the game i.e. tictactoe or connect4
idrequiredstringThe unique id of the game instance to join
namerequiredstringThe name of the player connecting
Responses

None

Example wscat
 wscat -c wss://api.quibbble.com/game/{key}/{id}
GET /game/{key}/{id}/snapshot?format={format} (get game snapshot)
Parameters
nametypedata typedescription
keyrequiredstringThe name of the game i.e. tictactoe or connect4
idrequiredstringThe unique id of the game instance to join
formatrequiredone of json or qgnThe type of data to return
Responses
http codecontent-typeresponse
200application/json or application/qgnJSON or QGN
400text/plain;charset=UTF-8Bad Request
404text/plain;charset=UTF-8Not Found
500text/plain;charset=UTF-8Internal Server Error
Example cURL
 curl -X GET https://api.quibbble.com/game/{key}/{id}/snapshot?format=json
GET /game/activity (get all games activity)
Parameters

None

Responses
http codecontent-typeresponse
200application/jsonActivity for all games
500text/plain;charset=UTF-8Internal Server Error
Example cURL
 curl -X GET https://api.quibbble.com/game/activity
GET /game/{key}/{id}/activity (get game activity)
Parameters
nametypedata typedescription
keyrequiredstringThe name of the game i.e. tictactoe or connect4
idrequiredstringThe unique id of the game instance to join
Responses
http codecontent-typeresponse
200application/jsonJSON data describing player count and last update time
404text/plain;charset=UTF-8Not Found
Example cURL
 curl -X GET https://api.quibbble.com/game/{key}/{id}/activity

Websocket Messaging

Sendable Messages

join (join a team)
Join
{
    "type": "join",
    "details": "$TEAM"
}
action (perform a game action)
Message
{
    "type": "$ACTION",
    "details": {...}
}
ai (ai plays for the current team)
Message
{
    "type": "ai",
}
chat (send a chat message)
Message
{
    "type": "chat",
    "details": "$MESSAGE"
}

Recievable Messages

snapshot (retrieve a snapshot of the game)
Details

Message sent to all players on every game state change.

Message
{
    "type": "snapshot",
    "details": {...}
}
connection (retrieve player connection information)
Details

Message sent to all players on every player connection, drop, or team change.

Message
{
    "type": "connection",
    "details": {
        "$NAME1": "$TEAM1",
        "$NAME2": "$TEAM2",
        "$NAME3": null
    }
}
chat (retrieve chat message)
Details

Message sent to all players on every sent chat message.

Message
{
    "type": "chat",
    "details": {
        "name": "$NAME",
        "team": "$TEAM",
        "message": "$MESSAGE",
    }
}
error (retrieve error message)
Details

Message sent to origin player on failed action message.

Message
{
    "type": "error",
    "details": "$MESSAGE"
}