# 🛸 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.