# Trivia Mayhem

Two machines, one build process.

- **Generator machine** (desktop / laptop): makes game bundles.
- **Player machine** (Odroid or any Linux PC on the Opal router): runs the show.

Workflow: build a show on the desktop → USB-copy one `export_NNN/`
folder → drop it into the player.

---

## How to install

Installation is a two-step flow. You **build a bundle here** on your
dev machine, then **carry two files** to the target and run the
installer there.

### 1. Build the bundle (on your dev machine)

```bash
cd trivia-final
./install.sh
```

It asks whether you want to build the **Generators** or the **Player**
bundle. The output goes to `dist/`:

- Generators: `dist/trivia-generators.zip` + `dist/install-generators.sh`
- Player:     `dist/trivia-player.zip` + `dist/install-player.sh`

### 2. Install on the target

Copy both files (`.zip` + `install-*.sh`) to the target, side by side,
then:

```bash
chmod +x install-*.sh
./install-*.sh
```

Nothing else is needed on the target — the installer unzips and does
the rest (apt, docker, desktop icons, kiosk autostart, Opal push, etc.).

---

## Bundle layout

```
trivia-final/
├── install.sh          bundle builder (this is what you run here)
├── installers/         target-side installers (carried with the zip)
│   ├── install-generators.sh
│   └── install-player.sh
├── generators/         source material — tkinter builders + templates + assets
├── player/             source material — Flask / WS / nginx + config + opal + odroid
└── data/
    ├── obsidian/       notes seed (bundled with the generator install)
    └── exports/        empty placeholder — generator-side layout reference
```

The generator machine and the player machine are **two separate
computers**, each with its own `data/` tree. No network share, no
sync — only a USB stick carrying one `export_NNN/` folder at a time.

---

## Generators — what you get after install

Default install dir: `~/trivia` (override: `TRIVIA_HOME=/path`).

Four desktop icons appear after install:

- **Trivia — S3A**, **Trivia — MC4**, **Trivia — 50 50**, **Trivia — MasterBuilder**

Usage:

1. Double-click S3A / MC4 / 50-50 → pick an obsidian note → build one
   game. Output lands in `~/trivia/games/<slug>/`.
2. Open **MasterBuilder** → pick games for the show → export. Bundle
   lands in `~/trivia/data/exports/export_NNN/`.
3. Paste your Anthropic API key in the AI panel once (persists inside
   the generator UI).

Layout after install:

```
~/trivia/
├── generators/     tkinter scripts
├── assets/         fonts, stock audio, stock images
├── games/          S3A / MC4 / 50-50 output — one folder per individual game
├── data/
│   ├── obsidian/   notes (seeded + anything you add)
│   └── exports/    MasterBuilder export_NNN bundles (what you USB-copy to player)
└── .venv/
```

---

## Player — what you get after install

Default install dir: `/opt/trivia-player`.

Flags (optional, set before running `./install-player.sh`):

| Flag           | Default                     | Purpose                                                        |
|----------------|-----------------------------|----------------------------------------------------------------|
| `TRIVIA_HOME`  | `/opt/trivia-player`        | Install dir                                                    |
| `SKIP_KIOSK`   | `0`                         | `1` = skip kiosk autostart (testing on a dev box)              |
| `SKIP_DOCKER`  | `0`                         | `1` = skip Docker install + container bring-up                 |
| `SKIP_WIFI`    | `0`                         | `1` = skip RTL8821CU/8822BU WiFi drivers + static-IP netplan   |
| `SKIP_OPAL`    | `0`                         | `1` = skip Opal init + push (used by remote-deploy strategy)   |
| `OPAL_ONLY`    | `0`                         | `1` = run ONLY Opal init + push (mutually exclusive with `SKIP_OPAL`); implies the three other SKIP flags |
| `OPAL_FORCE`   | `0`                         | `1` = force re-deploy on Opal even if already configured       |
| `PLAYER_MAC`   | (auto-detected)             | Override the MAC pinned in trustedmac+DHCP lease (used by remote deploy) |
| `OPAL_PASS_ENV`| (none)                      | Pre-set Opal admin password (skips first-boot prompt)          |

Hardcoded (no flags): Opal IP `192.168.8.1`, Opal SSH user `root`,
kiosk URL `http://localhost/operator`. The Opal host key is
auto-accepted (no y/n prompt).

Interactive: the installer prompts only for the Opal SSH **password** at
the Opal push step.

What happens on install:

1. Docker Engine + Compose plugin installed, daemon enabled at boot.
   `restart: always` in the compose file keeps the stack up across
   reboots.
2. Zip extracted, stack copied to `TRIVIA_HOME`, `docker compose up -d`.
3. Chromium kiosk autostart dropped in `~/.config/autostart/` (unless
   `SKIP_KIOSK=1`).
4. `opal/` pushed via SSH to the Opal and `setup.sh` run there.
   Fully self-contained — no Opal internet required. Installs
   **nodogsplash2** from bundled `.ipk`s (GL.iNet `mips_siflower`
   target), sets SSID `Trivia Mayhem` (open — no password), pins the
   player's MAC to `192.168.8.100` via static DHCP lease (auto-detected
   from the install host's Opal-facing interface), and deploys the
   captive-portal splash + firewall rules.
   **Install aborts if the Opal is unreachable.**

Ports: **80** (nginx → all UIs), **5000** (Flask internal), **8765**
(WebSocket).

Manual ops after install:

```bash
cd /opt/trivia-player
docker compose ps
docker compose logs -f
docker compose restart
docker compose down
docker compose up -d
```

---

## Transferring a show: generator → USB → player

The two machines are isolated. You physically carry each show across.
`export_NNN/` is self-contained (every game + `START.html` entry).

```bash
# 1. Generator machine — copy the export onto a USB stick.
cp -r ~/trivia/data/exports/export_NNN /media/$USER/<stick>/

# 2. Player machine — drop the folder into the player's exports dir.
sudo cp -r /media/$USER/<stick>/export_NNN /opt/trivia-player/data/exports/
sudo chown -R $USER:$USER /opt/trivia-player/data/exports/export_NNN
```

Docker picks it up immediately (`./data/exports` on the host →
`/data/exports` inside the container). The operator screen lists the
new show automatically.
