The user suspected these were bugged. They were, and the verdicts are not
uniform - three genuinely broken, one merely sloppy, one fine:
- WaveSurfer: GENUINELY BUGGED, worst of the five. (a) The enemy velocity
decomposition was sin/cos SWAPPED - enemyVx used sin and enemyVy used cos,
while Tank Royale is 0 deg = East, CCW+, so it must be cos for X and sin for
Y. Its linear-prediction gun was aiming at a reflected position. (b) The wall
escape flipped strafeDir on EVERY tick the bot was inside the wall margin,
so instead of turning away it flip-flopped in place: measured standing still
(speed < 0.5) for 96.2% of ticks with a longest continuous standstill of 1398
ticks. Fixed with a hysteretic wall-escape selection plus a corner escape,
dead enemyLastDir removed, and per-round state reset.
AFTER, measured through the booter: rest 12.3%, mean speed 6.69, full speed
79.7%, longest zero run 18, perpendicular 0.845 / radial 0.012 - it now
actually strafes. Gun sanity: lead error 1.0 px vs 106 px for head-on on a
constant-velocity target; lead gun 45.8% hits vs 29.3% for head-on.
- PatternMover: GENUINELY BUGGED. Real deadlock - it decremented its step
counter by the REQUESTED amount while issuing setTargetSpeed(8), so against a
wall the counter never reached 0, advanceStep never ran and it was stuck
forever (309-tick standstill). Now counts down by ACTUAL distance/turn with a
STALL_LIMIT watchdog and steers toward the arena centre. Standstill 309 -> 19
ticks; full-speed ticks 10.0% -> 28.4%.
- OscillatorBot: GENUINELY BUGGED, milder. No wall handling at all, so it
ground along walls 53.4% of ticks and could pin in a corner. Added wall
steering that preserves the fixed 25-tick reversal cadence. Wall-band 53.4%
-> 18.6%, mean wall distance 72 -> 119.
- RandomMover: merely sloppy, not broken. Its turn intent saturated against the
speed-dependent limit (18.4% of moving ticks clamped) and the fire gate was a
very loose 10 deg. Now clamps to calcMaxTurnRate and fires within 3 deg.
Saturation 18.4% -> 3.9%.
- SittingDuck: FINE. Speed 0 for 100% of ticks, zero shots. Left untouched -
it is a duck by design.
Adds test_wavesurfer_velocity.nim, a direct assertion that the decomposition is
cos/sin and explicitly NOT the swapped form (7 cases).
KNOWN ISSUE, not fixed: RandomMover/PatternMover/WaveSurfer import
tankroyale_botapi 1.0.1 and intermittently SIGSEGV in
tankroyale_botapi/event_queue.nim:89 addEvent, freezing the bot for the rest of
the battle. It reproduces on old and new code and never occurs for SittingDuck/
OscillatorBot, which import robocode_tankroyale_botapi 1.0.7. Migrating the
three to 1.0.7 would likely fix it and is worth doing - it is a real
reliability risk for these as sparring partners.
- 30-tick cooldown after ghost-stuck/timeout ram exit prevents re-entry loop
- enemy_tracker.update() skips dead bots to prevent same-tick scan resurrection
- TFIL graphics cleared when ramming is active movement
- [config] logs: white base with green-highlighted changes only
- [ram:enter] logs trigger reason and key values on false→true transition
- [death] and [target-invalid] logs retained for diagnostics