j129: virtual-bullet debug overlay (TR_VBULLET_DEBUG, default off) - travelled path, predicted aim ring, hit/miss vector; shared turret colour table
This commit is contained in:
@@ -43,6 +43,7 @@ import movement_harness/bullet_shadows
|
||||
import targeting/enemy_tracker
|
||||
import targeting/target_selector
|
||||
import env_report
|
||||
import vbullet_draw
|
||||
|
||||
const botJsonPath = currentSourcePath().parentDir / "ModularBot.json"
|
||||
const DebugVBullets = false
|
||||
@@ -160,6 +161,17 @@ const TmHorizonId = 15
|
||||
## head — hence every other gun's learning order — is byte-for-byte unchanged.
|
||||
const BitBrainId = 16
|
||||
|
||||
## ── virtual-bullet debug overlay (TR_VBULLET_DEBUG*) ───────────────────────
|
||||
## OFF by default: the shipped bot draws nothing. When on, the tracker's
|
||||
## virtual bullets are overlaid so the training signal the selector learns
|
||||
## from is visible (travelled path, predicted aim point, miss vector). The
|
||||
## colour table is shared with the turret (see `vbullet_draw.gunColors`).
|
||||
## Default filter: ONLY the currently selected gun, to stay legible; set
|
||||
## `TR_VBULLET_DEBUG_GUN=all` or name a gun (e.g. `Pattern`).
|
||||
let VBulletDebugOn = vBulletDebugEnabled()
|
||||
let VBulletDebugMax = vBulletDebugMaxBullets()
|
||||
let VBulletDebugGun = resolveGunFilter(getEnv(VBulletDebugGunEnv, ""), GunNames)
|
||||
|
||||
const
|
||||
CLR_GUN = "\e[33m" # yellow
|
||||
CLR_MOVE = "\e[36m" # cyan
|
||||
@@ -1267,6 +1279,11 @@ method run*(bot: ModularBot) =
|
||||
for id, es in bot.enemyTracker.enemies:
|
||||
enemyPositions[id] = (x: es.x, y: es.y, lastSeenTick: es.lastSeenTick, alive: es.alive)
|
||||
|
||||
# Debug-only: bullets that resolve during `tickBullets` below are cleared
|
||||
# from the tracker in the same tick, so capture their outcome here for the
|
||||
# overlay's miss vector. Empty (and unused) when the overlay is off.
|
||||
var resolvedMarks: seq[VbResolved]
|
||||
|
||||
let st = bot.lastState
|
||||
bot.tracker.tickBullets(st, enemyPositions, proc(gunId: GunId, binIdx: int, fe: FeedbackEvent) =
|
||||
case gunId
|
||||
@@ -1294,6 +1311,10 @@ method run*(bot: ModularBot) =
|
||||
of BitBrainId: bot.bitbrain.onResult(fe)
|
||||
else: discard
|
||||
if fe.hit: inc bot.virtualHits else: inc bot.virtualMiss
|
||||
if VBulletDebugOn:
|
||||
resolvedMarks.add VbResolved(
|
||||
gunId: gunId, aimX: fe.prediction.x, aimY: fe.prediction.y,
|
||||
actualX: fe.actualX, actualY: fe.actualY, hit: fe.hit)
|
||||
when DebugVBullets:
|
||||
let total = bot.virtualHits + bot.virtualMiss
|
||||
let pct = if total > 0: bot.virtualHits.float / total.float * 100.0 else: 0.0
|
||||
@@ -1320,25 +1341,11 @@ method run*(bot: ModularBot) =
|
||||
if selectedGun != bot.currentGun:
|
||||
bot.currentGun = selectedGun
|
||||
bot.cfgDirty = true # gun switch: emit the config line at tick end
|
||||
case selectedGun
|
||||
of 0: setTurretColor("#FFFFFF"); setBulletColor("#FFFFFF") # HEADON: pure white (was #FF3333 red)
|
||||
of 1: setTurretColor("#3366FF"); setBulletColor("#6699FF")
|
||||
of 2: setTurretColor("#9933FF"); setBulletColor("#CC66FF")
|
||||
of 3: setTurretColor("#33CC33"); setBulletColor("#66FF66")
|
||||
of 4: setTurretColor("#FFCC00"); setBulletColor("#FFE066")
|
||||
of 5: setTurretColor("#00CC44"); setBulletColor("#66FF99") # PATTERN: green (was #FF6600 orange, too close to BitBrain's pink)
|
||||
of 6: setTurretColor("#CCCCCC"); setBulletColor("#EEEEEE")
|
||||
of 7: setTurretColor("#FF00FF"); setBulletColor("#FF66FF")
|
||||
of 8: setTurretColor("#990000"); setBulletColor("#CC3333")
|
||||
of 9: setTurretColor("#006600"); setBulletColor("#009900")
|
||||
of 10: setTurretColor("#996633"); setBulletColor("#CC9966")
|
||||
of 11: setTurretColor("#008888"); setBulletColor("#00AAAA")
|
||||
of 12: setTurretColor("#CC00CC"); setBulletColor("#FF44FF")
|
||||
of 13: setTurretColor("#00FFCC"); setBulletColor("#66FFDD")
|
||||
of TmPatternId: setTurretColor("#AAFF00"); setBulletColor("#CCFF66")
|
||||
of TmHorizonId: setTurretColor("#00AAFF"); setBulletColor("#66CCFF")
|
||||
of BitBrainId: setTurretColor("#FF1493"); setBulletColor("#FF69B4")
|
||||
else: discard
|
||||
# Per-gun colours live in `vbullet_draw.gunColors`, shared with the
|
||||
# virtual-bullet overlay so turret and overlay can never drift apart.
|
||||
let (turretColor, bulletColor) = gunColors(selectedGun)
|
||||
setTurretColor(turretColor)
|
||||
setBulletColor(bulletColor)
|
||||
|
||||
let pred = case selectedGun
|
||||
of 1: bot.linear.predict(bot.lastState, bulletSpeed(power))
|
||||
@@ -1387,6 +1394,12 @@ method run*(bot: ModularBot) =
|
||||
|
||||
setGunTurnRate(normDelta)
|
||||
|
||||
# Virtual-bullet overlay (default off). Drawn AFTER selection so the
|
||||
# default "selected gun only" filter uses this tick's choice.
|
||||
if VBulletDebugOn:
|
||||
discard drawVirtualBullets(bot.tracker, resolvedMarks, selectedGun,
|
||||
VBulletDebugGun, VBulletDebugMax, GunNames)
|
||||
|
||||
# Emit exactly one config line per tick, at the END of the tick, so the gun
|
||||
# field reflects the selection made above rather than the previous tick's.
|
||||
if bot.cfgDirty:
|
||||
@@ -1449,6 +1462,9 @@ when isMainModule:
|
||||
printEnvReport(EnvReportContext(
|
||||
movementName: MovementName,
|
||||
vBulletAdmitOnly: VBulletAdmitOnly,
|
||||
vBulletDebug: VBulletDebugOn,
|
||||
vBulletDebugGun: getEnv(VBulletDebugGunEnv, ""),
|
||||
vBulletDebugMax: VBulletDebugMax,
|
||||
recordWorldState: RecordWorldState,
|
||||
radarForceSpin: RadarForceSpin,
|
||||
radarScanLog: RadarScanLog,
|
||||
|
||||
Reference in New Issue
Block a user