# Completed-season main-menu team label — 2026-10-25-r30

The finished-slot free-selection behaviour described here was superseded by
2026-10-26: completed slots are read-only results and retain their saved club.
See FINISHED_SEASONS.md. The r30 reproduction below is historical.

After a season finished, changing the Team row updated the native selected
club, logos and player card, but the text still displayed the previous club.
This affected completed Full, Light and Mini seasons.

## Cause and fix

`season/seasonmenu.s force` sets SELV at FFE3F2 for the season menu. A completed
season returns with FORCED at FFE3F0 cleared, before refreshing USERW at FFE3F4.
Home at FFD04C is freely selectable at that point. The `teamrow` hook at F7C72
still redirected the text renderer to USERW merely because SELV was set.

Only use USERW when FORCED is nonzero. When FORCED is zero, retain the native
Home pointer. The text now follows exactly the same selected club as the logos
and player card. Active away games still use USERW so the Team row shows the
user's club even when it is the visitor. Preseason selection, season locks,
playoff selection and the saved season's actual owner are unchanged.

The module grows from 1886 to 1894 bytes at 2F9800..2F9F65, leaving 154 bytes
before the leaders at 2FA000. The builder resolves and updates the moved
teamrow/labelhook/mainlr/skipmatch targets. No new RAM or SRAM. The statistics
module at 2E3000..2E3FFF is byte-identical to r29, including its column alignment,
spacer row, orange sorting and Xbox B help.

## Evidence

Native reproduction on r29: Home30 -> 31 -> 30, while USERW and the Team text
stayed30; the image changed to Winnipeg while the row still said Washington.

`experimental/verify_menu_team.py` observes the club passed by the actual
teamrow hook to the native text renderer, using a private ROM probe. Eighteen
cold-boot cases cover Full/Light/Mini, champion/eliminated/missed playoffs,
all32 clubs in both directions with wrap, pending new seasons, active away
games and Teammates. All 798 displayed/actual-club checks pass. The old ROM
fails the completed-season checks. Tests preserve season ownership/progress.

Existing season navigation: 12 cases, 228 full-circle/reverse checks pass.
An unmodified production ROM, normal controller input and the current user's
save show Winnipeg text and logo together after one Right. The battery save
is byte-identical before/after. Exact rebuild, guarded 962-byte diff (menu,
resolved hooks, title/version and checksum only), probe exclusion and IPS
reconstruction against the original v5.1W base pass.

Run:

```sh
python3 tools/experimental/verify_menu_team.py /private/test.bin \
  /private/menu-tests --seed /private/current.srm
```

r30 replaces r29 in canonical/Downloads/site ROM+IPS and Bodin's same item.
Six-button remaps, saves and matching states migrate. Launch normally at the
main menu so the selection can be tested. No extra backups.

SHA256: 98fa9b6c17afa0305bf154ad4886320d4f046fc38312f40ee1b275e4801cf770.
CRC32: 31257AC4. Private evidence: `work/menu-team-20261025-235212/`.
