The BT_GOTO beeline never actually closed on a target -- three separate faults:
1. It was gated behind `if(gBTDrive.forced)`, and `forced` was set ONLY by
BT_AUTODRIVE -- a chicken-and-egg where the block that would drive was gated
on the drive already being on. So BT_GOTO alone just turned in place (the
"stall"). Fix: BT_GOTO enables forced mode itself AND supplies its own
forward throttle (a beeline must drive, not only steer), cutting the throttle
inside a stop radius (weapon range for "enemy", so it holds + shoots).
2. Steering used the gDriveHeading SCALAR MIRROR (seeded to 0), but MP pilots
spawn facing a non-zero heading -> it steered the WRONG way. Fix: heading
error from the mech's ACTUAL forward (localToWorld's -Z axis), signed angle
to the target.
3. The goto turn was routed through controlsMapper->turnDemand, which zeroes out
in -net mode (the mapper key-bridge only shapes the local viewpoint mech
there) -- the heading froze and A drove straight past B. Fix: apply the goto
turn to the orientation integration DIRECTLY (if gBTGotoActive, turn=
gBTGotoTurn), after the mapper read.
Verified 2-node one-box: A with BT_GOTO="enemy" ALONE (no autodrive) drives
dist 1673->231m, holds at weapon range, mechPicks=59, autofire -> B hdlr=192,
DESTROYED -- a fully automated human-style cross-pod KILL via the real beam
path (not the FORCE_DMG hook). Solo un-regressed (plain autodrive still drives;
goto="enemy" resolves the enemy, mechPicks=59, no crash). BT_GOTO_LOG traces
the beeline.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>