The Hacker Jeopardy Game Board we use at NorthSec.
This is what the crowd sees:
When a clue is displayed:
This is the host interface, how you control the game:
Note that there are two drawers that can be opened by clicking on the brown arrows at the top and at the bottom of the screen. The top drawer contains the functions to change team names. The bottom drawer provides functions to display a custom message on the board or to pause a game.
Starting with v0.5, Ceopardy is split in two parts:
-
A Python/Flask back-end that exposes a small REST API (
/api/v1/…) and broadcasts state changes over a single Socket.IO namespace (/game). -
A Vite + Vue 3 front-end (in
frontend/) that powers the crowd-facing viewer, the host UI, and the start screen.
You need Python, pip, virtualenv and Node.js (LTS). The tl;dr:
make venv source .venv/bin/activate # bash/zsh source .venv/bin/activate.fish # fish npm install --prefix frontend npm run build --prefix frontend python run.py
make venv creates .venv/ and installs both runtime and dev requirements.
If you use direnv, the repo ships an .envrc that puts
.venv/bin on your PATH automatically when you cd into the directory —
works in bash, zsh, and fish. Install direnv (see
upstream docs for shell hook setup),
then from the repo root:
make venv # create the venv first; direnv won't do this for you direnv allow # trust the .envrc
After that, entering the directory activates the venv and leaving deactivates
it — no manual source needed.
Then open the host view to set up the game. The players' view (also known as the viewer) can be opened at any time.
python run.py runs the built-in dev server (debug + reloader). For
production, run it under gunicorn with the eventlet worker. Socket.IO requires
a single worker process unless you also configure a Redis message queue:
pip install gunicorn gunicorn -k eventlet -w 1 -b 127.0.0.1:5000 'run:app'
Put nginx (or similar) in front for TLS and to expose it on the network — the app itself binds to localhost because the host interface has no auth.
Run Flask and Vite side by side. Vite hot-reloads the UI and proxies
/api and /socket.io to Flask.
# terminal 1 - Flask python run.py
# terminal 2 - Vite dev server npm run dev --prefix frontend
Then open http://localhost:5173/.
You need at least 2 outputs: one for the game host for control and one for the public.
At NorthSec 2017, we used 3 outputs because we didn’t have the proper gear to
duplicate the public output for a stage monitor. There is a script in
helpers/ that will set 3 outputs using xrandr. It didn’t work with a GUI
tool when we tried at that time.
Game data goes in data/. There you should add round files (create a .round
file) and questions in Questions.cp. The format is pretty self explanatory.
Check data/ for an example.
|
Note
|
In order to avoid dataloss due to a crash, Ceopardy is backed by a database where transactions are pushed when the hosts submit the points. This has the flipside requiring games to be finalized before a new one can be started. Make sure that you always push the "Game over" button before reloading to start a new game. |


