# Shootout attempt rules and automatic start — 2026-10-31-r2

## What changes

jdc reported that shootouts permit losing the puck or retreating and seem to
wait for button input before starting. The old native watcher ends on keeper
possession, a retouch after the first loose shot, its flight window or the normal
attempt timeout. It has no pre-shot progress/stillness check. Its long human
setup countdown can be shortened by controller direction input, explaining the
apparent dependency on pressing something.

The human400-tick and CPU100-tick setup countdowns now both use60. In the native
late-OT fixture, with no input after the two menu Start presses, the first human
attempt becomes live after180frames (~3seconds), versus619(~10.3seconds). Both
ends are tested. The initial fixture only sets tied late-OT time and controller
side; it never forces the attempt, moves actors/puck or supplies an outcome.
Actual first-live time includes the native transition, not just the immediate.

A small attempt-only helper now follows signed16.16puck progress in the shooting
direction. After voluntary shooter movement, an unshot puck may not retrace more
than8world units from its high-water mark, stop for12consecutive native
observations or travel beyond Y264outside the goal mouth (absX>21). Fractional
forward movement resets the stop counter, including movement below the old
high-water mark. This avoids rejecting a valid diagonal start during native
stick-to-puck settling. These explicit allowances tolerate animation/update
quantization; they are not NHL measurements or exact referee simulation.

Native centre-possession is automatic, so it does not itself arm the stop rule:
the shooter gets reaction time before actually moving. The original attempt
clock still expires; this is not unlimited time. Announcement, pause, foreign
views and ended attempts do not charge the new stop counter. A new attempt
resets the record. No score, successful outcome, RNG or controller input is
injected by the release code.

## Official rule comparison

NHL2026–27 Rule24.2 concerns **puck movement toward the opponent goal line**.
Skating backward or turning the body is not itself the rule. Temporarily losing
an unshot puck is not automatically a failed attempt if it keeps moving forward.
After shooting, the attempt does not allow another shot/rebound touch by the
shooter; the direct post/crossbar-to-keeper-to-goal exception must remain possible.
Rule84.4 applies the penalty-shot execution rules to the shootout. Primary source:
[NHL2026–27 Official Rules,24.2 and84.4](https://media.d3.nhle.com/image/private/t_document/prd/i9yumvyaojps5kixzaxz.pdf).

The existing native watcher already distinguishes owned windup from a released
shot: it observes the first loose shot, then ends on reacquisition. A private
68000 boundary fixture calls those actual instructions and observes the native
miss queue: no ending during windup, none at release, one on retouch and still
one on the repeated call. Keeper ownership also retains its original end path.
The new pre-shot check stops acting once native shot flag5 begins, allowing the
original shot/deflection trajectory and native goal detection to finish. No
accepted-pickup, keeper-contact or general physics hook is introduced.

The existing three-per-team, early-clinch, paired-sudden-death, one-team-decider
and season/statistics handling retain their tests. This release does **not**
claim complete NHL parity: the native five-roster-slot rotation can repeat
before every eligible roster player has shot, and there is no explicit360spin
detector. Those remain recorded in TODO.md. User-selected5/7/10/20-minute OT and
custom Full/Light/Mini playoff formats are intentional project choices.

## Code, hooks and RAM

`shootout_rules.s` lives at2DAA00(max0x600bytes). Export+0 watches the existing
F2F4attempt watcher; +4 initializes each attempt and sets its countdown.

| Address | Parent bytes | Released bytes | Purpose |
|---|---|---|---|
| F280 |31FC0190C31A|4EB9002DAA04| fresh attempt/countdown |
| F298 |0064|003C| CPU countdown100→60 |
| F2F4 |48A780003038B7AA|4EF9002DAA004E71| pre-shot progress before native watcher |

Twenty transient bytes F65C–F66F hold magic, actor, phase, stop counter, normalized
high-water puck Y, initial shooter XY and previous puck Y. No SRAM/settings field
is added. The watcher restores full registers and CCR before replaying the two
original instructions, preserving the original word-sized D0 stack save.
`--legacy-shootout-rules --legacy-shootout-start --version 2026-10-31` recreates
the exact parent. Either feature can be separately disabled for diagnosis.

## Tests and limits

`verify_shootout_rules.py` uses54paired explicit native boundary/ABI contexts:
both directions, exact8-unit limit and one-subpixel excess, fractional progress,
11/12stopped observations, forward loose puck, body facing backward, initial
reaction/automatic ownership, announcement/pause/view guards, shot flight,
invalid IDs/keeper role, fresh actor and already-ended attempts. Its private
return observer measures all15registers, CCR/X and the original stack layout.
Those fixtures deliberately initialize RAM; they are not natural human play.

A separate native shot-state fixture retains the actual watcher and records its
queue calls. Four copied-save integrations capture both human shooting ends on
parent/current with no input after menu entry.28paired native input cases cover
idle reaction, diagonal approach, retreat, forward-then-reverse, coasting to a
stop, shooting and repeated shooting input. No actor/puck movement or outcome
is written after the initial OT fixture. A diagonal approach is legal while
moving; once input is released and it actually stops, the new stop rule may end
it. The two ends need not have identical timing or outcomes.

One early private stop counter used high-water progress alone and incorrectly
rejected a diagonal start. The final counter compares the previous observation,
while retaining the separate8-unit high-water retracement boundary. Failed
experiments/reports remain private. Native retouch is boundary-tested, not a
claim that a physical player reproduced every possible keeper/post rebound.

All83exact-source shared suites run:82pass, with only the same inherited
finisher_hold geometry failure; the strict release gate remains FAILED.
All40current ordinary raw trajectories exactly match40fresh2026-10-31 controls.
The retained net fix is separately compared to r13:38raw-exact and2verified
native impact changes, with strict historical comparisons retained. Independent
rebuild, exact parent rollback, four matched AI ablations and original-base IPS
reconstruction pass. No new Hard win-rate search or qualification is claimed.

## Delivery

A fresh2026-10-31-r2 basename replaces the current ROM/IPS on the website, in
Downloads, canonical workspace and Bodin's existing playlist item. An open
RetroArch is never closed; progress cleanup waits for normal exit. Controller
remaps, config and history retain their hashes. See QA_STATUS.json and
SHOOTOUT_RULES_RESULT.json for actual installation state, exact hashes and checks.
