fix(logging): [config] reported a stale gun - it printed before selection ran
The user spotted this from the game itself: the [config] line always said
gun=HeadOn while the in-game turret and bullet COLOURS varied. The colours are
set at the selection site, so they were truthful and the log was not.
MEASURED, one 2-round battle, same process:
[config] output : 6 lines, ALL gun=HeadOn
tracker selection : Displace 25.1%, HeadOn 20.8%, Pattern 15.5%,
KNN 14.1%, Tsetlin 6.3%, WallBounce 6.1%, ...
Root cause: printConfig did GunNames[bot.currentGun] but EVERY call site ran
before the tick's gun selection - onRoundStarted right after currentGun = 0
(so HeadOn by construction), and the target/radar-change prints. The selection
that sets currentGun is ~490 lines later in the same tick. radarMode and
currentTargetId ARE updated before those sites, which is exactly why the radar
and target columns looked plausible while the gun column did not.
WHERE IT CAME FROM: git history shows commit 2cc2a3b ('cleaner logging')
removed the original printConfig call at the selection site while leaving the
prevGun highlight logic in place. That removal is when the regression appeared -
before it, the bot logged on round start AND on gun switch.
FIX: one emission at the end of the tick, after selectShot has run, gated by a
cfgDirty flag set on gun switch / target change / radar change. The index is
guarded (currentGun may be -1), the round-start line omits the gun field rather
than inventing one, and the existing output contract is preserved (all white,
only changed fields green, enemies= and target= kept).
VERIFIED: before 6 lines all HeadOn; after 782 lines over 2118 ticks with 13
distinct guns and ZERO violations - no printed gun was one that had not been
selected. Counts differ from the selection totals because the log prints only
on change, which is the behaviour the user asked for.
Also removes the 'currentGun = 0' initialisation in onRoundStarted, keeping the
existing -1 sentinel so 'no gun chosen yet' is representable.
This commit is contained in:
@@ -137,6 +137,7 @@ type
|
||||
prevGun: int
|
||||
prevRadar: int
|
||||
prevTarget: int
|
||||
cfgDirty: bool ## gun/target/radar changed this tick; emit one config line at tick end
|
||||
roundNumber: int
|
||||
realShotsFired: int
|
||||
realHits: int
|
||||
@@ -205,19 +206,25 @@ proc resolveOwnBullet(bot: ModularBot, bulletId: int): int =
|
||||
if result >= 0:
|
||||
bot.bulletGun.del(bulletId)
|
||||
|
||||
proc printConfig(bot: ModularBot, changed: string = "") =
|
||||
let gunName = GunNames[bot.currentGun]
|
||||
proc printConfig(bot: ModularBot, forceAll: bool = false) =
|
||||
## One line describing the config in use for the tick being reported. Only the
|
||||
## fields that changed since the previous line are highlighted green. The gun
|
||||
## field is omitted until a gun has actually been selected this round, so a
|
||||
## round-start line never claims a gun that was not chosen.
|
||||
let rst = CLR_RST
|
||||
let gc = if bot.currentGun != bot.prevGun or forceAll: CLR_CHANGE else: ""
|
||||
let rc = if bot.radarMode != bot.prevRadar or forceAll: CLR_CHANGE else: ""
|
||||
let tc = if bot.currentTargetId != bot.prevTarget or forceAll: CLR_CHANGE else: ""
|
||||
let radarName = if bot.radarMode == 0: "radar_lock" else: "melee_scan"
|
||||
let moveName = if bot.isRamming: "rammer" else: "tfil"
|
||||
let gc = if bot.currentGun != bot.prevGun or changed == "all": CLR_CHANGE else: ""
|
||||
let rc = if bot.radarMode != bot.prevRadar or changed == "all": CLR_CHANGE else: ""
|
||||
let tc = if bot.currentTargetId != bot.prevTarget or changed == "all": CLR_CHANGE else: ""
|
||||
let rst = CLR_RST
|
||||
echo "[config] " & gc & "gun=" & gunName & (if gc != "": rst else: "") &
|
||||
" | move=" & moveName &
|
||||
" | " & rc & "radar=" & radarName & (if rc != "": rst else: "") &
|
||||
" | enemies=" & $bot.enemyTracker.allAlive().len &
|
||||
" target=" & tc & "#" & $bot.currentTargetId & (if tc != "": rst else: "")
|
||||
var line = "[config] "
|
||||
if bot.currentGun >= 0 and bot.currentGun < GunNames.len:
|
||||
line &= gc & "gun=" & GunNames[bot.currentGun] & (if gc != "": rst else: "") & " | "
|
||||
line &= "move=" & moveName &
|
||||
" | " & rc & "radar=" & radarName & (if rc != "": rst else: "") &
|
||||
" | enemies=" & $bot.enemyTracker.allAlive().len &
|
||||
" target=" & tc & "#" & $bot.currentTargetId & (if tc != "": rst else: "")
|
||||
echo line
|
||||
bot.prevGun = bot.currentGun
|
||||
bot.prevRadar = bot.radarMode
|
||||
bot.prevTarget = bot.currentTargetId
|
||||
@@ -448,7 +455,8 @@ method onRoundStarted*(bot: ModularBot, e: RoundStartedEvent) =
|
||||
# ponytail: default to melee until confirmed 1v1 via scans, avoids stale enemyCount issue
|
||||
bot.radarMode = 1 # Start in melee_scan; will switch to radar_lock (0) if tracker confirms 1v1
|
||||
bot.moveTracker.resetRound(getX(), getY(), getDirection(), getSpeed())
|
||||
bot.currentGun = 0
|
||||
# currentGun stays -1 ("no gun chosen yet") until run() picks one; printConfig
|
||||
# omits the gun field while it is negative.
|
||||
# Apply radar colors for initial mode
|
||||
if bot.radarMode == 0:
|
||||
setRadarColor("#004444")
|
||||
@@ -456,7 +464,8 @@ method onRoundStarted*(bot: ModularBot, e: RoundStartedEvent) =
|
||||
else:
|
||||
setRadarColor("#443300")
|
||||
setScanColor("#4D3D0D")
|
||||
bot.printConfig("all")
|
||||
bot.cfgDirty = false
|
||||
bot.printConfig(forceAll = true)
|
||||
# tracker fitness persists across rounds (rolling window carries over)
|
||||
|
||||
method onBotDeath*(bot: ModularBot, e: BotDeathEvent) =
|
||||
@@ -520,7 +529,7 @@ method run*(bot: ModularBot) =
|
||||
if candidateId != bot.currentTargetId:
|
||||
bot.currentTargetId = candidateId
|
||||
bot.targetSwitchTick = bot.tick
|
||||
bot.printConfig("target")
|
||||
bot.cfgDirty = true # emit at tick end, after gun selection
|
||||
if bot.currentTargetId >= 0:
|
||||
bot.lastKnownTargetId = bot.currentTargetId
|
||||
|
||||
@@ -593,7 +602,7 @@ method run*(bot: ModularBot) =
|
||||
else:
|
||||
setRadarColor("#443300")
|
||||
setScanColor("#4D3D0D")
|
||||
bot.printConfig("radar")
|
||||
bot.cfgDirty = true # emit at tick end, after gun selection
|
||||
|
||||
let radarRate = if bot.radarMode == 0:
|
||||
bot.radar.computeScan(bot.lastState)
|
||||
@@ -694,6 +703,7 @@ method run*(bot: ModularBot) =
|
||||
bot.gunSelectionCount[selectedGun] += 1
|
||||
if selectedGun != bot.currentGun:
|
||||
bot.currentGun = selectedGun
|
||||
bot.cfgDirty = true # gun switch: emit the config line at tick end
|
||||
case selectedGun
|
||||
of 0: setTurretColor("#FF3333"); setBulletColor("#FF6666")
|
||||
of 1: setTurretColor("#3366FF"); setBulletColor("#6699FF")
|
||||
@@ -754,6 +764,12 @@ method run*(bot: ModularBot) =
|
||||
|
||||
setGunTurnRate(normDelta)
|
||||
|
||||
# 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:
|
||||
bot.printConfig()
|
||||
bot.cfgDirty = false
|
||||
|
||||
proc seedSelectorRng() =
|
||||
## Seed the process-global RNG exactly once at bot startup so the gun
|
||||
## selector's "random" tie-break (`chooseFromFit` -> rand) actually varies
|
||||
|
||||
Reference in New Issue
Block a user