# Session Handoff: NYC Crashout — gauntlet r22-r28 + live bug fixes (2026-08-11)

## Current Goal
Continue the approved gauntlet (docs/GAUNTLET-PROMPT.md) and fix live bugs Quess reports while
playtesting. No open task right now — session paused at his request ("wrap up for now").

## Project
- Path: `/Users/quessq/Desktop/ALL Combined Models/COMBINED/NYC Crashout GAME`
- Working tree: clean, nothing staged or uncommitted
- Latest commit: `9d17b4e` on `main`

## Completed Work (this session, newest first)

**Live bug fixes, reported by Quess while playing (all committed, all verified in-engine):**
1. `9d17b4e` — Torta's `mp`/`hk` attacks were thrown AWAY from the opponent. Root cause: her
   `punch`/`kick` plates had `dirX` measured backward in the manifest, which made the strike-anchor
   scanner confidently find the wrong limb (self-consistent-looking but wrong — a coordinate-only
   sweep didn't catch it, had to render and look). Fixed `dirX` on those two poses only; left
   `upper` alone (genuinely ambiguous vertical pose, no visual evidence either way).
2. `db7fb7e` — Torta's "TORTA POWER" jersey text read backward whenever she was mirrored. Marked
   her 7 front-on/symmetric non-attack poses (`stance/walk/crouch/jump/hit/block/win`) as
   `symmetric: true` in the manifest so they never mirror — both the draw pass and the `strikeWorld`
   FX-anchor system now respect this flag from one place. Attack poses (`jab/punch/kick/upper`) were
   deliberately NOT touched — they must mirror to connect on the correct side.
3. `c2d282f` — `assets.js` fetched every character's `_manifest.json` with **no cache-busting**.
   Bumped to `?v=4` (was `?v=1` implicitly, now versioned). **Bump this again any time a manifest's
   data changes** — this was the reason an earlier fix (Vesper's walk direction) appeared not to
   have landed: the browser was serving a stale cached copy.
4. `5595f90` — Two bugs: (a) the canvas had zero responsive CSS, so any viewport smaller than the
   fixed 1280×720 drawing surface was silently CLIPPED, not scaled — this was the real cause of a
   "turntable looks choppy/out of order" report (a cropped window into a correctly-rotating
   character looks like frames jumping randomly). Fixed with CSS `min(100vw,177.78vh)` sizing;
   drawing resolution is untouched. (b) Vesper's `walk` plate had `dirX: 1` but the raw photo
   strides left — fixed to `-1`. Verified this was isolated to Vesper, not systemic, by checking
   4 other flagged characters visually (all were correct as authored).

**Gauntlet rounds r22–r28** (see `tools/gauntlet/progress.json` for full judge verdicts):
- r22 combo-feedback: 1/3 (best round yet for this piece, not a win)
- r23 combo-feedback: **WIN 3/3** — replaced whole-body hit wash with a contact-anchored core
- r24 hud: **WIN 3/3 unanimous** — health bars tied to team color instead of one gold gradient
- r25 character-scale: **WIN 4/4** — FIGHTER_H 360→400, camera zoom cap re-derived against the
  real per-character worst-case jump (Vesper), verified empirically for no cropping
- r26 title-screen: **WIN 2/3** — fixed a light-burst effect that was ghosting through the menu list
- r27 stage-art: **WIN 2/2** — no code change, existing art already cleared the bar
- r28 character-select: **WIN 2/2** — no code change, existing UI already cleared the bar

## Files Changed (this session)
- `js/core/constants.js` — `FIGHTER_H` 360→400
- `js/sim/sim.js` — camera `NEUTRAL_ZOOM_CAP` re-derived (1.20→1.06); combo-feedback hit FX anchor
- `js/render/sprites.js` — `plateMetrics`/`strikeWorld` shared seam; `symmetric` flag support
- `js/render/hud.js`, `js/render/screens.js` — hud team colors, title-screen burst fix
- `js/render/assets.js` — manifest fetch cache-bust (`?v=4`)
- `index.html` — responsive canvas CSS
- `assets/state-sprites/vesper_manifest.json` — walk `dirX` fix
- `assets/state-sprites/torta_manifest.json` — `symmetric` flags + punch/kick `dirX` fix
- `tools/gauntlet/progress.json` — r22-r28 verdicts booked
- `tools/capture.mjs` — combo-feedback shot recast (r22)

## Verification
- `./verify.sh` green after every commit this session (JS syntax, HTTP smoke, sprite package,
  headless sim).
- Full capture sweep (`node tools/capture.mjs`) clean after every commit: ~16.6ms avg frame time,
  zero console errors.
- Roster-wide facing/anchor sweep run twice (before and after the Torta punch/kick fix): 200
  checks (20 characters × 5 attacks × 2 facings) via the real `strikeWorld` system, 0 bad on the
  final pass.
- All fixes confirmed by rendering the actual frame and reading pixels, not just trusting
  coordinate math (the Torta punch bug specifically fooled the coordinate-only check).

## Current State
- No servers running (`lsof -ti tcp:8127` returns nothing — confirmed clean).
- Working tree clean, `main` at `9d17b4e`.
- Gauntlet standing: **9 of 10 pieces beat the bar.** Only `hit-feedback` remains open.

## Blockers, Risks, And Assumptions
- **hit-feedback is blocked, not skipped.** It needs regenerated `_hit.png` plates for
  TITAN/NOVA/MONSTA/BOLT (their current hit sprites are upright stances with no recoil). Paste-ready
  prompts are staged at `docs/prompts/REACTION-REGEN.md`. Blocked on Higgsfield/Chrome connectivity
  — `list_connected_browsers` returned empty every time it was checked this session. This needs
  Quess to connect the Claude-in-Chrome extension; do not attempt to work around it.
- **Known, disclosed limitation (not a bug to "fix" casually):** any character with legible printed
  text on a plate that must mirror for gameplay (an asymmetric attack pose) will show that text
  backward on whichever side forces the flip. This is architectural (baked-in photo text mirrors
  with the photo) and was only worked around for Torta's *non-attack* poses, where mirroring wasn't
  needed for correctness anyway. Torta's `mp`/`hk` attacks will show backward jersey text — flagged
  to Quess explicitly, not hidden.
- **Only Torta and Vesper have been individually audited** for wrong `dirX`/mirroring on their
  plates. The roster-wide sweep checks whether the *strike lands on the correct side*, which
  catches gross facing errors, but does NOT catch a self-consistent-but-wrong anchor the way the
  Torta punch bug was — that one needed a human look. If another character's attack looks wrong,
  don't trust the coordinate sweep alone; render and look.
- Several gauntlet wins this session carry an honest caveat that the reference frame used had its
  own weakness (noted per-round in `progress.json` and in each commit message) — not hidden, but
  worth knowing before treating any of r24-r28 as fully "settled" if re-litigated later.

## Do Not Overwrite
- `tools/gauntlet/progress.json` — the full judge-verdict history; append, don't replace.
- `docs/prompts/REACTION-REGEN.md` and `docs/prompts/reaction_regen_prompts.json` — paste-ready
  Higgsfield prompts for the blocked hit-feedback piece.
- Any manifest `symmetric`/`dirX` values without re-reading the actual PNG first — several of these
  were wrong in ways that looked plausible.

## r29 hud follow-up (2026-08-11)
Addressed the r24-panel-named gap ("hyper meter disconnected from the top health/name cluster,
sits at the bottom screen corners"): moved it to sit directly under each side's bench bar, forming
one connected block (portrait -> health -> bench bar/name -> hyper meter). `js/render/hud.js`
`drawHealthBars()` — `my` 
changed from `H - 46` to `140`, `mx` now derives from `bx` (the health bar's own x) instead of a
separate hardcoded `40`. Verified no overlap with DANGER flash, combo counter, or KO-moment
cinematic letterbox across capture shots.

Ran a narrow 2-judge blind re-check (cohesion + legibility only, not a full panel) against
`assets/refs/sf6/fight-neutral.png` — **lost 0/2**. Re-reading the actual reference pixels after
the loss (not just the r24 verdict text, which is what the fix was built from) showed SF6's Drive
gauge is center-top per side, not corner-clustered under the portrait like this fix assumes —
build from the reference image next time, not a text description of a prior verdict. Kept the
change anyway: it's a strict improvement over the prior floating-disconnected state with zero
regressions, and `hud` keeps its r24 win status — this is follow-up polish, not a re-litigation.
Full details in `tools/gauntlet/progress.json` `blind_round29`.

## r30 title-screen logo contrast (2026-08-11)
Fixed the r26-named defect: the wordmark's "NYC" row blended into the bridge tower stonework
behind it. `js/render/screens.js` title logo draw — added a dark radial contrast scrim behind the
mark's bounding box, and chained the drop-shadow filter (all-around 16px glow + the original 12px
downward shadow) so every edge separates from the background, not just the bottom. Visually
confirmed the fix on before/after captures; not re-run through a blind panel (unambiguous contrast
defect, low-risk change, no downside seen anywhere else in the sweep).

## r31 ko-moment debris calibration (2026-08-11)
r19's dissenting judge said the debris chips read as "zero debris" after r19b shrank them to kill
a "confetti card" look. Bumped chip size ~55% (`js/render/render.js` `drawKoDebris`, base 2.2->3.4,
variation range 5.75->9.0) keeping the same distance-shrink/streak shape. Visually confirmed chips
are now clearly visible near the KO impact point without reverting to the flat-card look. No panel
re-run (calibration tweak on an already-won piece, not a re-litigation).

## Roster-wide attack-pose audit (2026-08-11, after this session's live fixes)
Did the "render + look" audit item below for all 20 active-roster characters other than
Torta/Vesper (already audited when their bugs were fixed): alma, aria, axiom, cass, darnell, dev,
fang, hideki, jojo, lena, luca, moe, monsta, nova, priya, sabrina, talia, titan — captured both
facings of `lp`/`mp`/`hk`/`launcher` (160+ PNGs, visually inspected) via an ad hoc Playwright
script that force-sets `Fighter` state directly. **All 18 clean** — strikes extend toward the
opponent, no mirrored/backward text or asymmetric-detail issues. No manifest edits were needed;
nothing staged or committed.

Side finding: **`bolt` and `shade` are dead code.** Their manifest JSON files exist on disk
(`assets/state-sprites/{bolt,shade}_manifest.json`) but `js/data/roster.js` only exports `ROSTER`
+ `ALT_ROSTER` (the 20 characters above plus Torta/Vesper) and `js/render/assets.js` only fetches
manifests for `[...ROSTER, ...ALT_ROSTER]` — Bolt/Shade are unreachable from character select and
render as a generic placeholder puppet if force-selected. Not a live bug, but flag before ever
adding them to the roster: their manifests haven't been through the same visual audit.

## Next Steps
1. When Higgsfield/Chrome is reachable: regenerate the four defective `_hit.png` plates using
   `docs/prompts/REACTION-REGEN.md`, then run the hit-feedback gauntlet round (builder + 3-judge
   blind panel per the established protocol). Still blocked as of 2026-08-11 09:21 — Chrome
   extension shows zero connected browsers; needs Quess to reconnect it, don't keep retrying solo.
2. If Bolt/Shade are ever added to the active roster, run the same render+look attack-pose audit
   on them first (see above — they were skipped as dead code, not verified clean).
3. Optional: re-run the r24/r26/r27/r28 panels against cleaner reference frames if the noted
   reference-weakness caveats ever matter for a stricter re-judgment.
