Fishing minigame
The party stands on a pond shore, casts with a power meter, coaxes a bite by reeling in a rhythm, then fights the hooked fish on a tension gauge. A landed fish pays fishing points, which the venue’s prize counter trades for items. All three hosts of the port run the whole game as one session type.
At a glance
- Overlay
- PROT 0972 at base
0x801CE818; venue scene bundleother1 - Mode driver
FUN_801CF3BC, state wordDAT_801D926C, jump table0x801CEBE0- Lure / bite tick
FUN_801D26CC: band roll, strike roll, species pick, line-break and reel-in exits- Fish AI + tension
FUN_801D4004, gaugeDAT_801D9168,0..0x1000- Cadence recogniser
FUN_801D3DB4over the templates atDAT_801D87D4- Tables
- Species
0x801D81A4(10 records, stride0x28); spawn0x801D8334/0x801D8434; prizes0x801D8088/0x801D80D0 - Saved state
0x8008444C..0x8008446C: points, best catch, lure, rod, cast counter, one-time prize bits- Port
- Rules crate
engine-fishing(PondSession); draws inengine-ui::fishing
Getting there
The door is the mode-24 minigame warp: field-VM op 0x3E with op0 = 100 (sub-id 0) sets game mode 0x18 and loads the overlay. It is the ordinary scene-backup, overlay-load, return-to-field sequence, so the game returns to the exact field state it suspended. The mechanism is on the field / event VM page.
A disc-wide walk finds the door at exactly two sites, both signboards on the overworld. Which one the party came from picks the venue: state 1 compares the departure scene’s id against two immediates and selects Buma or Vidna, which in turn selects the prize page and the spawn page. Both pond areas are in the bundle’s one map.
The warp is the last op of the signboard’s own talk record, which the action button runs like any town conversation. Before it, the board refuses on a frozen lake (Karisto only, system flag 0x378 clear), on no fishing rod and on no lure; then it asks whether to fish, and a yes fades the screen to white and waits 48 frames before the warp. The record is laid out on the world-map internals page.
Fishing loads no music of its own; it keeps whatever the departure scene was playing. The driver has no direct caller either - it is the tick word of an actor template the init spawns.
State machine
Reel input
| Input | Retail meaning |
|---|---|
| Cross | reel A; also casts and locks the power meter |
| Square | reel B; also casts and locks the power meter |
| R2 | reel-direction mirror, read alongside the reel buttons |
| Circle, L2 | the abandon edge - not a cast |
| Triangle, Select | open the hub menu from the idle shore |
Holding both reel buttons resolves to reel A. The cadence recogniser keeps a 16-entry ring of {button, held frames} and matches a window of that history against the rhythm templates decoded from the disc. A match selects a cast band directly; with no match the band is the current frame’s random roll.
The port’s cast input differs from retail by choice: Circle casts and locks the meter, Cross and Square only reel.
Which fish bites
species = spawn_table[lure * 8 + band] lure 0..2, band 0..4
| Roll (12 bits) | Band | Share |
|---|---|---|
r <= 0xC00 | 3 | about 75.0% |
0xC00 < r <= 0xE70 | 2 | about 15.2% |
0xE70 < r <= 0xF38 | 1 | about 4.9% |
0xF38 < r | 0 | about 4.9% |
No roll and no template maps to band 4. The rarest band has its own gate, which is what the Spirit Fish write-up follows. A matched template holds its band for the next 64 frame-steps.
The fight
While hooked, a small behaviour machine (run, dart left, dart right, dive) moves the fish and modulates its pull, re-rolling from the species record’s cutoffs when each behaviour’s timer runs out.
| Condition | Effect |
|---|---|
| the line’s screen position leaves the play area | line-break latch |
| hooked and the fish has run far out | tension rises by step * 300 on its own |
| tension at the ceiling | one-in-ten roll per frame to break |
| latch set while the lure is in the water | line breaks: one lure is consumed |
| reeled all the way in with a fish on | the catch |
Scoring and the prize counter
points = fish_base_value * (strength + 0x9C0) / 0x32000
The points are added to the saved counter, clamped to 999999, and a catch that beats the saved best replaces it. A per-catch latch scores a fish once.
The prize counter spends the pool on six rows per venue. A row is a 12-byte record with a limit - 1 for a one-time prize latched in a saved bitfield, 99 for a repeatable one. Row 0 is hidden until strictly affordable, so each venue’s top prize only appears once the pool exceeds its price.
See also
The species table column by column, the cadence templates, the fish-weight sum, the venue spawn tables, the line, rod and shore actors and the whole HUD are in docs/subsystems/minigame-fishing.md.