RollTheDice is a lightweight multiplayer dice game with a FastAPI backend and a static HTML/CSS/JS frontend. It supports single-player, 2-player, 3-player, 2v2 team games, Hardcore mode, chat, emoji reactions, leaderboards, and read-only replay views for completed games.
- Responsive lobby and game room
- REST API for lobby, games, leaderboard, and replay data
- WebSocket game room for rolling, scoring, chat, spectators, and corrections
- Persistent leaderboards and stats in
./data - User accounts, admin management, public profiles, search, and player rankings
- Audited permanent deletion of invalid completed games with automatic statistic updates
- Self-registration from the lobby with immutable usernames
- Personal statistics split into Normal, Hardcore, and overall results
- Progressive Web App support via manifest and service worker
- Docker Compose setup for local machines, servers, and Raspberry Pi
- Docker with the Compose plugin
- Git, if cloning from GitHub
- Optional for local development: Python 3.12+ or 3.13 with the packages from
requirements.txt
git clone https://github.com/Maetran/RollTheDice.git
cd RollTheDice
docker compose up -d --buildFor the first administrator, copy .env.example to .env, set a temporary
username and password, and start the container. There is no default admin
password. After the first successful login, remove
ROLLTHEDICE_ADMIN_PASSWORD from .env. Set
ROLLTHEDICE_COOKIE_SECURE=1 for a public HTTPS deployment.
Self-registration is protected by persistent SQLite rate limits without any
extra service. For a public deployment, create a Cloudflare Turnstile widget
for the production hostname and set both ROLLTHEDICE_TURNSTILE_SITE_KEY and
ROLLTHEDICE_TURNSTILE_SECRET in .env. Local development leaves both values
empty and does not show a CAPTCHA. A partial Turnstile configuration is rejected
at startup so registration cannot silently run with broken protection.
Open:
- Lobby:
http://localhost:8000/ - API docs:
http://localhost:8000/docs
On a server or Raspberry Pi, replace localhost with the device IP.
git pull
docker compose up -d --buildGame data is stored in ./data and is preserved across rebuilds.
Production deployment details, including the IONOS SSH target and mandatory
leaderboard backup rules, are documented in docs/DEPLOYMENT.md. Use
scripts/deploy_zdwa.sh for the guarded production deploy.
python3 -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt
uvicorn app.main:app --host 127.0.0.1 --port 8000Install requirements-dev.txt when running the HTTP integration tests.
Useful checks:
python3 -m py_compile app/main.py app/rules.py
node --check app/static/scoreboard.js
node --input-type=module --check < app/static/room.js
python3 -m unittest discover -s tests -p 'test_*.py'
npm run test:browser
git diff --checkRollTheDice/
├── Dockerfile
├── docker-compose.yml
├── manifest.webmanifest
├── requirements.txt
├── app/
│ ├── __init__.py
│ ├── main.py # FastAPI routes, WebSocket game loop, lobby and leaderboard state
│ ├── models.py # User, session, completed-game, and participant models
│ ├── database.py # Database configuration and Alembic upgrades
│ ├── auth.py # Password, session, and role logic
│ ├── api_auth.py # Login, password, and admin-user API
│ ├── api_users.py # Profiles, stats, search, ranking, and assignments
│ ├── game_history.py # Complete results and legacy JSON import
│ ├── rules.py # Server-side subtotal and total calculations
│ └── static/
│ ├── index.html # Lobby
│ ├── room.html # Game room shell
│ ├── game_view.html # Read-only leaderboard replay view
│ ├── rules.html # Player-facing game rules
│ ├── chat.js # Chat client
│ ├── emoji.js # Emoji reactions
│ ├── room.js # Game room WebSocket client
│ ├── scoreboard.js # Scoreboard renderer and read-only replay renderer
│ ├── style.css # Shared styling
│ ├── sw.js # Service worker
│ ├── favicon.svg
│ └── icons/
└── data/ # Persistent runtime data, ignored by Git
├── leaderboard_recent.json
├── leaderboard_alltime.json
├── stats.json
└── rollthedice.sqlite3 # Accounts, sessions, and complete new game history
The application writes leaderboard JSON files and its SQLite database to
./data. Copy the complete directory only while the container is stopped; the
deployment script handles this automatically. Existing JSON snapshots are
imported idempotently by game_id. Historical user statistics can only include
the snapshots that still exist in the capped legacy lists.
docker build -t rollthedice .
docker run -d --name rollthedice --restart=unless-stopped \
-p 8000:8000 \
-v "$(pwd)/data:/app/data" \
rollthedice