The finding in one box
The hooked species is a table lookup: lure row × “band” column. The band roll only ever outputs 0–3. Band 4 - the Spirit column - is written by one store behind a strike-time gate: over 50 lifetime casts (a saved counter), the counter even at that instant, Normal Lure, the third rod, band 0 active, and then a 1-in-16 roll. The “Good!” splash fires for any of four reel cadences, and the matched cadence's id becomes the band - so only the one ending in a Square tap selects the rare band, while the natural rhythm selects the most common one.

At a glance

Where
Fishing overlay, PROT entry 0972 (load base 0x801CE818)
Species table
Per venue, 3 lure rows × 5 band columns; parser legaia_asset::fishing_species
Saved state
Lifetime cast counter in the save block - the gate's hidden precondition
Confidence
Confirmed - MIPS disassembly, checked against a retail USA disc
Used by
Playable fishing demo · curated fishing tables

The spawn tables

When a fish strikes, the hooked-fish handler picks the species with species = spawn_table[lure*8 + band]. The equipped lure picks the row; the current cast band (0–4) picks the column. The species agree cell-for-cell with the community tables - the gap is in how band 4 is reached.

Buma / lureband 3 (~75.0%)band 2 (~15.2%)band 1 (~4.9%)band 0 (~4.9%)band 4 (gated)
LightHigh ChargerHigh ChargerJackJackSpikefish†
NormalHigh ChargerJackHigh ChargerHigh ChargerSpirit
HeavyChargerFly PieLippianDevourerSpikefish†
Vidna / lureband 3band 2band 1band 0band 4 (gated)
LightJackJackFly PieJackSpikefish†
NormalHigh ChargerFly PieSpikefishFly PieSpikefish†
HeavyFly PieFly PieChargerOctobanBaraba

† Dead cells. Each venue's band-4 gate hardwires the lure it fires on (Normal at Buma, Heavy at Vidna), so band 4 is only ever read on the row carrying the rare fish. The other Spikefish cells are unreachable in retail play - only a developer shortcut (debug flag + R1 at the strike) forces band 4 unconditionally.

How the band is chosen

Band assignment has two phases. While the lure is in the water, the band is re-derived every frame: a cadence match pins it for a ~64-frame hold window, otherwise the frame's random roll replaces it. At the instant a fish strikes, the venue's gate may upgrade band 0 to band 4. Everything after the strike is deterministic.

Band selection pipeline while waiting (line record > 500, nothing hooked) reel-cadence match band = template id, held ~64 frames random roll re-rolled per frame: 75 / 15 / 5 / 5 % cast band 0 – 3 strike band-4 gate band 0 → 4 if all pass species = row[lure] col[band] gate (Buma): casts > 50 and even · Normal Lure · third rod · band 0 · then 1 in 16 no pass → band used as-is; nothing else writes band 4
The two phases of band assignment. The gate is evaluated once, inside the strike branch of the hooked-fish handler, immediately before the species lookup.

The band roll

While the lure sits deep enough (line record over 500 units) and no fish is hooked, the band re-rolls on every frame no cadence holds it: rand() & 0xfff against three fixed cutoffs. The published 184/48/16/8-out-of-256 estimate has the right shape; the real cutoffs sit slightly lower at the rare end. No outcome maps to band 4 - there is no fifth cutoff.

Band roll distribution actual roll - rand & 0xfff vs cutoffs 0xc00 / 0xe70 / 0xf38 (out of 4096) band 3 · 3073/4096 · 75.0% 15.2% 4.9% 4.9% published community estimate (out of 256) band 3 · 184/256 · 71.9% 18.8% 6.3% 3.1% band 4 has no segment in either bar: no roll outcome maps to it. band 0 (solid) is the band the gate requires - ~1 roll in 20.
Whatever band is active at the instant the fish strikes is the one the species lookup uses.

The reel-cadence recogniser

Before each frame's band roll, the game consults a reel-cadence recogniser: a 16-slot ring of {button, held-frames} reel history, walked backwards against four templates, each hold matched with ±10 frames of tolerance. A match does three things:

  • fires the “Good!” splash;
  • stores the matched template's id as the band;
  • arms a ~64-frame countdown during which the band holds instead of re-rolling and the bite roll runs at roughly twenty times its idle rate.

A strike can only land on a frame where a reel button is held, so the final press of the cadence doubles as the bite window.

Performing the band-0 cadence

Setup: cast deep (the cadence check only runs once the line record exceeds 500), then press either reel button briefly and release so the first rest starts from a measurable point. Then:

  1. Hands off for about two-thirds of a second (0.52–0.82 s accepted).
  2. Hold ✕ for about 0.4 s (0.27–0.57 s), then release.
  3. Hands off again for about two-thirds of a second.
  4. Press and hold □. The splash fires about a tenth of a second into the hold: band 0 is set. Keep holding - the boosted bite lands only while a reel button is down. If nothing bites, release and repeat from step 1.
The band-0 cadence on a real-time axis ✕ any brief press first 1 hands off 2 hold ✕ 3 hands off 4 hold □ rest ≈ ⅔ s ✕ ≈ 0.4 s rest ≈ ⅔ s □ hold… accepted 0.52 – 0.82 s accepted 0.27 – 0.57 s accepted 0.52 – 0.82 s splash ≈ 0.1 s in “Good!” · band 0 set · bite boosted ~1 s 0 s 0.5 s 1.0 s 1.5 s 2.0 s Times assume 60 Hz. Each hold is matched with ±10 frames (≈ ⅛ s) of slack - rhythm, not frame precision. No bite can land during the rests (a strike requires a reel button held), so the quiet phases cost nothing.
The whole cadence spans ~2 seconds; the final □ press is held past the splash so the boosted bite window stays open.

The hold window is the load-bearing part. A rolled band 0 exists only on the frames the dice produce it; a cadence-set band is pinned for the full window, and the boosted strike usually lands inside it. The four templates:

The four reel-cadence templates template 0 → band 0 rest 40f ✕ 25f rest 40f □ 15f selects the rare band template 1 → band 1 □ 15f ✕ 25f rel template 2 → band 2 □ 15f rest 40f □ 15f template 3 → band 3 ✕ 25f rest 40f ✕ 25f the natural reel rhythm Durations in frames at 60 Hz, each matched ±10. ✕ = reel A (Cross) · □ = reel B (Square). All four templates fire the same “Good!” splash - the splash reports a match, not which band was set.
Matching template 0 sets band 0 deterministically, replacing the ~4.9% roll. Rhythmic ✕ reeling matches template 3 and sets the most common band - with the same splash. Template 0 is the only cadence ending in a Square tap, which is the association players report between Square presses and Spirit catches.

The band-4 gate at the strike

When a strike lands (reel held, per-frame strike roll passed, nothing hooked yet), one branch immediately before the species lookup decides whether an active band 0 upgrades to band 4. Every condition must hold at once:

ConditionBuma (Spirit)Vidna (Baraba)Visible to the player?
Lifetime casts (saved counter)> 50no thresholdNo - lives in the save block, never displayed
Cast counter parityevenevenOnly as the lure's drift direction on wall contact
LureNormalHeavyYes
Rodthird rodthird rodYes, but no table records it
Band active00Only via a template-0 “Good!”
Final roll1 in 161 in 4No

The cast counter increments once per cast when the lure lands, persists across sessions and is saved with the game - band 4 at Buma is unreachable inside the first 51 lifetime casts. With either other rod equipped the gate short-circuits and band 4 cannot occur.

The gate as code
if (venue == Buma) {                          // DAT_801d90d0 == 0
    if (0x32 < casts                          // > 50 lifetime casts  (_DAT_80084460)
        && (casts & 1) == 0                   // cast counter EVEN at this instant
        && lure == 1                          // Normal Lure          (_DAT_80084450)
        && rod  == 2                          // third rod            (_DAT_80084454)
        && band == 0)                         // rare band active     (DAT_801d90e8)
        if ((rand() & 0xf) == 0)              // ... then 1 in 16
            band = 4;                         // -> Spirit
} else {                                      // Vidna
    if ((casts & 1) == 0 && lure == 2 && rod == 2 && band == 0)
        if ((rand() & 3) == 0)                // 1 in 4, no cast-count threshold
            band = 4;                         // -> Baraba
}

Rendered from the strike branch of FUN_801d26cc; the species lookup follows directly. The cadence hold countdown is armed to 0x40 and also feeds the strike credit (credit = countdown + 2), which is where the ~20× bite boost comes from.

Effective probabilities

Per-catch Spirit probability at Buma, assuming a deep cast and a landed strike:

SetupPer catchDerivation
Third rod, Normal Lure, 50+ lifetime casts, template-0 cadence held at the strike≈ 1/321/16 gate roll × ½ counter parity; the cadence pins band 0 and boosts the bite ~20× for its hold window
Third rod, Normal Lure, 50+ lifetime casts, no cadence≈ 1/660199/4096 band-0 roll × ½ parity × 1/16 gate roll
Either other rod, or under 51 lifetime casts0The gate fails before the random roll

Under a flat 1/32, 250 catches without a Spirit has probability ~0.04%; under the gated model without cadence input the same drought has probability ~68% - long empty sessions are the expected outcome. Baraba at Vidna has no cast-count threshold and a 1-in-4 roll, matching its far higher observed rate.

Passing the gate selects the species; landing it is a separate problem. The Spirit carries the species table's largest pull factor, so a gated strike can still be lost in the reel.

Player reports, mapped to mechanisms

Reported behaviourMechanism
Square presses associated with Spirit catchesTemplate 0 - the only cadence that sets band 0 - is the only template ending in a Square tap
Pond position affects resultsCells flagged 0x4000 in the floor grid raise the strike rate, so the gate is evaluated more often (the species table is unaffected)
Cast distance mattersBelow 200 line units no strike occurs; below 500 the band never re-rolls and the cadence check never runs
“Good!” improves the oddsAny match boosts the bite rate ~20× for ~1 s, but only template 0 sets band 0; the other three set bands 1–3 with the same splash
1/32 with a “Good!” on Normal LureThe effective rate when rod, cast-counter and cadence conditions all hold; those conditions are not visible
Long droughts despite the right lureExpected under the gated model - and certain with either other rod or under 51 lifetime casts

How we know

Everything above is read from the MIPS disassembly of the fishing overlay (PROT entry 0972) and checked against a retail USA disc. No Sony-owned bytes appear here - only addresses, offsets and decoded parameters. The full subsystem reference is minigame-fishing.md.

Function / dataAddressWhat it proves
Hooked-fish handler (strike branch + band-4 gate + species lookup)FUN_801d26ccThe gate conditions, the 1/16 and 1/4 rolls, spawn_table[lure*8 + band]
Reel-cadence recogniserFUN_801d3db4Four templates, ±10-frame tolerance, template id stored as band, hold countdown 0x40
Reel-button decodeFUN_801d7450Cross = reel A (pad bit 0x40), Square = reel B (0x80)
Species table0x801D81A4Per-species pull factor (Spirit largest)
Venue spawn tables0x801D8334 / 0x801D8434The Buma / Vidna lure × band grids above
Cadence templates0x801D87D4The four button/hold sequences
Cast band / venue / cast counter / lure / rodDAT_801d90e8 / DAT_801d90d0 / _DAT_80084460 / _DAT_80084450 / _DAT_80084454The five inputs the gate reads; the cast counter sits in the save block
Band-roll cutoffs0xc00 / 0xe70 / 0xf3875.0 / 15.2 / 4.9 / 4.9 %, no fifth cutoff