# Apogee Game Catalog

All games live in a flat namespace. To launch a game, pass its `id` as `gameId` in `POST /v1/sessions`. New games are additive — existing integrations continue to work.

**Game artwork:** every game ships with a 1600×900 SVG hero image (under [`../assets/games/`](../assets/games/)) that you can drop straight into your lobby cards, marketing pages, or press kits. The full set is bundled in the "Press Kit" zip download from **Admin → Docs → ⬇ Download all**.

## Launch paths

Each game has its own HTML bundle. **Do not hardcode any launch path in client code.** The single source of truth is `apps/api/server.js::GAMES[].launchPath` — every consumer derives from it via one of two endpoints:

### 1. Programmatic callers — `GET /v1/launch` (JSON)

Operator lobbies, the admin panel, tests. Returns `{launchUrl, sessionToken, ...}`:

```bash
curl -H 'Accept: application/json' \
  'https://api.apogeetech.net/v1/launch?gameId=contrail&merchant=mrc_demo&currency=EUR&balance=10000'
# → { "launchUrl": "https://apogeetech.net/contrail.html?merchant=...&sess=...", ... }
```

### 2. Browser redirects — `GET /v1/launch` (302 to HTML)

Bare-domain URLs like `https://apogeetech.net/?gameId=contrail&...`. The landing page's inline script delegates to `/v1/launch?...&redirect=1` which returns a 302 Location header straight to the right bundle:

```
GET /v1/launch?gameId=contrail&merchant=mrc_demo&redirect=1
→ HTTP/1.1 302 Found
→ Location: https://apogeetech.net/contrail.html?merchant=mrc_demo&sess=sess_...
→ X-Apogee-Game: contrail
```

Browsers follow the 302 transparently — URL bar lands on the correct bundle, no flash, no client-side table to drift.

**Both `/` and `/play.html`** carry an inline cross-game forwarder, so all three of these resolve to the same Contrail session:

```
https://apogeetech.net/?gameId=contrail&merchant=mrc_demo&player=p1&sess=…
https://apogeetech.net/play.html?gameId=contrail&merchant=mrc_demo&player=p1&sess=…
https://apogeetech.net/contrail.html?merchant=mrc_demo&player=p1&sess=…
```

The canonical form operators should use is the first one — the bare domain with `?gameId=`. `play.html` also forwards correctly but only as a safety net for legacy integrations that already hardcoded that path. See [INTEGRATION-PITFALLS.md §31](./INTEGRATION-PITFALLS.md#31-wrong-launch-path-for-multi-bundle-games--fixed-2026-04-12).

### Current paths (for reference only — do not hardcode)

| Game ID | Bundle | Transport |
|---|---|---|
| `skyward` | `/play.html?gameId=skyward` | HTTP wallet via apogee-api |
| `thermal` | `/thermal.html?gameId=thermal` | HTTP wallet via apogee-api |
| `contrail` | `/contrail.html` | WebSocket to `apogee-contrail` |
| `apogeehot5` | `/apogeehot5.html?gameId=apogeehot5` | HTTP `/spin` via `apogee-slots` |
| `safariapogee` | `/safariapogee.html?gameId=safariapogee` | HTTP `/spin` via `apogee-slots` |
| `foxyapogee` | `/foxyapogee.html?gameId=foxyapogee` | HTTP `/spin` via `apogee-slots` |
| `hormuz` | `/hormuz.html?gameId=hormuz` | HTTP `/hormuz/round/*` via `apogee-hormuz` |
| `apex` | `/apex.html?gameId=apex` | HTTP `/apex/*` via `apogee-apex` |

These values live in `apps/api/server.js::GAMES[]` and are updated **only** there. If you need them at runtime on the client side, call `GET /v1/games` — it returns the full catalog including `launchPath`.

### Adding a new game

Exactly one place to touch for launch routing: `apps/api/server.js::GAMES[]`. Add an entry with a unique `id` + `launchPath` (and the other metadata fields), and:

1. `/v1/launch?gameId=<new>` will 302 to the right bundle
2. `https://apogeetech.net/?gameId=<new>` will 302 through `/v1/launch`
3. The admin Integration "Try launch" button works via the same endpoint
4. `POST /v1/sessions` returns the correct `launchUrl`
5. `GET /v1/games` lists the new game with its launch path

Other things you still need to do for a complete new-game port (unrelated to launch routing):
- Add artwork at `assets/games/<id>.svg`
- Add a section in this doc
- If the game has its own backend service, wire `validateSessionToken` through `apogee-api/v1/wallet/*` per [BET-PREFLIGHT.md](./BET-PREFLIGHT.md)
- If the game is crash-family, copy `preflightBet()` verbatim
- (Optional) add to `store.js defaultGames()` so the admin Games tab lists it

### History

- **2026-04-11** — Fixed silent "Contrail goes to home page" bug. The landing page's root redirect had `if (gameId) location.replace("/play.html" + search)` hardcoded, so `/?gameId=contrail` landed on Skyward's HTML bundle. The admin panel's Games tab Play button and Integration tab Try-launch fallback had the same issue.
- **2026-04-11** — Collapsed the four-table maintenance problem (apogee-api GAMES, admin.js GAME_LAUNCH_PATHS, index.html LAUNCH, docs GAMES.md) into a single source of truth. The landing page's bare-domain redirect now delegates to `/v1/launch?...&redirect=1` which returns an HTTP 302. No client-side launch-path tables remain — the bug literally cannot recur because the client never decides a launch path itself.

## Live

### `skyward` — Skyward

![Skyward hero](../assets/games/skyward.svg)

- **Type:** crash · **Status:** live · **RTP:** 97%
- **Artwork:** [`assets/games/skyward.svg`](../assets/games/skyward.svg)
- Flagship crash game. Dual-bet, provably-fair (HMAC-SHA256), 10,000× cap.
- Bet window: 6s · Average round: ~14s · Max multiplier: 10,000×
- Supported currencies: EUR, USD, GBP, BRL, KES, ETB, SSP, SOS, SLS, ZMW, DJF, MAD, BTC, ETH, USDT (and more — see [INTEGRATION.md §5](./INTEGRATION.md#5-launching-a-game))
- Min bet: 0.10 minor · Max bet: configurable per operator, default 1,000
- **Opt-in re-entry after cashout:** After cashing out, the player's bet button switches to `BET FOR NEXT ROUND`. Staying on the sidelines is the default — the player must tap the button to opt in to the next round. No auto-continue, no "one more round" reflex loop. Tapping again cancels. This is a deliberate friction point consistent with Skyward's honest-session-limit design.
- **1-second cashout cooldown:** For the first second after a cashout, the `BET FOR NEXT ROUND` button is disabled and shows `✓ CASHED · just a moment…`. A rapid double-tap right after cashing out cannot accidentally queue the next round's bet. The button becomes tappable only after the player's hand has had time to leave the screen.
- **Live round stats pill:** During each round a compact pill in the bottom-right corner of the stage shows `ROUND #N · X bets · Y total`. Bets trickle in during the 6-second betting window (staggered join times, not all at once) and lock in when the flight starts. Designed as social-proof / FOMO texture, not manipulative pressure — it's honest about how many people are actually in the lobby.
- **Mobile live bets strip:** Below the bet panels on phones, a compact `USER / BET / @ / WIN` table shows the current round's bets sorted by stake descending (whales first). Cashed rows turn green; lost rows show `−` (no amount — the stake column already carries that info). Desktop gets a wider version in the sidebar.
- **Quick-set chips:** The 500 / 1000 / 2000 row on each bet panel sets the stake directly (not additive) for players who want to bet bigger without mashing `+100` eleven times.
- **Chat:** Simulated ambient chat with pseudonymized names, crash reactions, and player messages. Sidebar tab "Chat".
- **Aviator Rain (free-bet promo):** Free bets drop into the chat on player join (2s delay) and re-trigger every 5 minutes / after claim. Promo banner fixed at bottom (mobile) or inline (desktop). Direct CLAIM button on the banner. Free bets enforce 2.00× min cashout, expire after 2 minutes. Cancelled free bets are restored. Artwork: [`assets/games/rain.svg`](../assets/games/rain.svg).

### `thermal` — Thermal

![Thermal hero](../assets/games/thermal.svg)

- **Type:** crash · **Status:** live · **RTP:** 97%
- **Artwork:** [`assets/games/thermal.svg`](../assets/games/thermal.svg)
- **Live URL:** <https://apogeetech.net/thermal.html>
- High-volatility crash variant. 100,000× cap, escalating jackpot pool.
- Differs from Skyward in growth curve (`GROWTH_K` = 0.00018 vs Skyward's 0.00012) — faster climb, punchier feel.
- Same provably-fair engine (HMAC-SHA256 hash chain) and dual-bet panels as Skyward.
- Purple/volcanic theme with animated phoenix fire bird.
- Supported currencies: EUR, USD, GBP, BRL, KES, ETB, SSP, SOS, SLS, ZMW, DJF, MAD, BTC, ETH, USDT, USDC

### `contrail` — Contrail

![Contrail hero](../assets/games/contrail.svg)

- **Type:** crash (multiplayer) · **Status:** live · **RTP:** 99% (1% house edge — industry-low)
- **Artwork:** [`assets/games/contrail.svg`](../assets/games/contrail.svg)
- **Live URL:** <https://apogeetech.net/contrail.html>
- Shared-curve crash: every player watches the same rocket climb, same crash point, same aggregate bets table under the dual bet panels. Interceptor NPC rockets rise from below and converge on the player rocket in real time — on crash, one of them reaches it and the interception explosion fires (shockwaves + shrapnel + targeting reticle).
- **Math:** inverse-CDF variant `cents = floor((α_bps/100)·2^52 / (h+1))` with `α_bps = 9900` → exact 99% RTP at every cashout target (strategy-independent). Strictly cleaner than classic bustabit `(100E−h)/(E−h)` which drifts to ~96% at high k. Proof: `P(crash ≥ k) = P(U ≤ α/k) = α/k`, so `RTP(k) = k·α/k = α` exact.
- **Provably fair:** pre-generated hash chain of 10,000 server seeds. Genesis = `SHA256(SHA256(...SHA256(seeds[N-1])))`, committed at service boot and exposed via `GET /contrail/genesis`. Each round reveals its seed on crash; verifier walks `sha256(seed)` chained forward back to genesis.
- **Transport:** dedicated `apogee-contrail` Cloud Run service, `min=max=1` instance, raw WebSocket, server-authoritative crash point, client interpolates the curve locally between 500ms heartbeats. Cashout is timestamped at server ingress.
- **House-protection limits:** `CONTRAIL_MAX_BET_MINOR=10_000_000` (100,000.00 major), `MAX_PAYOUT_MINOR=10_000_000_000` (100,000,000.00 major/bet), `MAX_BETS_PER_CLIENT=2` (dual-panel), `MAX_MULT=10000`. These are **ceilings** — per-merchant `PATCH /v1/merchants/:id` rules can only tighten them, never raise them past this hard cap.
- **Dual-bet panel** (A + B, independent stakes + auto-cashout), 5s bet window, 500ms lock, variable flight, 2.5s crash reveal.
- **Mobile-first UI**: top-bar + history strip + stage + dual bet boxes + Aviator-style "All bets / Biggest" table below. Bottom-drawer on phones exposes Round / My Bets / Top / Chat tabs. Desktop (≥780px) lays the drawer inline as a left sidebar.
- **Chat system:** simulated ambient chat with pseudonymized names, crash reactions, and player messages. Chat tab in the drawer/sidebar.
- **Aviator Rain (free-bet promo):** operator-triggered free bets that drop into the chat panel. Players claim first-come-first-served via a CLAIM button. Promotional banner (sticky below header on mobile, inline on desktop) with "FREE BETS!" call-to-action. Rain triggers automatically on player join (welcome rain) and every 2 minutes for all connected clients. Admin endpoint: `POST /contrail/rain` with `X-Admin-Key` header. Free bets enforce a minimum cashout multiplier (default 2.00×) and expire after configurable timeout. Artwork: [`assets/games/rain.svg`](../assets/games/rain.svg), [`assets/games/rain-icon.svg`](../assets/games/rain-icon.svg).
- **Backend endpoint:** `wss://apogee-contrail-jyhtisqmyq-ew.a.run.app/contrail/ws?token=…` (direct run.app URL; `wss://contrail.apogeetech.net` once DNS lands).

### `apogeehot5` — Apogee Hot 5

![Apogee Hot 5 hero](../assets/games/apogeehot5.svg)

- **Type:** slot · **Status:** live · **RTP:** 96.5% (10M-spin Monte-Carlo verified — see [APOGEEHOT5.md](./APOGEEHOT5.md))
- **Artwork:** [`assets/games/apogeehot5.svg`](../assets/games/apogeehot5.svg)
- **Live URL:** <https://apogeetech.net/apogeehot5.html>
- Classic-fruit 5-reel × 3-row slot inspired by SmartSoft Gaming's Multi Hot 5 (2022). 10 fixed left-to-right paylines, 9 symbols (cherry, lemon, plum, orange, bell, watermelon, star, red 7, wild), 1–5× Multiplier Reel applied to every line win.
- **Differentiator:** the Multiplier Reel (stolen from Multi Hot 5) + **Sticky Respin** on any 5-of-a-kind (that symbol locks for one free respin).
- **Max win:** 2,000× total bet (hard cap, enforced server-side).
- **Volatility:** medium-high. Hit frequency ~12% (one win roughly every 8 spins). See [APOGEEHOT5.md §Math](./APOGEEHOT5.md#math) for the RTP proof.
- **Backend:** dedicated `apogee-slots` Cloud Run service (stateless, scale-to-zero). Spin endpoint is `POST /slots/apogeehot5/spin` with session-token auth. See [APOGEEHOT5.md §API](./APOGEEHOT5.md#api).
- **Provably fair:** pre-generated 10,000-seed hash chain committed at service boot. Each spin reveals `serverSeed`; verifier walks `sha256(seed)` forward back to the genesis commitment. Exposed at `GET /slots/apogeehot5/genesis`.
- **Explicitly NOT shipped (all dark patterns banned under UKGC 2021 or strongly discouraged elsewhere):** autoplay, turbo/quickspin, stop-to-reveal, gamble/double-up, virtual-reel near-miss mapping, LDW celebrations, "Big Win" audio for <10× payouts, recent-big-wins ticker, hot/cold streak indicators, ambient between-spin music, progressive jackpot.
- **Responsible gambling features (base build, not a regional variant):** session net P/L always visible in header, session timer, 30-minute reality check, two-tap confirm for stakes ≥ 5.00, 2.5s global spin-cycle floor, win audio gated on `payout > stake`, no autoplay, no turbo. Germany build clamps max stake to 1.00 via `SLOTS_DE_MODE=true` env var.
- **Supported currencies:** EUR, USD, GBP, BRL, KES, ETB, SSP, SOS, SLS, ZMW, DJF, MAD, BTC, ETH, USDT, USDC (and more — see [INTEGRATION.md §5](./INTEGRATION.md#5-launching-a-game))
- **Bet ladder:** 0.20, 0.50, 1.00, 2.00, 5.00, 10.00, 20.00, 50.00, 100.00 (minor units: 20–10,000; DE build caps at 100).

### `hormuz` — Hormuz

![Hormuz hero](../assets/games/hormuz.svg)

- **Type:** crash-step (single-player) · **Status:** live · **RTP:** 97% (flat at every cashout depth)
- **Artwork:** [`assets/games/hormuz.svg`](../assets/games/hormuz.svg)
- **Full spec:** [`HORMUZ.md`](./HORMUZ.md)
- Tap-paced crash ladder inspired by InOut Games' *Chicken Road* (2024), reskinned as a VLCC supertanker crossing the Strait of Hormuz under anti-ship missile fire. Each sector cleared ratchets a visible multiplier; any hit zeroes the stake; `MAKE PORT` cashes out at the current depth.
- **Math:** sector-level inverse-CDF derivation. Per-sector survival `p_1 = α/g` (sector 1 absorbs the 3% edge), `p_{k≥2} = 1/g` (fair), `m_k = g^k`. Proof: `m_k · P(reach k) = g^k · α/g^k = α` exact at every depth. House edge lives entirely in sector 1 — sectors 2..N are individually fair coins. Strategy-independent.
- **Modes:** Calm Seas (25 sectors, g=1.10, max ×10.83, 1-in-9 sector-1 death) · Skirmish (20, g=1.22, ×53, 1-in-5) · Tanker War (16, g=1.40, ×337, 1-in-3) · Blockade (15, g=1.70, ×2,862, 2-in-5). All four return 97% in expectation at every cashout depth — mode chooses variance, not edge.
- **Fairness:** 10,000-seed hash chain, same commit-reveal scheme as Contrail/Hot 5. The full sector sequence is fated at round start by the seed; per-sector draws are `HMAC_SHA256(serverSeed, "apogee-hormuz:<mode>:<clientSeed>:round:<idx>:sector:<k>")`. Seed revealed only on round termination — no future-sector oracle.
- **Transport:** dedicated `apogee-hormuz` Cloud Run service (stateless, scale-to-zero), HTTP only. Three endpoints: `POST /hormuz/round/start` (wallet debit + open round), `POST /hormuz/round/advance` (resolve sector k, enforces 2.5s per-sector floor), `POST /hormuz/round/cashout` (clamp payout to 10,000× cap, credit wallet, reveal seed). Per-session async mutex serializes all three.
- **RTP verification:** `apps/hormuz/sim.js` runs a Monte-Carlo verifier with an adaptive 3σ gate computed from theoretical per-round variance. At 1M rounds per (mode, cashout depth) all 76 `(mode, k)` gates pass. Analytic proof in [HORMUZ.md §Math](./HORMUZ.md#math).
- **House-protection limits:** `HORMUZ_MAX_BET_MINOR=10_000_000` (100,000 major), `MAX_MULT=10_000`, `MAX_WIN_X_BET=10_000`, chain size 10k, round TTL 10 minutes. Merchant rules can only tighten these.
- **Ethical bans specific to the genre:** no counterfactual "would-have-won at sector N" reveal on hit (Chicken Road does this — we do not), no near-miss animation on survive, no stop-to-reveal, no streak/hot-sector UI, no high-water-mark prompts, no autoplay, no turbo. Inherits Hot 5's LDW gate (win audio only fires if `payout > stake`) and session transparency (net P/L always visible, 30-min reality check).
- **Responsible gambling:** first-sector death probability DISCLOSED in the mode picker (`12% · 20% · 31% · 43%`), two-tap confirm for stakes ≥ 5.00, 2.5s sector floor enforced server-side. German build via `HORMUZ_DE_MODE=true` clamps max stake to 1.00.
- **Supported currencies:** EUR, USD, GBP, BRL, KES, ETB, SSP, SOS, SLS, ZMW, DJF, MAD, BTC, ETH, USDT, USDC (and more — see [INTEGRATION.md §5](./INTEGRATION.md#5-launching-a-game))

### `apex` — Apex

![Apex hero](../assets/games/apex.svg)

- **Type:** instant-win bundle · **Status:** live · **RTP:** 97% (per game) · **Max win:** 1,024× (flip streak)
- **Launch:** [`/apex.html`](../apex.html) · **Artwork:** [`assets/games/apex.svg`](../assets/games/apex.svg)
- **Full spec:** [`APEX.md`](./APEX.md)
- Three provably fair instant-win mini games: **Scratch** (match-3, 500×), **Wheel** (prize wheel, 50×), **Flip** (double-or-nothing, 1,024×). 3.5s cycle floor, no LDW celebrations, session transparency. Ethical defaults match the rest of the portfolio.
- Provably fair: hash-chain commit-reveal with HMAC-SHA256 per round.
- **Backend:** `apogee-apex` (Cloud Run, stateless, scale-to-zero). Endpoints: `POST /apex/scratch`, `POST /apex/wheel`, `POST /apex/flip/{start,flip,cashout}`, `GET /apex/genesis`, `GET /apex/spec`.
- **Supported currencies:** EUR, USD, GBP, BRL, KES, ETB, SSP, SOS, SLS, ZMW, DJF, MAD, BTC, ETH, USDT, USDC

### `safariapogee` — Safari Apogee

- **Type:** slot · **Status:** live · **RTP:** 96.5% (1M-spin Monte-Carlo verified)
- **Live URL:** <https://apogeetech.net/safariapogee.html>
- African safari-themed 5-reel × 3-row slot with 20 fixed paylines, inspired by SmartSoft's Safari Simba but dramatically improved: 5,000× max win (vs Simba's 145×), 4-tier progressive jackpot, Stampede Free Spins, Gamble feature.
- **Symbols:** Monkey, Zebra, Flamingo, Giraffe, Hippo, Elephant, Lion, Wild (Baobab Tree), Scatter (Drum). Emoji-rendered at high resolution onto canvas textures (same pipeline as Hot 5).
- **Multiplier Reel:** 1× (45%), 2× (30%), 3× (18%), 5× (7%). Applied to ALL line wins on every spin. During free spins, the 1× position is removed — minimum multiplier is 2×.
- **Stampede Free Spins:** 3/4/5 Scatter drums → 10/15/20 free spins with boosted multiplier reel (no 1× positions). Scatter appears on reels 1–4 only.
- **Sticky Respin:** any 5-of-a-kind locks that symbol for one free respin (same mechanic as Hot 5).
- **Gamble Feature:** after any win, double-or-nothing coin flip (heads/tails), max 3 rounds. Server-resolved.
- **4-tier Progressive Jackpot:** MINI (seed €1), MINOR (seed €3), MAJOR (seed €50), MEGA (seed €750). Mystery trigger — every spin feeds the pools. Same jackpot math as Hot 5 but separate Firestore pool.
- **Max win:** 5,000× total bet (hard cap, enforced server-side).
- **Volatility:** medium. Hit frequency ~54%. Free-spin trigger rate ~3%.
- **Backend:** shared `apogee-slots` Cloud Run service (stateless, scale-to-zero). Spin endpoint is `POST /slots/safariapogee/spin` with session-token auth. Gamble endpoint: `POST /slots/safariapogee/gamble`.
- **Provably fair:** independent 10,000-seed hash chain (separate from Hot 5). Genesis at `GET /slots/safariapogee/genesis`. Each spin reveals `serverSeed`; verifier walks `sha256(seed)` forward to genesis.
- **Visual theme:** African savannah sunset — warm gradient sky (purple → orange → brown), golden sun disk with radial glow, acacia tree silhouettes, distant mountains, warm amber dust-mote particles. Gold accent color (#D4A017), dark brown background.
- **Audio theme:** Savannah ambient bed (procedural synthesis — djembe-style drums, kalimba tones).
- **Ethical bans:** no autoplay, no turbo, no LDW celebrations, no near-miss mapping, no hot/cold streak indicators. Session net P/L always visible, 30-min reality check, two-tap confirm for stakes ≥ 5.00.
- **Supported currencies:** EUR, USD, GBP, BRL, KES, ETB, SSP, SOS, SLS, ZMW, DJF, MAD, NGN, GHS, ZAR, BTC, ETH, USDT, USDC (extended African market coverage — NGN, GHS, ZAR added)
- **Bet ladder:** 0.20, 0.40, 1.00, 2.00, 4.00, 10.00, 20.00, 40.00, 100.00 (minor units: 20–10,000).

### `foxyapogee` — Foxy Apogee

- **Type:** slot · **Status:** live · **RTP:** 96.5% (5M-spin Monte-Carlo verified)
- **Live URL:** <https://apogeetech.net/foxyapogee.html>
- Autumn fox forest-themed 5-reel × 3-row slot with 20 fixed paylines, inspired by SmartSoft's Foxy Hot 20 but dramatically improved: 10,000× max win (vs Foxy Hot's 1,000×), 4-tier progressive jackpot, Fox Hunt Free Spins with Expanding Wilds, Gamble feature.
- **Symbols:** Cherry, Lemon, Orange, Plum, Watermelon, Grapes, Bell, Red Seven, Wild (Fox), Scatter (Star). Emoji-rendered at high resolution onto canvas textures (same pipeline as Hot 5 / Safari).
- **Multiplier Reel:** Base: 1× (45%), 2× (30%), 3× (18%), 5× (7%). Free spins: 2× (55%), 3× (25%), 5× (15%), 10× (5%). Applied to ALL line wins on every spin.
- **Fox Hunt Free Spins:** 3/4/5 Scatter stars → 10/15/20 free spins with boosted multiplier reel (no 1× positions, 10× available). Scatter appears on reels 2–4 only.
- **Expanding Wilds:** During free spins, any reel containing a Fox Wild expands — ALL positions on that reel become Wild. This is the primary path to the 10,000× max win combined with the 10× multiplier.
- **Sticky Respin:** any 5-of-a-kind locks that symbol for one free respin (same mechanic as Hot 5 / Safari).
- **Gamble Feature:** after any win, double-or-nothing coin flip (heads/tails), max 3 rounds. Server-resolved.
- **4-tier Progressive Jackpot:** MINI (seed €1), MINOR (seed €3), MAJOR (seed €50), MEGA (seed €750). Mystery trigger — every spin feeds the pools. Same jackpot math as Hot 5 / Safari but separate Firestore pool.
- **Max win:** 10,000× total bet (hard cap, enforced server-side).
- **Volatility:** medium-high. Hit frequency ~45%. Free-spin trigger rate ~1.3%. Expanding wilds activate in ~31% of free spins.
- **Backend:** shared `apogee-slots` Cloud Run service (stateless, scale-to-zero). Spin endpoint: `POST /slots/foxyapogee/spin`. Gamble: `POST /slots/foxyapogee/gamble`.
- **Provably fair:** independent 10,000-seed hash chain (separate from Hot 5 / Safari). Genesis at `GET /slots/foxyapogee/genesis`. Each spin reveals `serverSeed`; verifier walks `sha256(seed)` forward to genesis.
- **Visual theme:** Autumn fox forest — sunset gradient sky (amber → burnt orange → purple), autumn forest silhouettes, golden/red falling leaf particles. Amber accent (#d97706), fox orange (#ea580c), dark forest background (#1a0d00).
- **Audio theme:** Fox Hunt ambient (procedural synthesis — woodland tones, horn calls).
- **Ethical bans:** no autoplay, no turbo, no LDW celebrations, no near-miss mapping, no hot/cold streak indicators. Session net P/L always visible, 30-min reality check, two-tap confirm for stakes ≥ 5.00.
- **Supported currencies:** EUR, USD, GBP, BRL, KES, ETB, SSP, SOS, SLS, ZMW, DJF, MAD, NGN, GHS, ZAR, BTC, ETH, USDT, USDC
- **Bet ladder:** 0.20, 0.40, 1.00, 2.00, 4.00, 10.00, 20.00, 40.00, 100.00 (minor units: 20–10,000).

---

## Game object shape

```json
{
  "id":             "skyward",
  "name":           "Skyward",
  "type":           "crash",
  "status":         "live",
  "rtp":            97,
  "currencies":     ["EUR","USD","GBP","BRL","BTC","ETH","USDT"],
  "minBetMinor":    10,
  "maxBetMinor":    100000,
  "maxMultiplier":  10000,
  "aspectRatio":    "16:9",
  "mobileOrientation": "both",
  "launched":       "2025-09-01",
  "assets": {
    "thumb": "https://cdn.apogeetech.net/skyward/thumb.png",
    "hero":  "https://cdn.apogeetech.net/skyward/hero.mp4"
  }
}
```

---

## Requesting a game

Unlisted game IDs return `404 game_not_found`. Disabled games return `423 game_disabled` with a `message` explaining why (maintenance, geo-block, currency unsupported).

You don't need to pre-register per-operator access for **live** games — any valid key can launch them. **Beta** games require explicit opt-in.
