Files
SirRoboGarage/ModularBot_garage
SirStone ed25ce29ad STRAFE: range control (tilt) + corner-stall escape; shipped TFIL default untouched
Task j111. Two changes to the TR_MOVEMENT=strafe engine, both OFF the shipped
tfil path; the binary default is still tfil.

RANGE CONTROL (a hypothesis under test, no default changed elsewhere):
the body is still pinned ~perpendicular to the threat, but the line is tilted
by the range error: lineAngle = threat + 90 + appliedTilt, with the tilt zero
inside +/-TR_STRAFE_RANGE_TOL around TR_STRAFE_RANGE (200 px, chosen because it
is exactly TR_POWER_FAR_DIST) and clamped to +/-TR_STRAFE_TILT_MAX. A tilt alone
cannot change range (the picker chooses both ends at random), so the picker also
PREFERS the end that reduces |distance - target| with a probability that grows
with |tilt|; both ends stay possible. The tilt sign is aligned to the ENEMY
bearing, since  is the bullet direction (roughly its opposite) when a
bullet is in flight. Knobs: TR_STRAFE_RANGE (200), TR_STRAFE_RANGE_TOL (25),
TR_STRAFE_TILT_MAX (15), TR_STRAFE_TILT_GAIN (0.10), all registered in
env_report.nim (emit + knownEnvNames). NOT claimed to be better: j107 measured
that drifting 25-30 px closer made damage/run and wins WORSE.

CORNER STALL (a real defect): a line whose in-arena candidate set was empty set
targetValid=false and kept driving on the last sign, so the bot could oscillate
inside a corner tile forever. Three defenses: (1) a deterministic corner guard
projects the outward component off the line whenever BOTH ends are outside, so
the line becomes wall-parallel and a candidate always exists; (2) a degenerate
line (<=1 candidate) falls back to a radial search for the coolest in-arena
tile and commits the sign; (3) a commanded move with no displacement for
StuckFlipTicks (5) ticks flips the sign. Both warnings now reach the [strafe]
log.

GUI/log: the tilt is drawn as the existing strafe line (it is lineForward), plus
a green/red ray toward the enemy (length = |distance-target|) and white text
d=.. tgt=.. tilt=..; a red disc marks a stuck tick. The existing overlays and
the j110 heat grid are unchanged.

Gates (offline, kinematic replay of the DrussGT fixtures; see
common_libs/tests/measure_strafe_range_stall.nim): on the j110 field all four
corners that were 100% confined inside 72 px / 22.6 px max before now escape
(<=2.6% confined, 209-741 px); the achieved |distance-200| falls on 3 of 4
fixtures (mean -16% to -30%); mean |turnRate| and the 8.00 px/tick speed are
essentially unchanged (no-turn property survives). Reversal-interval entropy
falls 5.85 -> 5.31 bits (still above TFIL's 5.09): the range bias costs some
reversal randomness while closing.
2026-09-25 23:39:28 +02:00
..