c091bf3c34
All prior measurements ran on server 0.35.5. The default is now the current 1.3.1 jar, with the legacy jar kept and switchable via TR_SERVER_JAR (no code edit). test_gauntlet_5bots.nim no longer clobbers a caller's TR_SERVER_JAR - it used to putEnv() unconditionally, so an override was silently ignored. RE-BASELINE (controlled RulesProbe battle, stationary bot, powers 0.1/0.5/1/2/3): dimension 1.3.1 0.35.5 verdict bullet damage per hit 0.4/2/4/10/16 identical SAME bullet speed (20-3p) within noise within noise SAME post-fire gun heat (1+p/5) identical identical SAME cooling 0.1/tick 0.1/tick SAME bulletDamage SCORE exactly 100/round 104..113/round DIFFERENT bulletKillBonus (20%) 20/round 20..23/round DIFFERENT LOUD FINDING - a SCORING rule changed, physics did not: 0.35.5 credits OVERKILL to bulletDamage (the killing bullet's full damage even past 0 energy); 1.3.1 caps it at the energy actually removed. Every 0.35.5 score is therefore inflated ~5-6%, and bulletKillBonus inherits the inflation. Gauntlet totals shift accordingly (SittingDuck 1936 -> 1800, WaveSurfer 1886 -> 1669). Consequence: score-based numbers recorded on 0.35.5 are NOT comparable to 1.3.1. Our gun A/Bs used real HIT RATE, not score, so those conclusions stand. Runner 1.0.2 (unchanged, no newer one on the box) is measured compatible with the 1.3.1 server. Note TrBattleCapture uses the runner's EMBEDDED server, which is 1.0.2 - so the capture path still runs an older engine than the gauntlet. Also re-ran acceptance_offline_vs_online on the new default: 12/12.
76 lines
3.4 KiB
Nim
76 lines
3.4 KiB
Nim
## Gun gauntlet: ModularBot vs all 5 adversaries, 10 rounds each.
|
|
## Dumps per-gun stats via ModularBot's onRoundEnded to /tmp/gun_stats.jsonl.
|
|
## nim c -r --path:../../common_libs tests/test_gauntlet_5bots.nim
|
|
|
|
import std/[os, strutils, strformat, tables]
|
|
import test_framework/server_manager
|
|
import test_framework/bot_compiler
|
|
import test_framework/runner_process
|
|
import test_framework/battle_result
|
|
|
|
const
|
|
modularBotDir = currentSourcePath().parentDir.parentDir
|
|
adversariesDir = "/home/davide/Projects/SirRoboGarage/common_libs/test_framework/adversaries"
|
|
defaultRunnerJar = "/home/davide/Projects/tank-royale/runner/examples/lib/robocode-tankroyale-runner.jar"
|
|
|
|
# Respect an EXISTING TR_SERVER_JAR / TR_BATTLE_RUNNER so either server version
|
|
# (1.3.1 default, or the 0.35.5 legacy via server_manager.LegacyServerJar) can be
|
|
# selected from the environment. Only fill in the default when the user left the
|
|
# variable unset. This file must not clobber a caller's choice.
|
|
let serverJar = getEnv("TR_SERVER_JAR", DefaultServerJar)
|
|
let runnerJar = getEnv("TR_BATTLE_RUNNER", defaultRunnerJar)
|
|
|
|
if not fileExists(serverJar):
|
|
echo "SKIP: server JAR not found at " & serverJar
|
|
quit(0)
|
|
if not fileExists(runnerJar):
|
|
echo "SKIP: runner JAR not found at " & runnerJar
|
|
quit(0)
|
|
|
|
putEnv("TR_SERVER_JAR", serverJar)
|
|
putEnv("TR_BATTLE_RUNNER", runnerJar)
|
|
putEnv("TR_BATTLE_RUNNER_DIR", "/home/davide/Projects/SirRoboGarage/tools/battle_runner")
|
|
|
|
# Pre-compile ModularBot once
|
|
discard compileBots(@[modularBotDir])
|
|
echo "[gauntlet] ModularBot compiled OK"
|
|
|
|
proc runBattle(label, enemyName, enemyDir: string) =
|
|
let sep = "=".repeat(60)
|
|
echo "\n" & sep
|
|
echo " " & label
|
|
echo sep
|
|
let bots = @[modularBotDir, enemyDir]
|
|
discard compileBots(@[enemyDir]) # ensure adversary is compiled
|
|
# Write session marker so analysis can map rounds to enemy name.
|
|
# Honor GUN_STATS_PATH (same knob ModularBot reads) so repeated pooled runs
|
|
# can append to one dedicated file instead of clobbering the default.
|
|
let statsPath = getEnv("GUN_STATS_PATH", "/tmp/gun_stats.jsonl")
|
|
block:
|
|
let lf = open(statsPath, fmAppend)
|
|
lf.writeLine("{\"session_start\":\"" & enemyName & "\"}")
|
|
lf.close()
|
|
let raw = runBattleRunner(getServerUrl(), bots, 10, 300_000, true)
|
|
let r = parseServerOutput(raw)
|
|
var mbScore = 0; var enScore = 0
|
|
for b in r.results:
|
|
if b.name == "ModularBot": mbScore = b.totalScore
|
|
elif b.name == enemyName: enScore = b.totalScore
|
|
let winner = if mbScore >= enScore: "ModularBot" else: enemyName
|
|
echo fmt" ModularBot: {mbScore} {enemyName}: {enScore} -> {winner} wins"
|
|
echo fmt" Rounds played: {r.rounds.len}"
|
|
|
|
# Write summary line to gauntlet log
|
|
let logLine = fmt"[{label}] ModularBot={mbScore} {enemyName}={enScore} winner={winner} rounds={r.rounds.len}"
|
|
let lf = open("/tmp/gun_gauntlet_results.log", fmAppend)
|
|
lf.writeLine(logLine)
|
|
lf.close()
|
|
|
|
ensureServer()
|
|
runBattle("Battle 1/5: vs SittingDuck", "SittingDuck", adversariesDir / "SittingDuck")
|
|
runBattle("Battle 2/5: vs OscillatorBot","OscillatorBot", adversariesDir / "OscillatorBot")
|
|
runBattle("Battle 3/5: vs RandomMover", "RandomMover", adversariesDir / "RandomMover")
|
|
runBattle("Battle 4/5: vs PatternMover", "PatternMover", adversariesDir / "PatternMover")
|
|
runBattle("Battle 5/5: vs WaveSurfer", "WaveSurfer", adversariesDir / "WaveSurfer")
|
|
echo "\nGauntlet complete. Stats in " & getEnv("GUN_STATS_PATH", "/tmp/gun_stats.jsonl") & " and /tmp/gun_gauntlet_results.log"
|