fix(botapi): static SVG + intent buffers to kill cross-thread heap realloc

Round N+1's fresh bot thread realloc'd module-level strings/seqs (SVG buffer,
intent stdout/stderr, team messages) left behind by dead round N's thread —
same rawDealloc SIGSEGV class as the event queue, seen at graphics.nim:274
(drawText->prepareAdd, core 2490478 @ 03:13:40, battle round 257).

- graphics.nim: gSvgBuffer -> array[16384, char] + gSvgLen, appendSvg
- bot.nim: intent stdout/stderr -> static char arrays; team messages ->
  array[16, TeamMessage] + len; buildIntentJson/printToStdOut/Err/
  broadcastTeamMessage bounded appends
- botThreadEntry: reset graphics+intent buffers on the owning thread

Also fixes stale mapActions call sites in tests/ (missing enemyX/enemyY).
This commit is contained in:
2026-08-19 03:32:28 +02:00
parent 64697f917e
commit a4e830531b
11 changed files with 87 additions and 39 deletions
+2 -2
View File
@@ -40,7 +40,7 @@ when isMainModule:
let raw = randomNormalTensor[float32](ACTION_DIM)
let speed = 4.0'f32
# arena 800×600, bot at centre, heading north, gun north
let botActs = mapActions(raw, 0.0'f32, 800.0, 600.0, 400.0, 300.0, 0.0, speed.float, 0.0) # gunHeat=0 → fire allowed
let botActs = mapActions(raw, 0.0'f32, 800.0, 600.0, 400.0, 300.0, 0.0, speed.float, 0.0, 400.0, 300.0) # gunHeat=0 → fire allowed
assert botActs.targetSpeed >= -8.0'f32 and botActs.targetSpeed <= 8.0'f32,
&"targetSpeed out of range: {botActs.targetSpeed}"
@@ -52,7 +52,7 @@ when isMainModule:
&"firePower out of range: {botActs.firePower}"
# shouldFire=false when gunHeat > 0
let noFire = mapActions(raw, 1.0'f32, 800.0, 600.0, 400.0, 300.0, 0.0, speed.float, 0.0)
let noFire = mapActions(raw, 1.0'f32, 800.0, 600.0, 400.0, 300.0, 0.0, speed.float, 0.0, 400.0, 300.0)
assert not noFire.shouldFire, "shouldFire should be false when gunHeat > 0"
echo "All tests passed"