# Crash Bash Web Port — Changelog
Live at http://localhost:7051 · Changelog at http://localhost:7051/changelog
Goal: a faithful recreation of Crash Bash (PS1, Eurocom 2000) running in the browser on
WebGPU via Rust + WebAssembly, using the original disc's assets, with 4-player online rooms.
## Where things stand
- **Playable now**: Battle and Tournament on all 28 arenas (every minigame family, with the
arena-specific hazards and items from the original, rounds-to-win and CPU-skill options),
and the whole Adventure: five warp rooms, trophies, gems, crystals, gold and platinum relics,
all four bosses (Papu Pummel, Bearminator, Big Bad Fox, Oxide Ride) behind the retail
trophy/gem/crystal counts, the story scenes (intro, a mentor scene after each boss, the
good / evil / mixed endings), and browser saves per character. Adventure can be played by
two (a second pad locally, or a second browser in the room).
- **Online**: rooms for up to four browsers (`room` + `your name` → Join online) with
auto-reconnect; the server runs the same simulation the browser does.
- **Controls**: arrows/WASD = D-pad, Z/Space = ✕, X = □, C = ○, V = △, Enter = Start,
Backspace = Select, Q/E = L1/R1; standard gamepads work too. Each arena's controls follow
the retail button layout and are shown in the status line.
- **Known gaps / liberties**: the boss fights, gem/crystal twists and story-scene voice order
are recreated from the wiki's rules and the disc's file order rather than the original code
(see each milestone for what is inferred); relic "champions" are the regular CPUs with faster
reactions; the sound-effect banks of the bosses are mapped by ear-less guesswork from the
tone lists.
- **Verification**: `tools/sweep.py` loads all 32 arenas (28 + 4 bosses) and checks each
round starts cleanly; `tools/multi.py 4 ROOM`, `tools/reconnect.py ROOM` and
`tools/coop.py ROOM` exercise online play; `cargo test -p game` covers the Adventure flow,
each boss win, the challenge progression and the co-op seat.
- **Debug**: `?scene=intro|room1..room4|good|evil|mix` plays a story scene; `?play=<arena>`
(e.g. `?play=meltpanic`, `?play=papu`, `?play=bear`, `?play=fox`, `?play=oxide`) jumps
straight into an arena (`&bots` lets the AI play the human seat, `&gem` / `&crystal` /
`&gold` / `&platinum` play that challenge round); `?view=N` opens the model viewer
(`&top=1&at=x,z,half` for a top-down plan, `&mesh=M&noobj` to isolate a mesh).
## Milestone 0 — Disc ripped, formats decoded, first WebGPU render (2026-09-15)
- Parsed the raw MODE2/2352 disc image (`crashbash.bin`) and extracted the ISO9660 filesystem:
`SCUS_945.70` (executable), `CRASHBSH/CRASHBSH.DAT` (73 MB asset archive), plus the bundled
Spyro 3 demo. `BASHY.` is 31 MB of zero padding.
- Located the DAT file table inside the executable (992 entries of LBA/size at 0x3E910) and
unpacked every file to `assets_raw/`.
- Wrote Rust parsers (`crates/bashfmt`) for the Eurocom formats:
- `.tex` texture packs (4/8-bit paletted, 1555 CLUTs)
- `.mdl` model packs — triangle strips, per-triangle vertex colors and UVs, semi-transparency
modes, vertex-morph animations (including the shared point pool and per-animation pools),
and placed objects living in separately loaded 4 KB-aligned segments.
- `.sfx` sound bundles (VAB header + ADPCM body + SEQ songs) and SPU ADPCM decoding.
- TGA legal/title screens.
All 964 asset files on the disc parse successfully.
- Rust/wasm client with a WebGPU renderer that reproduces PS1 shading rules (vertex-color
modulation with 128 = neutral, 0x0000 texel cut-out, the four semi-transparency blend
equations). Currently shows the boot legal screen, then Warp Room 1 with Crash's idle
animation playing.
- Native Rust server (`crates/server`) hosts the client and assets on :7051, serves this
changelog at `/changelog`, and runs 60 Hz authoritative game rooms over WebSockets (`/ws`)
for up to four players per room (lobby only for now).
- Keyboard and Gamepad input mapped onto PS1 controller bits.
### Next
- Title screen and main menu from the real menu models + fonts.
- Music/SFX: SEQ sequencer + VAB synth in WebAudio.
- First playable minigame (Crate Crush) with local and online 4-player.
## Milestone 1 — Crate Crush is playable (2026-09-15)
- **Playable minigame: Crate Crush on Jungle Bash** with the real arena, the real crate-mode
character models and animations (idle, run, pick-up, carry, throw, kick, hurt, win, lose),
and the real crate set (wood, TNT with 3-2-1 countdown faces, Nitro, iron, blob shadows).
- Rules implemented: crates rain from the sky, ✕ picks up / throws, □ kicks, TNT fuses and
chain-reacts, Nitro explodes on contact, iron crates can only be kicked, damage and knockback,
health bars, 90-second rounds, last-one-standing / most-health wins, best-of-3 match.
- Three CPU opponents with simple AI (fetch crates, aim with lead, dodge lit TNT and incoming
throws), so single-player is a full match right away.
- Game flow: boot legal screen → title → main menu → 8-character select (other players can join
with Start) → arena select (Jungle / Snow / Space / Drain Bash) → match → results.
- Decoded level format details: object instance table (placement matrices), separately loaded
4 KB segments, vertex-colour blend-mode bits — arenas now render with all props placed.
- **Music**: a software PS1 SPU (VAB instruments, SPU ADSR envelopes, SEQ sequencer with loop
points) renders the original sequenced soundtrack through WebAudio. Title, menu and arena
tracks play; sound effects fire from the arena sfx bank on pick-up/throw/kick/break/explode.
(Sound-effect → action mapping is a first guess and will be tuned.)
- **Online play**: open `http://localhost:7051/?room=NAME&name=YOU` in up to four browsers; the
server runs the authoritative 60 Hz simulation and streams snapshots to everyone in the room.
- Debug model viewer: `http://localhost:7051/?view=<file index>` (Q/E orbit, ↑/↓ zoom, ←/→ anims).
## Milestone 2 — Second minigame, authentic UI (2026-09-15)
- **Polar Push is playable** (Polar Panic arena, with Tilt/Melt/Manic Panic arenas selectable):
four polar-bear riders on the ice floe, ✕ charges, collisions use weight and momentum, the
floe shrinks as time runs down, last bear standing wins. Bots hunt, aim to push you outward,
and avoid charging off the edge.
- The menus and HUD now use the game's own bitmap font (`fonts/font1.tex`), the 3D CRASH BASH
logo, the Aku Aku mask model, and the interface model: character face icons, orange 3D timer
digits, the 3D "3-2-1" countdown, "GO!" and "TIE".
- Arena select lists arenas grouped by minigame (Crate Crush ×4, Polar Push ×4).
- Crate Crush: wood-splinter and smoke/fire particles on breaks and explosions, blob shadows
under players and crates, Nitro bobbing, TNT count faces.
- Fixed PS1 shading of untextured polygons (light shafts / glows no longer blow out) and the
blend-mode source (bits 13-14 of the vertex-colour flag).
- `cargo run -p game --bin simulate -- polar|crate` runs headless bot matches for balancing.
## Milestone 3 — Pogo Pandemonium (2026-09-15)
- **Pogo Pandemonium is playable** on all four arenas (Pogo Painter, Pogo-a-Gogo, El Pogo Loco,
Pogo Padlock): hop across the 8×8 tile grid painting tiles in your colour, close a rectangle
of your tiles to fill it for double points, grab the power crate to paint a whole row and
column and get six fast hops. Bumping a hopper as it lands knocks it off balance. Highest
score at 1:30 wins the round. The 64 tile objects in each arena file are recoloured live.
- Hop animations are synchronised to the simulation's hop phase (the vertical motion is baked
into the original animation data).
- Scores appear in the HUD for score-based games; the arena list now spans three minigames
(12 arenas).
## Milestone 4 — Ballistix (2026-09-15)
- **Ballistix is playable** (Crashball, Beach Ball, N. Ballism, Sky Balls arenas): each player
hovers in front of their own wall on the real hover-paddle vehicle with a player-coloured
ring; balls stream out of the centre launcher faster and more often as time passes; ✕ fires a
burst that whacks nearby balls; every ball that reaches your wall costs one of 15 points and
at zero you're out. Corner blocks, the launcher and other balls all bounce.
- Fixed the control convention across all games: Up on the d-pad/stick moves away from the
camera, and characters now face the direction they move in every minigame.
- Arena select shows all 16 arenas in two columns grouped by minigame.
- A room join form (room + name) sits in the bottom bar for online play.
## Milestone 5 — Tank Wars (2026-09-15)
- **Tank Wars is playable** (Desert Fox, Metal Fox, Jungle Fox, Swamp Fox): drive the real
tank model (turn toward the stick, then roll), ✕ fires shells that bounce once off the walls,
□ drops a spiky mine behind you (two per life; smashed crates can restock them), three hits
and your tank blows up. Destructible crates and steel blocks are laid out symmetrically; the
arena playfields are re-centred from their original offsets. Bots lead their shots, keep line
of sight, dodge incoming shells and detour around obstacles.
- Explosion fire frames, smoke, debris and shock rings come from the original tank effect set.
- Five of the seven Crash Bash minigame families (20 arenas) are now playable, all with
four-player local (keyboard + gamepads) and online rooms.
## Milestone 6 — Tournament mode and results (2026-09-15)
- **Tournament**: five games, one random arena from each minigame family in a shuffled order,
single round each; the winner of each game earns a point; final standings on a podium with
the character statues and the tournament podium music.
- **Battle results screen** after every match (win counts, winner headline, podium).
- Adventure is listed but shows a "not built yet" notice for now.
## Milestone 7 — Medieval Mayhem: Mallet Mash (2026-09-15)
- **Mallet Mash is playable**: mushrooms pop out of the castle lawn and sink back; ✕ swings the
mallet (red = 1, gold = 3, purple = −2 points), clonking another player stuns them; splats,
rings and debris from the original effect set. Bots chase the best-value mushroom they can
reach in time.
## Milestone 8 — Crash Dash (2026-09-15)
- **Crash Dash is playable** (Dante's Dash, Splash Dash, Toxic Dash, Dot Dash): hover pods race
three laps around the ring track; Wumpa fruit (the original 14-frame spinning fruit) fills the
boost meter, hold ✕ to boost, TNT crates spin you out, pods bump each other. HUD shows the lap
counter and boost meter. All seven minigame families are now represented (25 arenas).
## Milestone 9 — Dragon Drop (2026-09-15)
- **Dragon Drop is playable**, following the retail rules: ride a baby dragon around the castle
pit, touch a jewel lying on the ground to pick it up, then press ✕ to shoot it at the target
wheel rolling along the far wall. A hit scores the multiplier of the band you shot from — the
pit floor's ×1/×2/×3/×5 arcs, measured from the real arena model, with the tiny ×5 half-disc
at the near edge. Green and purple jewels are always in play; the blue one drops into the
middle with 45 seconds left. Ramming a carrier knocks their jewel loose. Bots pick a band,
lead the rolling wheel and shoot, and squabble over loose jewels.
- Player colours now match retail throughout (P1 yellow, P2 red, P3 blue, P4 green): HUD,
character select, Pogo tiles, Ballistix and Tank Wars markers.
- Debug viewer gained a top-down orthographic mode (`?view=N&top=1&at=x,z,half`) used to
measure arenas from the real models.
## Milestone 10 — Ring Ding (2026-09-15)
- **Ring Ding is playable**: four players on the slowly spinning wooden cog inside the clock
tower (the real arena model with its gears and pendulum; the deck, rim and hub turn). Balloons
in the four player colours drift over the ring — jump (✕) into your own colour for a point,
pop a rival's colour and you are stunned. Black balloons recolour every balloon to yours for
five seconds, pop all rivals' balloons, or reverse the ring. □ kicks rivals (stun) and opens
the purple ? crates, which hold hover boots (8 s, move freely against the spin) or a vacuum
cleaner (11 s, your balloons drift to you; lost when hit). Pop clouds, colour stars and
balloon shadows come from the original Ring Ding effect set.
- Arena select and Tournament now treat the Medieval Mayhem games as one family (27 arenas;
a tournament is still five games).
## Milestone 11 — Keg Kaboom (2026-09-15)
- **Keg Kaboom is playable** — all four Medieval Mayhem games are now in (28 arenas). Everyone
carries a barrel of gunpowder around the village square: start a trail at one of the two
roaming fire creatures and hold □ to keep pouring as you run; the flame chases along your
trail and blows up every keg it reaches. Brown kegs score 2, 4, 6, 8 then 10 each in an
unbroken chain, silver 10, gold 20; neighbouring kegs catch. Let go of □, get caught by your
own flame, or get knocked over by a rival's blast or a floor shock wave and the chain resets
— back to a fire creature. Kegs drop in from above with the original debris, fireball, spark
and shock-ring effects. Bots pick kegs, dodge lit ones and shock waves, and never run back
into their own flame.
## Milestone 12 — Adventure mode: the warp rooms (2026-09-15)
- **Adventure is playable as a hub.** Pick your character and walk around the real warp room
levels (all five rooms, with their door signs), following behind with a chase camera like
the original. Stand on a portal and press ✕ to play that game against three CPU rivals;
win three rounds and the trophy is yours (the portal turns gold). Win every trophy in a room
and the green warp pad on the left opens the next room; the other pad takes you back.
Rooms and their games follow the retail layout (Warp Room 1: Crashball, Polar Panic, Pogo
Painter, Jungle Bash … Warp Room 5: Splash Dash, Dragon Drop, Mallet Mash, Swamp Fox, Keg
Kaboom, Dante's Dash).
- Progress (trophies and current room) is saved per character in the browser, so it survives
reloads. Boss fights are signposted but not built yet; gem, crystal and relic challenges
are still to come.
## Milestone 13 — Retail controls and Splash Dash creatures (2026-09-15)
- **Crate Crush** now uses the retail buttons: ✕ jump, ○ pick up / throw, □ attack.
- **Crash Dash** races are ten laps like retail, boost is on □ (hold), and **Splash Dash** puts
every character on their sea creature from the disc (Crash and Coco on dolphins, Cortex and
Brio on the robot fish, Tiny and Kong on killer whales, Dingodile and Rilla Roo on
swordfish). The rods slide out of the centre island and sweep the track against the race
direction — press ✕ to hop them or you spin out. Bots time their hops.
- Ring Ding and Crate Crush jumps have their own sound.
## Milestone 14 — Papu Pummel boss fight (2026-09-15)
- **The Warp Room 1 boss is in.** Once all four trophies are won, the pink portal opens Papu
Pummel: Papu Papu (the original model and animations) sits on his throne at the far end of a
7×7 tile floor over lava. Each phase he slams his staff — leftover crates are smashed and
columns of tiles roll in a snake pattern (stay off them) — then crates drop in, his shield
goes up and he sends out little Crash clones. Kick them or hit them with crates; when they
are gone the shield drops and he laughs — land a crate on him for a quarter of his health.
Two, then two-plus-two, then six clones; after the third hit his final slam brings the arena's
stone block down on his head. Wumpa fruit restores your health. Beating him is saved and
opens Warp Room 2 (which also needs its trophies).
- Debug: `?play=papu` (or any arena name, e.g. `?play=junglebash`) jumps
straight into that arena.
## Milestone 15 — Polar Push arena variants (2026-09-15)
- **Melt Panic** now uses the arena's real melting floe: sixteen animated ice wedges whose
melt frame follows the shrinking safe radius, with Uka Uka hovering overhead handing out only
bad news (shrink rays and 500 lb weights). The other Polar Push floes no longer shrink.
- **Tilt Panic**: the floe leans in a new direction every few seconds (the deck and its rim
actually tilt on screen) and everyone slides downhill; bots lean into the slope.
- **The power-up robot** from the original object set now hovers over Polar Panic and Tilt
Panic dropping items on a random bear: grow (bigger and heavier for 8 s), shrink (easier to
shove), or a 500 lb weight with a ten-second fuse — ram someone to hand it on before it
crushes you.
- Effect sprites that the original places at runtime (lightning frames, ice chunks) are no
longer drawn statically in the Polar arenas.
## Milestone 16 — Crate Crush arena hazards (2026-09-15)
- **Snow Bash**: the penguin sleeps in the middle of the rink (the original model). Hit him
with a crate or a kick and he wakes up and rampages — spinning around the arena, smashing
crates (TNT and nitro go off), knocking players flying — then waddles back to bed.
- **Space Bash**: TNT and nitro blasts blow away the skyscraper's roof tiles (nitro takes two).
Anyone who steps over a gap, and any crate left on one, falls into the city below. Bots steer
round the holes and flee the penguin.
## Milestone 17 — Ballistix arena variants (2026-09-15)
- **N. Ballism**: N. Gin (his original hover pod model) rises out of the centre launcher every
so often and sprays eight balls in every direction before sinking back.
- **Sky Balls**: a turbine blows out periodically and the whole floating platform leans for a
few seconds — the balls roll downhill, so the low goal takes a battering.
## Milestone 18 — Crash Dash arena variants (2026-09-15)
- **Dot Dash and Dante's Dash**: missiles appear on the track — drive over one to take it,
then ○ fires it; it homes on the pod ahead and spins them out.
- **Dante's Dash**: the volcano erupts every so often and leaves glowing lava pools on the
circuit for a few seconds; touch one and you spin out. Bots steer round them.
- **Toxic Dash**: the poison barrels placed by the original arena are now solid hazards, and
force fields can be picked up — ○ shoves every nearby pod away.
- Loose effect meshes in the Dash arenas (lava blobs, props) are no longer drawn statically.
## Milestone 19 — Pogo Pandemonium variants (2026-09-15)
- The "!" crates now hold the retail items: **arrows** (paint the whole row and column),
**speedy boots** and **missiles** — ✕ fires a missile along your hop direction and the first
rival it hits is stunned. Held items float over your head.
- **Pogo-a-Gogo** scores only for closed figures (the tiles themselves are worth nothing).
- **El Pogo Loco**: Ripper Roo (the original model) hops across the grid every so often,
squashing anyone in his way and leaving TNT that blows the paint off a 3×3 patch.
- **Pogo Padlock**: a missile hit steals the victim's tiles, hopping onto your own colour wipes
all of them, and the padlock (shown above its crate and its holder) protects you. Bots
avoid their own colour and TNT.
## Milestone 20 — Manic Panic bombs and the Beach Ball magnet (2026-09-15)
- **Manic Panic**: bombs drop onto the ice; run over one to pick it up and ○ lobs it — the
blast sends every bear nearby flying. Bots fetch bombs and throw when a rival is lined up.
- **Beach Ball**: hold ✕ for the electromagnet — balls in front are drawn in and stick to your
pod (up to four); release to fire the lot at high speed. Hold it too long and it overloads,
dropping the balls and needing a moment to recover. The field is drawn in front of the pod
and flickers as it strains.
## Milestone 21 — Bearminator, the Warp Room 2 boss (2026-09-15)
- **Bearminator** is playable from the Warp Room 2 boss portal (or `?play=bear`). It uses the
real boss arena (`boss_bear/arena.mdl`): the metal platform over the water, the submarine
with its twin cannons and the polar-bear captain in the conning tower (his own idle, order,
roar, duck and laugh animations), the mechanical bears (`robopolar.mdl`: walk, lunge, curled
up in flight, stunned) and the red-tipped missile, plus the crate it arrives in.
- Retail rules: the sub fires waves of mechanical bears onto the platform — charge them off.
When they are all gone a missile appears; walk over it, face the sub and ○ (or ✕/□) fires.
A hit takes a third of his health; hit or miss, the sub then bombs the platform and a whole
pie section drops into the sea (the arena's own three damage meshes, in their real
orientation, and the simulation's floor matches them exactly). Each hit adds a bear to the
next wave; three hits and he sinks, fall in the water and he points and laughs.
- The platform rocks like Tilt Panic; bots (and the mechanical bears) know where the holes are.
- Boss health bar in the HUD, boss music (`boss_bearminator`) and its sound bank, and winning
marks the Warp Room 2 boss as beaten in the browser save (covered by a state test).
- Fixed a Polar Push physics gap that let anything spawned in the air hover forever (this was
why the mechanical bears could never be pushed off in the first headless runs).
## Milestone 22 — Big Bad Fox, the Warp Room 3 boss (2026-09-15)
- **Big Bad Fox** is playable from the Warp Room 3 boss portal (or `?play=fox`), on the real
Komodo boss arena (moon crater, nebula sky) with the war post built from the game's own
`boss_komodo/arenaobjects.mdl`: the machinery block along the far edge, the cannons, turrets
and launchers (each with its wrecked, smoking variant), and the Komodo Brothers' tank hulls
with Joe and Moe in the hatches (`komodotank.mdl`, their idle / hit / defeat animations).
- Round 1, three stages of hardware to shoot out: three cannons lobbing spiky cannonballs that
bounce once and burst; four turrets that swing onto you and spit green bolts (every fourth
shot a three-way spread); two launchers whose missiles home in on you — a shell or a mine
knocks a missile down. Everything only fires once it has turned onto you, so keep moving.
Mines (three to start, more lie about) also wreck hardware, and wumpa fruit restores health
(the boss uses a proper health bar instead of three hits).
- When the engine goes up the machinery sinks into the pit and round 2 is a straight tank duel
against Joe and Moe (health restored, nine mines).
- HUD: the war post's / the brothers' health bar at the top; boss music (`Metal Fox` theme) and
the Komodo sound bank; a win marks the Warp Room 3 boss beaten in the browser save (state
test).
- Tank Wars explosions now use additive fire sprites (the file marks them opaque, which drew
them as black squares).
## Milestone 23 — Oxide Ride, the final boss (2026-09-15)
- **Oxide Ride** is playable from the Warp Room 4 boss portal (or `?play=oxide`), in two
phases like the original:
- **The chase.** A camera-behind flight down the asteroid course from `boss_oxide/arena.mdl`
(every placed rock, metal hulk and structure of the file, at its real position) in the real
chase pod (`playervehicle.mdl`, with the player's Ballistix rider aboard), after Oxide in his
winged ship. Rocks are solid, nitro crates and iron fences appear along the way, and Oxide
fires missiles back at you; six hits and it's over. Reach the end and the pods drop onto…
- **The duel.** The file's Ballistix platform (the same model, lifted from where it is stored
10,000 units below the course) with Oxide alone on the far side in his ship. Balls through
a goal cost health; the two cannons by his goal fire missiles at you (a well-timed □ pulse
swats them); every so often a slow red ball comes down the arena — touch it and you are
finished, so step aside and let it pass. Oxide's pod is a little slower than yours.
- HUD: a course-progress bar under "N. OXIDE" during the chase, his health in the duel, and
the player's own health bar throughout. Winning marks the Warp Room 4 boss beaten (state
test); the AI can drive the whole fight (`?play=oxide&bots`).
## Milestone 24 — Gems and crystals (2026-09-15)
- Every minigame portal now runs the retail sequence: **trophy** (three round wins), then a
**gem** round, then a **crystal** round, each a single round won under a condition. The
portal sign says what the next visit is for, the portal glow moves blue → gold → green →
violet as they are won, and the warp-room header counts trophies, gems and crystals.
- Gem rounds stack the odds against you: half health (Crate Crush), heavier bears and a
60-second clock (Polar Push), opponents starting on 8 points (Pogo), 8 points to start
(Ballistix), a two-hit tank (Tank Wars), the field starting a fifth of a lap ahead (Crash
Dash), and head starts for the field in the Medieval Mayhem games.
- Crystal rounds add a twist: no explosion may touch you (Crate Crush), a floe already
two-thirds gone (Polar Push), win by double (Pogo), no power pulse (Ballistix — the retail
Crashball rule), mines raining from the sky (Tank Wars — the retail Metal Fox rule), no
spin-outs (Crash Dash — the retail Dot Dash rule), and a 1.5× margin in Medieval Mayhem.
Breaking the condition shows "GEM/CRYSTAL LOST" and the win awards nothing.
- Boss portals now use the retail entry requirements (Papu 4 trophies; Bearminator 9/6/3;
Big Bad Fox 15/10/7; Oxide Ride 22 trophies, 15 gems, 12 crystals) and each warp room opens
once the previous boss is beaten. Saves carry gems and crystals; covered by a state test.
## Milestone 25 — Two-player Adventure and local seats (2026-09-15)
- **Co-op Adventure**: a second player can press Start at the character select (as in the
original, Adventure takes one or two players). Both walk the warp rooms together (P2 tags
along behind P1), both are human seats in every minigame and boss fight, and a win by either
of them earns the trophy, gem, crystal or boss for the team.
- Local seats: every connected gamepad plus the keyboard is a seat that can join Battle,
Tournament or (P2) Adventure — previously only P1 could join without an online room.
- `tools/coop.py` drives two browsers through a co-op Adventure start; state tests cover the
second seat and the team award.
## Milestone 26 — Gold and platinum relics (2026-09-15)
- After the trophy, gem and crystal, each arena offers its **gold relic** (beat the arena's
champions two rounds in a row) and then its **platinum relic** (three in a row), as in the
original: gold rounds open once Warp Room 4 is reached, platinum at 25 trophies, and the
gold must be won before the platinum. A round taken by a CPU breaks the streak ("GOLD RELIC
LOST") and the match no longer counts.
- The champions are the regular CPU opponents thinking twice as often (and Pogo bots hop with
far less dither), across all ten minigame kinds.
- Portal signs, the award flourish, the portal glow (gold, then white when everything at an
arena is won), the warp-room counters and the browser save all carry relics; `?play=<arena>
&gold` / `&platinum` start a relic round directly. State test for the progression.
## Milestone 27 — Story scenes (2026-09-15)
- The Adventure's story is back, rendered from the disc's own cutscene files
(`models/cutscene/*`): the temple sets, the crystal chest and light beams, and Aku Aku's and
Uka Uka's talking animations bundled in each shot. Speech comes from the 58 cutscene voice
bundles (`sfx/cutscene/214–271`, VAGs played at 22 kHz through the synth's fourth bank slot),
one line per talking animation; the title cards (`text_intromovie`, `Good Wins`, …) open the
scenes.
- **Intro** (nine shots, `level_intro` then `level_shot2…6` and the three closing shots) when
a new Adventure begins — a returning save skips it. **Mentor scene** (`level`…`level4`) after
each boss, with only your side's mask talking (Aku Aku for Crash, Coco, Tiny and Dingo; Uka
Uka for Cortex, Brio, Kong and Rilla). **Endings** after Oxide Ride: good, evil, or the mixed
ending when two players from different teams finish together.
- The camera picks a side clear of the set and drifts slowly round the speaker; ✕/Start skips a
shot, △ the whole scene. `?scene=…` plays any scene directly.
- Caveat: which speech line belongs to which shot is inferred from the files' order on the disc
(variable-length lines 214–221 for the intro, 222–225 for the endings, then the fixed-length
ones for the warp rooms); the game's real table has not been located in the executable yet.
## Milestone 28 — Battle options (2026-09-15)
- The arena select carries the original's Battle options: **rounds to win** (2–7, L1/R1 —
Q/E on the keyboard) and **CPU skill** (easy / medium / hard, □). Skill scales every CPU's
reaction time across all ten minigame kinds (hard thinks twice as fast, easy half as fast);
Tournament takes the skill setting too. Adventure keeps its own rules (three rounds for a
trophy, single rounds for gems and crystals, champions for relics).
## Milestone 29 — Published on the spencerbench portal (2026-09-17)
- The port is live at **https://spencerbench-portal.down.lol/crashbash-fable51/**, behind the
portal's nginx: one `server` on 127.0.0.1:4052 under systemd (`crashbash-fable51.service`,
`/srv/crashbash-fable51`) answers the page, the wasm bundle, the ~1000 asset files, the
changelog and the room WebSocket. `deploy/publish.sh` rebuilds and republishes all of it; the
nginx snippet and unit file live in `deploy/`.
- The client no longer assumes it is served from the site root: assets are fetched relative to
the page and the room socket is opened beside it (`…/crashbash-fable51/ws`), so the same build
runs at `localhost:7051/` and under the portal's sub-path.
- `BIND` env var on the server (default `0.0.0.0`, loopback on the portal box).