The finding in one box
A monster approaching an out-of-reach target waits in a range-check poll that has no movement code and no timeout; its staged “Move” animation is what actually carries it forward. A summon cast immediately before the melee leaves the animation driver stale, the Move clip dies about 12 frames in, nothing re-stages it, and the fight waits forever. The fix rewrites nine redundant words inside the poll so a dead clip bounces the state machine back to its own staging state and the attacker resumes walking. Enable it with the Approach-softlock fix toggle.

At a glance

What stalls
The per-action battle state machine, parked in state 0x19 (attack approach)
Where
Battle-action overlay, PROT entry 0898, load base 0x801CE818
Trigger
A summon, then a melee by a monster with no walk animation against an out-of-reach target
Affected
180 of 186 monsters take the affected path; bosses included
Fix
Nine same-size words at overlay offset +0x14D50; --approach-softlock-fix
Confidence
Confirmed - live captures on two emulator cores, replayed with the fix

What the orbit means

The orbiting camera carries no information of its own. The battle round driver sweeps the camera's idle azimuth every frame without consulting the action state machine, so an orbiting camera is what any stalled Legaia battle looks like. The component that stops advancing is the per-action state machine in the battle overlay.

Two independent live captures localise it. A poll-only emulator probe flags any action state held for thousands of frames; both captures park in the same state: 0x19, the attack approach.

Four ways out of an attack

Every physical attack enters approach setup, state 0x14. Its first act is a range check - “within reach” is a size-scaled radius, about 416 units for a boss-sized actor. From there the attack routes four ways:

State routing out of attack setup 0x14 setup in reach 0x1E strike the usual case out of reach, party member 0x19 wait run animation moves them 0x1E strike monster with a walk clip (6 of 186) 0x15 0x16 loop 0x17 0x1E strike the state machine itself steps the monster forward - guaranteed to arrive monster without a walk clip (180 of 186) 0x19 wait-in-range Move clip carries it 0x1E strike if the clip dies: no movement code, no timeout - the poll runs forever
The bottom lane is where almost every monster melee lives - and the only lane whose forward motion depends on an animation staying alive.

The decisive branch is the walk gate. Out of reach, a monster attacker needs its approach-transition clip - action tag 0x20 in its per-monster action table. If the tag is missing, setup stages the ordinary tag-1 “Move” locomotion clip instead and drops into the wait-in-range poll. A sweep of the monster archive puts numbers on it: 180 of 186 monsters have no tag 0x20, bosses included. All 186 carry the Move clip - the float or walk cycle the enemy viewer shows.

An approach the state machine does not perform

The two approach mechanisms differ in one property. The walking states 0x15–0x18 contain the state machine's own stepping code - a monster in that chain is moved by the engine. The fallback state 0x19 contains none: it re-derives facing, re-polls the range check, and on failure bumps a counter that nothing reads as a timeout. All movement comes from the staged animation's playback: the Move clip slides the actor along its facing at about 19 units per frame.

Position captures of ordinary play show this working every time: a healthy boss melee starts out of reach (438–1,078 units against a ~416 reach - standard formation spacing is out of reach; the models are large enough that it reads as adjacent) and the Move clip walks the boss in over 28–67 frames. The path fails only if the animation stops, and no code can observe that it stopped: the clip is staged once, in 0x14, and never again.

Healthy versus parked approach, measured from live captures frames since the approach began distance to target 0 416 1022 reach (~416, size-scaled) in reach at ~28 frames → strike healthy melee: Move clip playing, ~19 units/frame clip dies at ~12 frames frozen at 786 > reach - polls forever, battle over
The same fallback path, ~19 units/frame in both - until the staged clip dies. Nothing re-stages it, and state 0x19 has no timeout.

The trigger: a summon, then the melee

The second capture logs the actor's animation pair - staged clip versus playing clip - every frame, which pins what kills the clip. Summons relocate every combatant for the cinematic: the boss is parked ~2,500 units off-arena while his hit-reaction clip plays, then restored. When his very next action is the melee, the freshly staged Move clip terminates about 12 frames in - the staging round-trip leaves the animation driver holding stale state, so the new clip reaches its end condition almost immediately.

  • Any intervening action resets it. Summon → another combatant's turn → melee runs the same clip 64 frames to a clean hit.
  • It reproduces on demand. Cast a summon, stall until the boss's melee is the next action, and the approach parks.
  • It matches the folklore. Late-game bosses (walk-less, contact attacks, long fights where summons are routine), every region, apparently random - because it needs the summon-then-melee adjacency and an out-of-reach target in the same round.
  • It is not an emulator artifact. The same recipe parks under both PCSX-Redux CPU cores with an identical onset. It is sensitive to when the summon's restore lands relative to the melee, which follows CD-drive latency - so an emulator that reads ahead may rarely land in the window while hardware does occasionally.
Frame-exact onset from the capture
v26536  summon cinematic: boss staged off-arena to (0,-2048),
        his damage-reaction clip plays (pair 2/2), restored, pair -> 0/0
v26867  summon action ends
v26873  boss melee starts DIRECTLY next - 0x14, target ~1022 away -> fallback
v26876  0x19, pair 1/1: Move clip ENGAGED, sliding ~19 units/vsync
v26888  pair 0/0: clip DEAD after ~12 vsyncs / ~236 units
        frozen at ~786 (> 416 reach) -> polls forever  = the softlock

The pair is actor+0x1DA (staged clip) / actor+0x1D9 (playing clip). Which latch in the animation driver goes stale across the staging round-trip - a frame cursor or a clip-length word - is the one detail left open; the fix does not depend on it.

The fix: teach the poll to re-stage

Two fixes are possible. Retargeting the walk-gate fallback straight into the strike (one word - attack from wherever you stand) closes the softlock but removes every monster's approach walk, because out-of-reach is the norm. The shipped fix addresses the defect itself: the dead clip that nothing re-stages.

There is no free space for new code - every verified-dead run in the executable is occupied by other patch features - so the guard replaces nine redundant words inside the poll itself. State 0x19 recomputes the actor's facing every frame, but the target does not move during an approach and both neighbouring states recompute it anyway. Nine words with no observable effect, exactly where the guard needs to live.

The guard reads the staged-clip byte each poll. While the clip is alive nothing happens - healthy fights are byte-identical. If the clip is dead while the poll still fails, the guard sets the state byte back to 0x14. That single write is enough because the staging logic already exists in retail: the 0x14 arm re-runs next frame, re-checks the range, re-stages the Move clip, and the attacker resumes walking. If the clip dies again, the guard fires again - a stuttering but monotonic approach that always arrives.

The nine words, before and after
The nine-word window stock: facing recompute (redundant during an approach) 801e3568 lh a0,0x38(s8) 801e356c lh a1,0x34(s8) 801e3570 lh a2,0x38(s3) 801e3574 lh a3,0x34(s3) 801e3578 jal 0x80019b28 801e357c _nop 801e3580 addiu v0,v0,0x800 801e3584 andi v0,v0,0xfff 801e3588 sh v0,0x46(s3) target is static; 0x14 and 0x1E both re-derive this same size patched: the re-stage guard 801e3568 lbu v0,0x1da(s3) staged clip? 801e356c lui v1,0x8008 801e3570 lw v1,-0x42dc(v1) battle ctx 801e3574 ori a0,zero,0x14 801e3578 bne v0,zero,+3 alive → skip 801e357c _nop 801e3580 sb a0,0x7(v1) dead → state 0x14 801e3584 nop 801e3588 nop falls into the unchanged range-check call
One same-size nine-word rewrite at overlay offset +0x14D50. No injected routine, no reclaimed dead space, no new behaviour.

The walk gate that selects the lane: 801e3260 li a1,0x20 scans the action table for the approach-transition tag via FUN_80050E2C; not found → li a1,0x1, stage the Move clip into actor+0x1DA, jump to the 0x19 poll. Party reach comes from the static table DAT_80078870 = {256, 384, 1024}; monster reach from the size-scaled check FUN_8004E2F0.

The same bounce protects a party attacker whose run clip dies. The one shape it cannot rescue - a monster with no Move clip at all - does not exist: the roster sweep finds zero.

Apply the fix to your disc

Get the fix
Open the in-browser ROM patcher, load your disc image (processed entirely in the tab, never uploaded), tick “Approach-softlock fix”, and download the patched image or a PPF patch.
legaia-patcher randomize --input DISC.bin --approach-softlock-fix

The fix is seedless, composes with every other patch option, and the Balanced / Full Chaos presets enable it by default. See the patcher reference.

How we know

EvidenceAddressWhat it proves
Battle-action state machineFUN_801E295C (PROT 0898)The 0x14 → 0x15..0x19 → 0x1E routing; 0x19 has no movement code and no timeout
Battle round driverFUN_801D0748Camera orbit runs unconditionally - the symptom is generic
Action-table scan / range checkFUN_80050E2C / FUN_8004E2F0Tag 0x20 selects the walk chain; reach is size-scaled (~416 for a boss)
Monster archive sweepPROT 867180 of 186 monsters lack tag 0x20; all 186 carry the tag-1 Move clip
Two live park capturesPCSX-Redux poll probeBoth stall in 0x19; animation pair +0x1DA/+0x1D9 goes 1/1 → 0/0 ~12 frames in
Reproductionrecompiler + interpreter coresSummon → melee parks on demand with identical onset
Disc oracle + replays+0x14D50, nine wordsExactly nine words change; both park states replay to a completed round with only those words poked

The full evidence trail is on settled RE threads.