# 🛸 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 ```bash 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 ```json { "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: ```json { "q": "Question text here?", "options": ["Answer A", "Answer B", "Answer C", "Answer D"], "correct": 0, "fun_fact": "Explanation shown after the answer is revealed." } ``` - `correct` is 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: ```yaml # 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.