j136 add TR_MODULE_* on/off switches + single [modules] boot inventory

This commit is contained in:
2026-09-26 14:46:29 +02:00
parent fd34e4ae4a
commit 8f44140783
4 changed files with 255 additions and 17 deletions
+17 -11
View File
@@ -7,6 +7,7 @@ import env_boot # MUST be first: applies the .env file before any other
# module's top-level `let` reads the environment.
import std/[math, os, strformat, tables, sets, json, random, strutils]
import robocode_tankroyale_botapi
import module_switches
import radar_harness/radar_interface
import radars/radar_lock_module
import radars/adaptive_melee_radar
@@ -126,6 +127,10 @@ let VBulletAdmitOnly* =
## tfil_ring — the new RANGE-WEIGHTED mover (movements/the_floor_is_lava_ring).
## UNPROVEN: it must never become the default silently.
let MovementName* = getEnv("TR_MOVEMENT", "strafe").strip().toLowerAscii()
## The engine the tick ACTUALLY runs after the per-engine on/off switches
## (`TR_MODULE_MOVE_*`, default all on) are applied. With every switch unset this
## equals `MovementName`, so the dispatch below is byte-identical to before.
let EffectiveMovementName* = resolveMoveEngine(MovementName)
## TEMPORARY j134 diagnostic (TASK B): when `TR_FIRE_DIAG` is set, print the tick
## of every enemy-hit / our-hit EVENT so it can be checked against the energy
## reading tick logged by the mover. OFF by default; observability only.
@@ -379,13 +384,13 @@ proc printConfig(bot: ModularBot, forceAll: bool = false) =
let tc = if bot.currentTargetId != bot.prevTarget or forceAll: CLR_CHANGE else: ""
let radarName = if bot.radarMode == 0: "radar_lock" else: "adaptive_melee"
let moveName =
if MovementName == "strafe":
if EffectiveMovementName == "strafe":
if bot.isRamming: "strafe(ram)" else: "strafe"
elif MovementName == "tfil_ring":
elif EffectiveMovementName == "tfil_ring":
if bot.isRamming: "tfil_ring(ram)" else: "tfil_ring"
elif MovementName == "surf":
elif EffectiveMovementName == "surf":
if bot.isRamming: "surf(ram)" else: "surf"
elif MovementName == "learned":
elif EffectiveMovementName == "learned":
if bot.isRamming: "learned(ram)" else: "learned"
elif bot.isRamming: "rammer"
else: "tfil"
@@ -1150,8 +1155,8 @@ method run*(bot: ModularBot) =
let ramReason = ramTrigger(RamInputs(
dist: ramDist, selfEnergy: ws.selfEnergy,
enemyEnergy: ws.enemyEnergy, gunHitRate: gunHitRate))
let triggerRam = bot.currentTargetId >= 0 and bot.ramCooldownTicks == 0 and
ramReason != rrNone
let triggerRam = ModuleRam and bot.currentTargetId >= 0 and
bot.ramCooldownTicks == 0 and ramReason != rrNone
# Abort an IN-PROGRESS ram on sustained incoming fire. The trigger itself is
# unaffected, so a firefight before the approach never vetoes the start.
let abortRam = shouldAbortRam(bot.isRamming, ramDmgRate)
@@ -1195,13 +1200,13 @@ method run*(bot: ModularBot) =
# through the single ring engine; the default `tfil` keeps the old
# two-engine behaviour (tfil when holding, rammer when ramming).
var spd, tr: float
if MovementName == "strafe" and not shouldRam:
if EffectiveMovementName == "strafe" and not shouldRam:
(spd, tr) = bot.strafeMover.computeMove(ws)
elif MovementName == "surf" and not shouldRam:
elif EffectiveMovementName == "surf" and not shouldRam:
(spd, tr) = bot.surfMover.computeMove(ws)
elif MovementName == "learned" and not shouldRam:
elif EffectiveMovementName == "learned" and not shouldRam:
(spd, tr) = bot.learnedMover.computeMove(ws)
elif MovementName == "tfil_ring":
elif EffectiveMovementName == "tfil_ring":
bot.ringMover.band =
if shouldRam: (lo: 0.0, hi: 50.0)
else: (lo: RangeLo, hi: RangeHi)
@@ -1282,7 +1287,8 @@ method run*(bot: ModularBot) =
# is 0, so TR_VBULLET_ADMIT_ONLY=0 reproduces the exact pre-change rack.
var admit: array[17, bool]
for gi in 0..<17:
admit[gi] = vBulletAdmitted(gi, bot.rackMode, ActiveRackMembership,
admit[gi] = ModuleVBullets and
vBulletAdmitted(gi, bot.rackMode, ActiveRackMembership,
VBulletAdmitOnly or gi == TmPatternId or
gi == TmHorizonId or gi == BitBrainId)
for i in 0..<len(PowerBins):