πŸ§ͺ Battle Loco β€” Pair Test Plan

Live pair-programming QA for the Battle Loco show platform (Heat vs Ice): Show Designer, Performance console, and screen surfaces. Two testers β€” the agent (AS Dev) and Mike β€” execute the same steps with their own shows and performances, compare results, and file GitHub issues for every mismatch. Shared protocol and the other brands live on the FunFirst test plan index.

Environments & data A Β· Show Designer B Β· Performance console C Β· Screens & preview E Β· Hardening Results & issue log

Environments & test data

ThingValue
Marketing sitebattleloco.com (dark-neon family look: ink #07060d, Bebas Neue + Sora)
Consolefunfirst.fun/battle-loco/performance β€” same path serves at battleloco.com/performance; designer at /designer, wall at /preview. Sign in via /signin (Convex auth).
BackendConvex deployment funfirst (trustworthy-lemming-377); seeder seed.battleLocoLuxor
Seeded show / performanceBattle Loco β€” Luxor Oct 17 (22 scenes; performance shares the title)
Test data markerCreate only PairTest <who> …-titled shows/performances. Never rename or re-cue the seeded Luxor show β€” cue copies.

Brand data β€” use these exact values

TeamsHeat vs Ice
Round card18 rounds β€” Intro, then 5Γ— [Game (scored) β†’ Pause β†’ Game Celebration], Award, Outro
Winner scenesWinner Heat / Winner Ice β€” exact team names
OverlaysGame Instructions, Vote, Crowd, Score, Punishment (signature), Games, Score Rotation
Catalog picks to exerciseSmash Bros / Mario Kart / Trivia Blitz (Game), Punishment Wheel (Pause), Champion Streak (Celebration), Trophy Reveal (Award), Goodnight (Outro)
SoundtrackBackNForth, BringTheFun, BubbleGumGirl, CockatooInTheGrass, DressedInPink, DrivingYourVibes

Flow A Β· Show Designer

A1BothSign in at funfirst.fun/signin, open /designer, select Battle Loco β€” Luxor Oct 17.
Expected: 22 scenes render, every effect thumbnail loads from public/battle-loco/effects/ (or the shared effects library), timeline renders, no console errors.
A2AgentCreate show PairTest Agent Smoke β€” <date>, tagged battleloco, left draft. MikeCreate PairTest Mike Smoke β€” <date>.
Expected: show appears in the picker; the preview wall paints nothing for it while draft (verified in C5).
A3BothAdd a scene titled exactly Vote (overlay), attach one video-loop effect, set a duration.
Expected: scene saves into the ordered list; effect preview plays; overlay kind inferred from the title.
A4BothAdd scenes titled exactly Winner Heat and Winner Ice.
Expected: both save; Flow B5 proves they cue after a Heat/Ice win (exact-name winner contract).
A5AgentScreens tab: open the Luxor layout, drag one screen-polygon corner, save, verify in the multi-screen preview β€” then restore the original geometry and re-save. MikeSame screen, drag a whole edge; confirm the polygon stays valid.
Expected: geometry persists after reload; restore leaves the layout identical (this layout drives the real Luxor screens).
A6BothProfiles tab: inspect the display profile's logical→physical panel mapping.
Expected: every logical panel maps to exactly one physical panel β€” no gaps or duplicates.
A7AgentDuplicate a scene, rename the copy, delete it, reopen the show.
Expected: duplicate is a real copy; delete leaves no orphan in the scene list or timeline.
A8BothEdit your Vote scene's effect with the multi-screen preview open.
Expected: preview updates live, no refresh.

Flow B Β· Performance console

B1BothOpen funfirst.fun/battle-loco/performance. Find Battle Loco β€” Luxor Oct 17. Open the create-performance modal.
Expected: team fields prefill Heat / Ice; seeded performance shows the 18-round card.
B2AgentCreate PairTest Agent Perf bound to your PairTest Agent Smoke show. MikeCreate PairTest Mike Perf bound to the seeded show.
Expected: console opens; bound show name displays; scene buckets list the show's scenes.
B3BothVerify the template contract: 18 rounds β€” Intro; 5Γ— Game (scored) each followed by Pause + Game Celebration; Award; Outro. Scoreboard 0–0 Heat vs Ice.
Expected: round list, types, scored flags, and team names all match.
B4BothBegin round 1 (Face Off / Intro), then cue Game Instructions from the game grid.
Expected: wall/player shows your bound show's designed scene β€” cue matched by exact scene title.
B5BothRun a Vote β€” agent taps Heat, Mike taps Ice β€” then cue the winner scene for the winning side.
Expected: vote overlay Heat vs Ice with live counts; Winner Heat/Winner Ice plays for the correct side, never the wrong one.
B6AgentManually score round 2 (a Game round) for Heat, then Ice; confirm totals. MikeScore using the Win / Rotation controls instead.
Expected: scoreboard updates live on console + wall; Score / Score Rotation overlays render; math sums.
B7BothOpen Box Score, start a soundtrack track, play an SFX, stop both.
Expected: per-round history correct; audio starts and stops cleanly β€” no double-play or orphaned track.
B8AgentMid-show: rebind your PairTest performance from your show to the seeded show via the console selector, then cue a scene. MikeRebind the opposite direction and cue.
Expected: behavior undocumented β€” record exactly what happens; the issue defines the wanted behavior.

Flow C Β· Screens & preview wall

C1BothOpen funfirst.fun/preview while your performance is live; find the Battle row + scene strip.
Expected: every screen in the Luxor layout paints; strip shows the current scene; row marked β€” LIVE.
C2AgentCue each overlay in sequence: Game Instructions, Vote, Score, Box Score, and the signature Punishment overlay.
Expected: overlays composite over wall panels (Instructions full-screen, Vote team-vs-team, Score partial) β€” matching the player.
C3BothOpen one screen full-bleed via funfirst.fun/screens/<id> and the player in a second window (Mike: on his phone). Cue a scene.
Expected: wall, screen page, and player react within a beat of each other, no refresh, identical visuals.
C4AgentEnd the show (status β†’ ended) from the console.
Expected: wall stops painting your screens immediately; "Go live or tap a scene below." returns.
C5AgentDraft gate: set your PairTest show back to draft, bind + go live, cue a scene.
Expected: wall refuses to paint the draft show β€” fallback card only (documented gating rule).
C6Agent390px viewport: wall, player, one screen page. MikeDo C3 on your phone, both orientations.
Expected: overlays readable, strip usable, no horizontal-scroll breakage, no console errors.

Flow E Β· Hardening

E1AgentRe-run seed.battleLocoLuxor from the Convex dashboard.
Expected: inserted = 0; updates in place via sourceKey β€” no duplicate shows or scenes.
E2AgentRun the cue-contract self-check (sceneCues.ts) against the Battle seeded show; record any error strings.
Expected: zero contract errors (winner-cue, full-overlay, score-overlay rules); any error filed verbatim.
E3AgentDouble-cue race: tap two game buttons as fast as possible, twice.
Expected: undocumented β€” record wall behavior (last-write-wins? flicker? stuck overlay?).
E4BothThrottle to Slow 3G, load console + wall.
Expected: loading/empty states render, never a blank screen; normal once data arrives.

Results & issue log

"Match" = agent and Mike saw the same behavior. Every ⚠/βœ– row needs an issue link: [pair-test FLOW<STEP>][battle] … in microspaces/linkall, label pair-test.

StepAgentMikeMatchIssueNotes
A122 scenes
A2draft invisible on wall
A3
A4winner-name contract
A5restore Luxor layout
A6
A7
A8
B1Heat/Ice prefill
B2
B318-round card
B4
B5Winner Heat/Ice
B6
B7audio stops cleanly
B8rebind undocumented
C1
C2Punishment overlay
C3
C4
C5draft gating
C6
E1idempotency
E2cue contract
E3undocumented
E4

Session cleanup