- Updated Dockerfile to Python 3.11, selective COPY for cleaner image - Expanded .gitignore with Python/OS patterns - Added config.json, questions.json, env_example, and static assets - Updated templates (host, player, scores) with Space Invaders UI - Rewrote README for SI Quiz branding and setup docs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
🛸 SI Quiz — Space Invaders Quiz
A multiplayer trivia game with a Space Invaders-style arcade twist. Players join from their phones, answer questions by shooting the correct answer with their spaceship, and compete on a live leaderboard — all projected from the host's screen.
Built with FastAPI, WebSockets, SQLite, and Docker. No external services required.
Features
- 🎮 Space Invaders mechanic — players shoot answers, not just tap buttons
- 📱 Mobile-friendly player view — join via QR code, no install needed
- 🖥️ Host panel — controls game flow, shows live answer count and ranking
- 🌐 Bilingual UI — English / Español toggle on the join screen
- 🎨 Theme switcher — Dark / Light / High Contrast (great for projection)
- 📊 Score history — persistent leaderboard across sessions
- 🏢 Department grouping — track scores by team
- ⚙️ Fully configurable — questions, org name, departments, time limit via JSON
Quick Start
git clone https://github.com/carlitosbond/si-quiz.git
cd si-quiz
# 1. Edit your questions and branding
cp config.json config.json # already provided, edit as needed
cp questions.json questions.json # already provided, customize freely
# 2. Start
docker compose up -d
# Host panel: http://localhost:8000/host
# Players join: http://localhost:8000
Configuration
config.json — branding and game settings
{
"app_name": "SI Quiz",
"app_subtitle": "Space Invaders Quiz",
"org_name": "Your Team",
"departments": ["Engineering", "Operations", "IT", "Sales", "Finance", "HR", "Other"],
"time_limit_seconds": 15,
"questions_file": "questions.json"
}
| Field | Description |
|---|---|
app_name |
Displayed in browser title and UI headers |
app_subtitle |
Tagline shown on the join screen |
org_name |
Optional org/team name shown in the host panel |
departments |
List shown in the player join dropdown |
time_limit_seconds |
Seconds per question (default: 15) |
questions.json — your question bank
Each question follows this format:
{
"q": "Question text here?",
"options": ["Answer A", "Answer B", "Answer C", "Answer D"],
"correct": 0,
"fun_fact": "Explanation shown after the answer is revealed."
}
correctis the zero-based index of the correct answer (0 = A, 1 = B, 2 = C, 3 = D)- Questions are shuffled each session
- No minimum or maximum — add as many as you want
Scoring
| Component | Points |
|---|---|
| Correct answer | 200 pts base |
| Speed bonus | Up to +800 pts (scales with remaining time) |
| Wrong / no answer | 0 pts |
| Max per question | 1,000 pts |
Reverse Proxy (Caddy)
If you're running behind Caddy, do not add encode gzip — it breaks the WebSocket upgrade.
si-quiz.yourdomain.com {
reverse_proxy si-quiz:8000
}
Connect the container to your Caddy network:
# In docker-compose.yml, under the si-quiz service:
networks:
- si-quiz-net
- web-net # your Caddy shared network
Environment Variables
Copy .env.example to .env to override defaults:
| Variable | Default | Description |
|---|---|---|
DB_PATH |
/data/si-quiz.db |
SQLite database path (inside container) |
CONFIG_PATH |
config.json |
Path to config file |
QUESTIONS_PATH |
questions.json |
Path to questions file |
Project Structure
si-quiz/
├── main.py # FastAPI backend + WebSocket game logic
├── config.json # Branding, departments, time limit
├── questions.json # Your question bank
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
├── .env.example
├── templates/
│ ├── player.html # Mobile player view (Space Invaders game)
│ ├── host.html # Host control panel
│ └── scores.html # Score history viewer
└── static/ # CSS, JS assets (add music.mp3 here if desired)
Background Music (optional)
The player view supports background music. Add a file named music.mp3 to the static/ folder — it will play automatically when a player joins and stop at the podium screen. Volume is set to 20%.
Music is not included in this repo. Bring your own royalty-free track.
License
MIT — use it, fork it, adapt it for your team.