# Shot panel above the score box, retained during replay — r31

Current r7 update: the live charge bar is white at low charge, orange while
charging and solid red at maximum; see [SHOT_COLOUR.md](SHOT_COLOUR.md). The
r31 blink description below is historical. Replay/lifetime behavior is retained.

The shot panel is now **8x5 cells (64x40 pixels)**, the same size as the team/
score box, directly above it at screen x256,y144. HUD map E000 rows18..22,
columns32..39; the native score box is rows23..27. The frame and font remain
native. Interior row1 holds the charge meter; rows2/3 use six cells for compact
`165KMH` and `102MPH` (same units/conversion, no slash/space to fit the box).

In play, the existing smooth32px white/red charge bar is centered inside the
box (x272,y152), retaining the80-sprite bound. Sampling continues through the
swing while the player still owns the puck: the preceding phase<16 filter
stopped the displayed charge at29. The UI now reaches full at native raw31,
the existing full-slapshot boundary, and blinks red before release. This changes
only the meter; shot power, critical chance, physics and sound are unchanged.

On release KMH/MPH are stored in FFF650/FFF652. During automatic replay states
A502..A506, the measured speed and charge freeze. HELD at FFF64E marks that
lifecycle. The HUD box is refreshed through the replay and cleared on the first
normal-rink frame after it, including X+B skip. Ordinary shots retain their
240-frame lifetime; ordinary pause/menu clears the panel as before. New-game
magic initialization clears the replay-hold flag.

The REPLAY title temporarily occupies the crowd meter's tiles. Consequently,
the replay displays the recorded charge with six native HUD dash segments;
live play keeps the smooth red/white bar. This requires no new pattern tiles,
palette writes or DMA. In particular FB00/3BC/3EF remain untouched: those areas
are not safe as permanent shot-meter tile storage. A private prototype using
FB00 was discarded before publication. Native HUD glyph/frame patterns remain
byte-identical throughout the tested shot/replay lifecycle.

## Source and verification

Source: experimental/shotmeter.s,1240bytes at2ED000; ABI+0logic/+4draw unchanged.
New repeatable tests: verify_shot_panel.py and shot_panel_hook.py. Real controller
shots, native crit sound/power, actual puck crossing the goal line and native
automatic replay. P1's measured crit in the screenshot is165km/h,102mph. Fixtures
move other actors aside; no live user save is changed. Timeout/pause cases hold
the released puck away from the net to isolate the display's lifetime.

PASS **8 native cases /161 VRAM checks**: critical forehand goal, short shot,
pads1..4, complete replay, skip, timeout and pause/resume. Checks same-size frame,
actual speed text, fixed speed/charge through replay, clean disappearance,
unchanged native HUD font patterns and sprite-list bounds. Replay entry/exit
checks follow real playback/normal-view state, allowing native fade/load phases.
PASS critical10,critical_flash,navigation14/266,finished9/108,menu_team18/240.
The80 non-dive four-pad goalie cases also pass. The historical home diving
fixture does not catch the puck on either unchanged r30 or r31; it is the already
documented timing-sensitive fixture artifact, not treated as a passed test.

Two full builds are byte-identical. Guarded r30->r31 diff1099bytes, solely the
shotmeter module, ROM title and checksum; every other game module is unchanged.
Original-base IPS234819bytes reconstructed and verified.
SHA2568e45bb86e1728c5933bbe4614a6a89007459b0a88839570f4415b90cde8c48da;
CRC1A35E68D. r31 replaces r30 locally, Downloads, website and Bodin's existing
playlist item. Save/state/remap/history files migrate with identical contents.
Private evidence: work/shot-panel-replay-20261026-165147/.

```sh
python3 tools/experimental/verify_shot_panel.py /private/current.bin /private/panel-tests --state /private/four-native.state
```
