This is a basic web app (server + client) that provides a buzzer and message display for ad-hoc multiplayer games.
This app was built in a hurry and is very much prototype-quality code. There are no tests. There is no automation. Caveat emptor. Here be dragons.
Also, much of this app was "vibe coded" with LLM assistance. A great deal of the machine-generated code ran fine as provided, but it made many mistakes and undesired changes, frequently needing manual fixes and adjustments, especially later in development as the behaviors grew more complex. So, this wasn't strictly "vibe coded". More like "vibe pair programmed" to get the basic framework and base features operational before I took over adding fixes and enhancements directly.
I deliberately included none in this repo because I cannot verify that the files I sourced are safe for redistribution with this code. I leave this as an exercise to the reader.
uv sync
HOST_SECRET=your-host-password uv run uvicorn main:app --reload --host 0.0.0.0
Then open http://0.0.0.0:8000 in your local web browser.
How I quickly built locally and shipped to my remote server. Should work with either docker or podman.
Local dev system:
docker build -t localhost/buzzer:latest -f Containerfile . && \
docker save localhost/buzzer:latest | gzip > /tmp/buzzer.tar.gz && \
scp /tmp/buzzer.tar.gz username@my-remote-server:~/
Remote server:
docker kill buzzer; docker rmi localhost/buzzer:latest; \
gunzip -c ~/buzzer.tar.gz | docker load && \
docker run --rm -d --name buzzer -p 8083:8000/tcp -e HOST_SECRET=my-secret localhost/buzzer:latest
The app should then be running on the remove server's port 8083. I wrapped this with an nginx config like this so nginx would serve the static assets and uvicorn/fast-api would only serve the game html and web sockets:
server {
server_name buzzer.my-remote-server;
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
location /static {
alias /path/to/buzzer/static/;
}
location / {
include proxy_params;
proxy_pass http://127.0.0.1:8083;
}
location /ws {
include proxy_params;
proxy_http_version 1.1; # WebSockets require HTTP/1.1
proxy_set_header Upgrade $http_upgrade; # WebSocket handshake upgrade
proxy_set_header Connection "Upgrade"; # WebSocket upgraed connection
proxy_buffering off; # required for real-time data
proxy_pass http://127.0.0.1:8083;
}
}
You may also need to update your server's DNS settings and update Nginx's SSL certificates to support this new subdomain, or just rewrite that to work from a path on an existing domain.