Enemy tracker + full 42-float state vector #15

Closed
opened 2026-08-16 15:02:05 +02:00 by SirStone · 1 comment
Owner

Parent

#13

What to build

Implement the deterministic enemy tracker and the full 42-float normalized state vector, so the bot feeds real game state to the neural network instead of dummy values.

End-to-end slice:

  • EnemyState struct: x, y, direction, speed, energy, ticksSinceLastScan, hasFired, lastFirePower.
  • Radar strategy (1v1): The tracker fully owns setRadarTurnRate, compensating for body/gun rotation. Round start: 45°/tick sweep until first onScannedBot. After contact: lock with overshoot — narrow oscillation scanning enemy nearly every tick. Recovery: if no scan for 2+ ticks, widen oscillation or full sweep.
  • Dead reckoning: on missed ticks, predicted_pos = last_pos + last_velocity × ticks_since_scan.
  • Enemy fire detection: infer hasFired and lastFirePower from energy delta between scans (bullet cost = firePower, so energy drop = firePower used).
  • 5-tick enemy history window: store last 5 ticks of enemy (x, y, direction, speed), shift on each tick.
  • Full 42-float state vector construction, all normalized to ~[-1,1]:
    • 14 current-tick: own x,y (/arenaW,H), direction(/360), speed(/8), energy(/100), gunDirection(/360), gunHeat(/1.8), enemy x,y,direction,speed,energy (same norms), hasFired(0/1), lastFirePower(/3)
    • 8 derived: enemy acceleration(/2), enemy turn rate(/10), relative bearing to enemy(/180 signed), distance to enemy(/~1700), 4 wall distances(/max(W,H))
    • 20 history: 5 ticks × 4 values (enemy x,y,direction,speed), same normalizations
  • Bot glue update: replace dummy state tensor with real state vector construction in the run loop.
  • Assert-based tests: synthetic bot values → correct 42-float normalized vector, correct derived features.

All state construction logic operates on plain floats/Tensors — no bot API types cross the seam. Bot event handlers extract raw values and pass them in.

Acceptance criteria

  • EnemyState updated on onScannedBot, dead-reckoned on missed ticks
  • Radar locks enemy and recovers from lost contact
  • Enemy firing detected from energy deltas
  • 5-tick enemy history window maintained
  • State vector is exactly 42 floats, all normalized to ~[-1,1]
  • Derived features (acceleration, turn rate, bearing, distance, walls) computed correctly
  • Bot runs with real state feeding into the network from slice 1
  • Assert-based test file passes

Blocked by

None — can start immediately

## Parent #13 ## What to build Implement the deterministic enemy tracker and the full 42-float normalized state vector, so the bot feeds real game state to the neural network instead of dummy values. End-to-end slice: - **EnemyState struct**: x, y, direction, speed, energy, ticksSinceLastScan, hasFired, lastFirePower. - **Radar strategy (1v1)**: The tracker fully owns `setRadarTurnRate`, compensating for body/gun rotation. Round start: 45°/tick sweep until first `onScannedBot`. After contact: lock with overshoot — narrow oscillation scanning enemy nearly every tick. Recovery: if no scan for 2+ ticks, widen oscillation or full sweep. - **Dead reckoning**: on missed ticks, `predicted_pos = last_pos + last_velocity × ticks_since_scan`. - **Enemy fire detection**: infer `hasFired` and `lastFirePower` from energy delta between scans (bullet cost = firePower, so energy drop = firePower used). - **5-tick enemy history window**: store last 5 ticks of enemy (x, y, direction, speed), shift on each tick. - **Full 42-float state vector construction**, all normalized to ~[-1,1]: - 14 current-tick: own x,y (/arenaW,H), direction(/360), speed(/8), energy(/100), gunDirection(/360), gunHeat(/1.8), enemy x,y,direction,speed,energy (same norms), hasFired(0/1), lastFirePower(/3) - 8 derived: enemy acceleration(/2), enemy turn rate(/10), relative bearing to enemy(/180 signed), distance to enemy(/~1700), 4 wall distances(/max(W,H)) - 20 history: 5 ticks × 4 values (enemy x,y,direction,speed), same normalizations - **Bot glue update**: replace dummy state tensor with real state vector construction in the run loop. - **Assert-based tests**: synthetic bot values → correct 42-float normalized vector, correct derived features. All state construction logic operates on plain floats/Tensors — no bot API types cross the seam. Bot event handlers extract raw values and pass them in. ## Acceptance criteria - [ ] EnemyState updated on onScannedBot, dead-reckoned on missed ticks - [ ] Radar locks enemy and recovers from lost contact - [ ] Enemy firing detected from energy deltas - [ ] 5-tick enemy history window maintained - [ ] State vector is exactly 42 floats, all normalized to ~[-1,1] - [ ] Derived features (acceleration, turn rate, bearing, distance, walls) computed correctly - [ ] Bot runs with real state feeding into the network from slice 1 - [ ] Assert-based test file passes ## Blocked by None — can start immediately
SirStone added the ready-for-agent label 2026-08-16 15:02:05 +02:00
Author
Owner

Resolved in f27b023, refined in fd22535 and bbc9e51. EnemyState struct with dead reckoning, deterministic radar lock with overshoot recovery, enemy fire detection from energy deltas, 5-tick history window, full 42-float normalized state vector. Bearing fixed to game coords (north=0° CW) in bbc9e51.

Resolved in f27b023, refined in fd22535 and bbc9e51. EnemyState struct with dead reckoning, deterministic radar lock with overshoot recovery, enemy fire detection from energy deltas, 5-tick history window, full 42-float normalized state vector. Bearing fixed to game coords (north=0° CW) in bbc9e51.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: SirStone/SirRoboGarage#15