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
This commit is contained in:
2026-09-20 00:37:10 +02:00
parent c9191b7afb
commit 254c7dc997
39 changed files with 2630 additions and 30 deletions
+92
View File
@@ -0,0 +1,92 @@
# BNNBot Research Brief
## Problem
Predict enemy future position in Robocode Tank Royale to aim bullets accurately. The prediction must happen online (during battle), without pre-training.
## Hard Constraints
- NO supervised learning (no labeled input→output training pairs)
- NO gradient descent (no derivatives, no surrogate gradients, no STE)
- Online learning only — must learn and improve during a single battle
- Computational budget: ~1ms per tick
- Binary-friendly (690-bit input encoding already exists)
## Allowed
- Backpropagation of SIGNALS (non-gradient information flowing backward through layers)
- Reinforcement learning (reward signal available from wave hit system)
- Self-supervised learning
- Unsupervised learning
- Network structure modification during runtime
## Current Architecture
### Input Engineering (binary_encoding.nim)
- 690-bit binary vector: 10 frames × 69 bits
- Per frame: bearing sin/cos (16b), distance (7b), velocity (5b), heading sin/cos (16b), enemy X/Y position (14b), enemy energy (11b)
- Gray-coded for Hamming distance smoothness
- Temporal window: 10 most recent radar scans
### Feedback System (wave system in BNNBot.nim)
- Every tick: 10 circular waves spawned at bot position
- Powers: 0.1 to 3.0 (10 levels), speeds: 19.7 to 11.0 px/tick
- When wave radius reaches enemy: records enemy state as 69-bit frame
- Provides ground truth: "if you fired at power X, the enemy would be HERE when the bullet arrives"
- ~95.6% hit rate in testing
### Current Predictor (predictor.nim)
- Linear extrapolation: predicted = current_pos + velocity * ticks_to_arrival
- Hebbian residual table: 8 heading sectors × 3 distance bands = 24 cells
- Each cell stores (correction_x, correction_y), updated online with lr=0.2
- Backtest results: 14-21% MAE reduction over pure linear extrapolation
- Converges within one battle (MAE 14.85 → 2.62, first 50 vs last 50 rows)
## Key Findings
### Data Analysis (analysis/report.txt)
- Enemy movement is 97.8% constant-velocity straight lines
- Acceleration is negligible (std 0.25-0.49 px/tick²)
- Heading is very stable across 10-frame windows
- Linear extrapolation MAE: 15-27px (1.5-2.7% of arena)
- Distance to enemy is the main error driver
- Scalar velocity alone is weak predictor (r=0.15); directional velocity from frame deltas is strong
### Backtest Results (analysis/backtest_report.txt)
- P1 (linear): MAE 8.1-18.7 encoded units
- P2 (weighted 4-frame): ~8% improvement, trivial cost
- P3 (linear + Hebbian residual): 14-21% improvement, converges fast
- Most residual table cells stay empty — only ~10/24 activate
### Encoding Insights
- sin/cos angle encoding avoids wraparound discontinuity — worth the extra bits
- Enemy X/Y position partially redundant with bearing+distance (encodes absolute position)
- Wall distance → XY% compression saved 140 bits losslessly
- Self-state removed (not needed for aiming)
## What We've Tried
1. ✅ Input engineering with Gray coding and temporal window — works well
2. ✅ Linear extrapolation — strong baseline, 15-27px error
3. ✅ Hebbian residual table — learns online, 14-21% improvement
4. ❌ Pure XOR layer stacking — collapses (associative, no non-linearity)
5. ❌ XOR + AND layers — AND with fixed mask is still linear over GF(2)
6. ✅ XOR + popcount + threshold = valid binary neuron (non-linear)
## Open Questions
1. Can we go deeper than the current shallow predictor while respecting the constraints?
2. What non-gradient learning rules can train multi-layer binary networks?
3. Can the temporal structure (10 frames) be exploited by the network architecture?
4. Is there a way to do credit assignment through depth without gradients?
5. Can the wave hit system provide richer learning signal than just miss distance?
## Architecture Philosophy
- Input engineering IS the feature hierarchy (handcrafted, domain-informed)
- Current approach is essentially reservoir computing: rich fixed features → simple learnable readout
- Question: can we do better with a learnable feature extractor, or is the handcrafted one already near-optimal?
## Files
- `src/BNNBot.nim` — main bot, wave system, integration
- `src/binary_encoding.nim` — 690-bit input encoding
- `src/predictor.nim` — linear extrapolation + Hebbian residual table
- `analysis/correlations.py` — data analysis script
- `analysis/backtest.py` — predictor comparison script
- `analysis/report.txt` — correlation analysis results
- `analysis/backtest_report.txt` — predictor backtest results
- `data/` — CSV battle logs (enabled via BNNBOT_CSV=1)