WebSocket Protocol
The communication between the frontend (JS) and backend (Python) happens via JSON messages over WebSockets.
Endpoint: ws://<HOST>/ws/game/<ROOM_CODE>/
Client -> Server (Actions)
These messages are sent by the Frontend (Host or Player). Every message must have an action key.
Player Actions
| Action | Payload | Description |
|---|---|---|
join | {nickname: "Name", token: "UUID"} | Authenticates a player. Token is optional (for reconnects). |
answer | {option: "A"} | Submits an answer (A, B, C, or D). |
check_rejoin | {token: "UUID", code: "ABCD"} | valid whether a token is still valid for a room. |
remove_old_player | {token: "UUID"} | Explicitly disconnects an old session before a new join. |
Game Master Actions
| Action | Payload | Description |
|---|---|---|
start_game | {} | Starts the first question of the quiz. |
next_question | {} | Advances to the next question. |
previous_question | {} | Go back one question. |
time_up | {} | Force stops the timer and reveals the result. |
control_timer | {command: "pause"} | Options: pause, resume, stop, add_10s, sub_10s. |
kick_player | {nickname: "User"} | Removes a player from the session. |
switch_quiz | {quiz_id: 1, reset_scores: true} | Injects a new quiz into the session. |
terminate_session | {} | Destroys the lobby and data. |
rename_player | {id: 123, new_name: "Name"} | Renames a player instantly. |
toggle_exclusion | {player_id: 1, question_id: 2, compensate: true, message: "..."} | Excludes a player from a specific question. |
change_room_code | {new_code: "ABCD"} | Changes the room code on the fly. |
trigger_lobby_results | {} | Shows the results screen while in the lobby. |
(See consumers.py for the full list of supported actions)
Server -> Client (Events)
These messages are broadcasted to connected clients. The type key indicates the event.
Global Events
| Type | Data | Description |
|---|---|---|
new_question | {question: {...}} | Displays a new question. Contains text, options, and duration. |
show_result | {correct_option: "A"} | Sent when time is up. Reveals the answer. |
game_over | {leaderboard: [...], is_intermediate: bool} | Sent when quiz ends. Shows final or intermediate rankings. |
timer_control | {command: "pause"} | Syncs timer state across devices. |
player_joined | {nickname: "Name"} | Sent to Host when a new player connects. |
player_kicked | {nickname: "Name"} | Sent when a player is forced out. |
player_renamed | {old_name: "A", new_name: "B"} | Sent when a player is renamed by GM. |
game_reset | {message: "..."} | Sent when the quiz or session is reset. |
room_moved | {new_code: "ABCD"} | Sent when the room code changes. |
session_terminated | {} | Redirects all users to the "Ended" screen. |
Private Events (Sent to specific socket)
| Type | Data | Description |
|---|---|---|
join_confirmed | {token: "UUID", ...} | Sent to player upon successful login. |
player_excluded | {message: "..."} | Sent if the player is excluded from the current question. |
answer_confirm | {option: "A"} | Confirms that the server received the answer. |
error | {message: "..."} | Sent if an action failed (e.g., room full). |