# Crit flames follow the puck through a camera pan — r33

jdc reported a red puck and the Twin Cobra bomb sound, but no visible flame
trail in Edmonton–Chicago: Mini, Easy,5-minute periods,Fighting Off. Both
red puck and the bomb sound mean the critical path succeeded; difficulty,
crit probability and the opposing club are not the explanation.

## Reproduction and cause

A native private Mini fixture confirms Home10EDM,Away5CHI,slot3,DIFF2,
period0(5min),Fighting0. Twenty real full forehand Bouchard shots all crit.
The six flame sprites are present and the three VRAM patterns are correct,
but their historical **screen coordinates** almost coincide while the camera
follows the shot. The six circles overlap into a tiny orange/red dot. Later,
when the camera stops near the net, they may spread out again. Thus the same
crit can look different depending on the camera's movement and shot position.
There is no Chicago-specific condition in the effect.

Before(r32): the six circles' median vertical span at release+8frames was11px.
After(r33), same20attempts: **42px**, forming a visible trail behind the puck.
The screenshots show the same first shot at the same relative time:

![Before: overlapping circles](/nhl94/img/crit-flames-before-r32.png)
![After: separated flame trail](/nhl94/img/crit-flames-after-r33.png)

## Source

`tools/experimental/trail.s` at2E4000 retains the existing two entry points,
nine-history length, six sprites, three patterns, DMA timing,80-sprite bound
and24-frame afterglow. HIST now holds camera-independent anchors:

```
x_anchor = puck_x + 285
y_anchor = 233 - puck_y - puck_height
```

Drawing projects each old anchor with the camera used for that draw. The
other-view branch first normalizes the native puck sprite into the same
coordinate space, so it can use the same drawing path. No extra RAM or VRAM,
no changed tile art or palettes. The transient history is repopulated within
nine frames if an old mid-shot savestate is loaded; season SRAM is unchanged.

This is a rendering fix. Crit eligibility/chance/power, native puck velocity,
height, the long-shot goalie rule, audio, controls and season logic have no
changed code. Source/header/checksum diff from r32 is115bytes, all inside
trail.s's reserved512-byte bank or the title/checksum fields. New routine
size362bytes, below the unchanged tile data at2E4200.

## Verification

Permanent rigs: `verify_critical_trail.py` and `critical_trail_hook.py`, using
the native shooting harness and explicit private fixture directory. The
Mini fixture and per-shot reports/screenshots are under
`~/.config/retroarch/roms/claude/work/flames-chicago-20261026/`.
Accepted comparison: `trail-regression-pass/`.

```
python3 tools/experimental/verify_critical_trail.py current.bin /private/trail \
  --fixture /private/mini-easy-fixture --baseline preceding.bin
```

PASS20/20 native crits, six resident flame sprites per sampled shot, correct
patterns and **1,424/1,424 camera/world-path checks**, including afterglow.
The identical old build fails0/1,424. Geometry checks preserve world-path
spacing and share a camera transform within one pixel of native frame
quantization; the camera can update between frontend samples. VRAM is
host-word-swapped in GPGX states: swap each ROM art word before comparing it.

PASS critical10, velocity88, flash lifecycle, shot panel8/161VRAM(including
four pads and replay), navigation12/228. One complete autonomous5-minute-
period game finishes and saves a season result. Exact second build and
original-base IPS reconstruction verified. Save/remap/state/history migration
reports retain content hashes; one current season playlist item on Bodin.

Release2026-10-26-r33 replaces r32 under the standing release policy. The
r32 strong-crit arithmetic fix and its complete shot audit remain included.
