Commit Graph

15 Commits

Author SHA1 Message Date
SirStone e53690036b fix(guns): speed-sensitive caches, dead stop-shot branch, exact TM trace pairing
Four guns cached a whole prediction per tick while predict() is called once
per power bin, so every bin after the first (and the real fired shot, which
shares lastState) reused the power-1.0 lead. Fixed by caching only the
speed-INDEPENDENT derived state and recomputing the lead per requested speed:
- stop_shot: also fixes prevSpeed being written before it was read, which
  made abs(speed) < abs(prev) permanently false and the entire
  stop-prediction branch unreachable (it was just Linear).
- displacement: the cache key included bulletSpeed, so the guard missed on
  all four bins and the 15-tick window advanced ~4x/tick, making the
  inferred velocity ~4x too small.
- averaged_lead: tick cache removed outright. pattern_matcher: split into
  speed-independent match+path and per-call lead.

FeedbackEvent gains fireTick/powerBin (additive; only virtual_bullets
constructs one) so guns can pair feedback to the exact shot instead of
guessing by coordinates. tsetlin uses it: traces are now keyed exactly by
(fireTick, powerBin) with a 1024-slot ring, and the 10-frame window shifts
at most once per tick (it was shifting ~4-5x/tick, so isWarmedUp tripped
after ~2 ticks).

KNOWN INCOMPLETE: tsetlin still does not diverge from Linear in battle. The
two named bugs are fixed (a 600-tick sim shows trainedShots=2141,
traceMisses=0, and a fixed-input probe converges to a 9.6px correction), but
the TM's clause feedback itself is broken: ~131 of 1740 literals end up
included per clause, so its conjunction never fires. Sweeping TM_S,
TM_N_CLAUSES and a two-branch Type-I update did not change the correction
from 0. Needs a real TM fix or removal, not another bug fix.

First-ever guard tests for the gun selector: common_libs/tests/
test_gun_harness.nim (14 checks, headless, no Java). There were none before,
which is how six broken guns survived a full analysis cycle. Against the
previous HEAD, 5 of these checks FAIL - that is the regression guard.
2026-09-20 22:47:26 +02:00
SirStone 0cc682152d fix(guns): per-bin wave queues unbreak GF/DecayGF/KNN learning; fix vbullet drops
Wave queues (guess_factor, decay_gf, knn_gun): predict() stored ONE wave
per tick while onResult() popped one per resolved bullet (~4/tick), so the
queue drained to empty within a few dozen ticks, ~3 of every 4 resolutions
returned without learning, and the survivor paired with a same-tick wave
(bearingDelta ~= 0) pinning the histogram at centre. PROOF: GF.vHits ==
HeadOn.vHits and DecayGF.vHits == HeadOn.vHits byte-for-byte in every one
of 50 rounds — the guns had degenerated to HeadOn.

Now each gun keeps a per-bin FIFO with an O(1) head cursor. At most one
push per (tick, bin) so the fire site's 5th predict() call is a no-op, and
onResult pops the oldest wave of its OWN bin via e.bulletPower. Aiming
math untouched (it was already correct: 0 deg = East, CCW+).

maxBullets 2048 -> 8192: the rack spawns 52 bullets/tick so the ring wrapped
every ~39 ticks while a long power-3 shot needs ~90, silently discarding
unresolved bullets and biasing every measured hit rate by range. Added a
droppedBullets counter so a future overflow is measurable, and wavePushes/
waveStarved counters on the three guns. After the fix: vDropped = 0 and
vStarved = 0 across all 48 recorded rounds.

fitnessFor is now exported, deterministic (enemies iterated in ascending id
order) and shared by the selector and the stats dump, replacing a hand-rolled
merge in ModularBot that never advanced its window head.

Round lines gain additive keys: vDropped, vStarved.
2026-09-20 22:27:52 +02:00
SirStone 2cc2a3bd87 fix(ModularBot): ram loop prevention, dead-target guards, cleaner logging
- 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
2026-09-20 20:44:45 +02:00
SirStone 651ce80620 feat(ModularBot): KNN gun, gunheat tracker, bullet shadows — inspired by DrussGT
New DrussGT-inspired modules:
- KNNGun: K-nearest-neighbor statistical targeting using GF density peaks
- GunheatTracker: dual-heat system (predicted + confirmed) for 1-2 tick lead
- ShadowTracker: computes GF regions safe from in-flight bullets (enemy wave dodge)

VirtualBodyTracker now integrates gunheat for earlier fire detection and shadows
for safe-zone multiplier (90% reduction in danger zones).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-20 11:58:57 +02:00
SirStone c94ba1f2fe feat(ModularBot): decay-GF gun (recency-weighted), 13 guns total
- Decay-GF: exponential decay on GF histogram (0.998/tick, ~350-tick half-life)
- Adapts faster to mid-battle strategy changes than standard GF
- Battle-tested vs WaveSurfer, Crazy, RandomMover
2026-09-20 01:52:22 +02:00
SirStone fbf9414375 feat(ModularBot): rammer movement + averaged-lead gun, 12 guns
- Ram movement: drive straight at enemy (not wired, needs selector)
- Averaged-lead gun: mean of linear+circular+wall-bounce predictions
- 12 guns total, battle-tested

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-20 01:46:52 +02:00
SirStone b373d3d505 feat(ModularBot): displacement-vector gun, 11 guns total
- Displacement gun: average velocity over sliding window, captures drift
- Complements instantaneous-velocity linear gun
- Battle-tested vs Crazy, WaveSurfer, PatternMover
2026-09-20 01:43:25 +02:00
SirStone a87be5f99f feat(ModularBot): stop-shot gun, 10 guns total
- Stop-shot gun: predicts enemy deceleration stop point
- Catches bots at direction reversal pauses
- Battle-tested vs WaveSurfer, Crazy, RandomMover

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-20 01:37:45 +02:00
SirStone 18ff2d45b3 feat(ModularBot): acceleration predictor gun, 9 guns total
- Accel gun: tracks velocity+heading changes, extrapolates with acceleration
- Handles speed-up, slow-down, and combined accel+turn
- Battle-tested vs Crazy, RandomMover, Walls
2026-09-20 01:34:27 +02:00
SirStone a3b4f26b69 feat(ModularBot): wall-bounce gun, 8 guns total
- Wall-bounce gun: linear extrapolation with arena wall reflection
- Simulates enemy tick-by-tick, bouncing off walls (billiard-ball reflection)
- 4-iteration convergence on ticksToArrive like circular gun
- 8 guns: head-on, linear, circular, tsetlin, guess-factor, pattern, anti-surfer, wall-bounce
- Turret: #CCCCCC (silver), bullet: #EEEEEE (white)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-20 01:30:21 +02:00
SirStone ebe5b1b7f1 feat(ModularBot): anti-surfer gun + wave-surf movement module
- Anti-surfer gun: inverse GF targeting for wave-surfing enemies
- Wave-surf movement: danger histogram dodge (not wired yet, needs movement selector)
- 7 guns total, battle-tested

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-20 01:28:29 +02:00
SirStone 78723fce13 fix(GFGun): head-on prior + per-bin mea in onResult
- Cold-start bug: uniform bins[0..30]=0.1 made peakBin() always return
  0 (first-wins tie), giving GF=-1 (max CW escape) before any learning.
  Fixed with a triangular head-on bump at bin 15 (GF=0) as the prior.
- onResult now recomputes mea from FeedbackEvent.bulletPower instead of
  the stale first-bin mea cached by predict; correct per-power-bin GF.
- Add DebugGF const (default false) with [gf-dbg] echoes in predict/onResult.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-20 01:05:22 +02:00
SirStone 1ed7797cb6 feat(ModularBot): 6 guns, pattern matcher, melee modules, adversarial bots
- New guns: guess-factor (GF histogram), pattern-matcher (movement tape replay)
- New modules: minimum-risk melee movement, spinning melee radar
- New test bots: PatternMover, RandomMover, WaveSurfer
- Fixed: FeedbackEvent now carries actualX/actualY for proper GF learning
- Fixed: TM gun warmup gating + directional residuals
- Fixed: circular gun integrated formula + multi-bin omega cache
- Fixed: oscillator wall-bounce lockout
- Fixed: phantom meteor perpendicular body orientation
- 6/6 battle wins across all enemy types
2026-09-20 00:59:53 +02:00
SirStone 254c7dc997 feat(ModularBot): pluggable bot with 4 guns, phantom meteor movement, radar harness
- Gun harness: virtual bullet tracker, rolling fitness, auto-selector
- Guns: head-on, linear (extrapolation), circular (integrated formula), tsetlin machine (learning)
- Movement: phantom meteor gravity engine (danger histograms, phantom bullets, fire detection)
- Radar: harness + radar_lock adapter
- Color-coded modules: turret/bullet color per gun, body per movement, scan per radar
- Beats Target, SpinBot, Crazy, TrackFire in 10-round battles
2026-09-20 00:37:10 +02:00
SirStone c9191b7afb fix(circular-gun): correct turn-rate calculation for multi-scan delays
Two bugs fixed:
1. Multi-tick gaps: turn rate assumed 1 tick between observations, but scans can be 5+ ticks apart. Now divides by actual tickDelta.
2. Per-power-bin state corruption: predict() called 4x per tick (per power bin). After first call, prevHeading was already updated, causing subsequent calls to compute 0° delta. Now captures oldHeading/oldTick before updating.

Verified: OscillatorBot at 4°/tick captured correctly; normalization [-180°,180°] works; tickDelta=1 typical; first bin gets delta, subsequent bins see 0 (expected).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-19 19:43:40 +02:00