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
+83 -6
View File
@@ -21,6 +21,7 @@
import std/[os, strutils, algorithm, times, sets]
import env_dotenv
import module_switches
import gun_harness/virtual_bullets
import gun_harness/selector
import movements/ram_decision
@@ -194,12 +195,10 @@ proc printEffectiveValues(ctx: EnvReportContext) =
# ── movement / process-level ModularBot knobs ─────────────────────────────
# Only `tfil_ring` and `strafe` select a non-default engine; every other value
# runs `tfil`, so report the RESOLVED engine rather than the raw string.
let effectiveMovement =
if ctx.movementName == "tfil_ring": "tfil_ring"
elif ctx.movementName == "strafe": "strafe"
elif ctx.movementName == "surf": "surf"
elif ctx.movementName == "learned": "learned"
else: "tfil"
# `resolveMoveEngine` applies the per-engine TR_MODULE_MOVE_* switches, so
# this line reports the engine the tick will actually run (identical to the
# old name-mapping when every switch is unset).
let effectiveMovement = resolveMoveEngine(ctx.movementName)
emit("TR_MOVEMENT", effectiveMovement, sourceOf("TR_MOVEMENT"))
emit("TR_MOVEMENT_LOG", onOff(MovementLog), sourceOfPresence("TR_MOVEMENT_LOG"))
emit("TR_VBULLET_ADMIT_ONLY", onOff(ctx.vBulletAdmitOnly),
@@ -422,6 +421,79 @@ proc printEffectiveValues(ctx: EnvReportContext) =
emit(EnvReportEnableEnvVar, getEnv(EnvReportEnableEnvVar, "1"),
sourceOf(EnvReportEnableEnvVar))
# ── section C: the module on/off inventory ───────────────────────────────────
#
# One line per module, always the same shape:
# [modules] gun.pattern = ON (source: default)
# so `grep '^\[modules\]'` is the complete answer to "what is switched on right
# now". The always-on core is listed too, marked `source: always-on`, rather
# than silently omitted. Existing off switches (TR_RACK_<GUN>, TR_POWER_POLICY,
# TR_FIRE_FIX, TR_RADAR_FORCE_SPIN, TR_VBULLET_DEBUG, TR_GEO_DEBUG,
# TR_DEBUG_DRAW, TR_STRAFE_HEAT_GRID, TR_TFIL_HEAT_TIME) are surfaced under
# their ONE name — no duplicate knobs are invented.
proc emitModule(name: string, on: bool, source: string, note = "") =
var line = "[modules] " & name
while line.len < len("[modules] ") + 20: line.add ' '
line.add "= "
line.add(if on: "ON" else: "off")
line.add " (source: "
line.add source
if note.len > 0:
line.add "; "
line.add note
line.add ")"
echo line
proc printModules(ctx: EnvReportContext) =
echo "[modules] --- C. module on/off inventory (grep '^\\[modules\\]' for all) ---"
# Guns. Rack membership IS the on/off switch: `off` = disabled, any other
# mode = enabled in that rack.
for i in 0..<len(RackGunNames):
emitModule("gun." & RackGunNames[i].toLowerAscii(),
ActiveRackMembership[i] != rmOff,
sourceOf(RackEnvPrefix & RackGunNames[i]),
"rack: " & rackMembershipName(ActiveRackMembership[i]))
# Movement engines + the engine the tick actually runs.
for e in MoveEngines:
emitModule("move." & e.name, e.enabled, sourceOf(e.envVar))
echo "[modules] move.effective = ", resolveMoveEngine(ctx.movementName),
" (requested: TR_MOVEMENT=", ctx.movementName, ")"
# New TR_MODULE_* switches (j136).
emitModule("vbullets.tracker", ModuleVBullets, sourceOf(ModuleVBulletsEnvVar),
"off: no predict/spawn; selector falls back to its floor gun")
emitModule("ram.decider", ModuleRam, sourceOf(ModuleRamEnvVar),
"off: never ram; the movement engine alone drives")
# Existing off switches, surfaced as modules under their ONE existing name.
emitModule("radar.adaptive", not ctx.radarForceSpin,
sourceOfPresence("TR_RADAR_FORCE_SPIN"),
"off via TR_RADAR_FORCE_SPIN: full 360 spin")
emitModule("radar.lock", true, "always-on",
"1v1 radar; without it the bot cannot function")
emitModule("power.policy", PowerPolicyEnabled, sourceOf(PowerPolicyEnvVar),
"off via TR_POWER_POLICY: uncapped")
emitModule("fire.fix", TfilFireFix, sourceOf("TR_FIRE_FIX"),
"off: shipped prev-energy detector")
emitModule("dbg.debug_draw", ctx.debugDraw, sourceOfPresence(DebugDrawEnv),
"off: every mover debugGraphics=false")
emitModule("dbg.vbullet", ctx.vBulletDebug, sourceOfPresence(VBulletDebugEnv))
emitModule("dbg.geo", ctx.geoDebug, sourceOfPresence(GeoDebugEnv))
emitModule("dbg.heat_grid", StrafeHeatGrid, sourceOf("TR_STRAFE_HEAT_GRID"))
emitModule("dbg.heat_time", TfilHeatTime, sourceOf("TR_TFIL_HEAT_TIME"),
"off: flat (time-independent) bullet heat")
# Always-on core, listed so the inventory is complete.
emitModule("core.enemy_tracker", true, "always-on",
"without it the bot has no enemy positions")
emitModule("core.target_select", true, "always-on",
"picks which enemy to aim at")
emitModule("core.gun_selector", true, "always-on",
"ranks the rack; empty fitness floor = first admitted gun")
# ── build identity (which binary is the GUI actually running?) ───────────────
proc printBuildIdentity() =
@@ -466,6 +538,10 @@ proc knownEnvNames*(): seq[string] =
# exported constants — the single source of truth (do not re-spell these)
MetricEnvVar, SelectorModeEnvVar, TieBreakEnvVar,
RackShareEnvVar,
# module on/off switches (j136) — the new TR_MODULE_* prefix
ModuleVBulletsEnvVar, ModuleRamEnvVar,
ModuleMoveTfilEnvVar, ModuleMoveRingEnvVar, ModuleMoveStrafeEnvVar,
ModuleMoveSurfEnvVar, ModuleMoveLearnedEnvVar,
PowerPolicyEnvVar, PowerFarDistEnvVar, PowerFarCapEnvVar, PowerMidCapEnvVar,
PowerRefEnvVar, PowerEnergyHiEnvVar, PowerEnergyLoEnvVar,
PowerEnergyMinEnvVar, PowerEnergyMaxEnvVar, PowerFinishKillEnvVar,
@@ -661,5 +737,6 @@ proc printEnvReport*(ctx: EnvReportContext) =
printRawEnvironment()
printMistakeWarnings()
printEffectiveValues(ctx)
printModules(ctx)
printBuildIdentity()
echo "[env] === END ENVIRONMENT ==="