Files
SirRoboGarage/SAC_LSTM_Bot/make_twin.sh
T
SirStone 19f34abf0c fix(SAC_LSTM_Bot): freeze mirror-twin via eval-mode gate in twin launcher
SACLSTM_EVAL_MODE=1 in SacTwin.sh suppresses all sendTrainingMsg traffic
(lever-4 gate), so the twin never trains — not even in-RAM within a battle.
Required now that the main bot's SACLSTM_SAVE_INTERVAL drops to 1 (v2 relaunch
after checkpoint-cadence diagnosis): without the gate the twin would persist
per-battle drift and stop being the frozen reproducible opponent #54 specifies.
2026-08-22 21:09:07 +02:00

62 lines
2.6 KiB
Bash
Executable File

#!/usr/bin/env bash
# make_twin.sh — #54 mirror-twin sparring partner generator.
#
# Builds a self-contained `SacTwin` bot dir inside the sample-bots archive so
# RunTraining.java resolves it like any sample bot ($SAMPLE_BOTS_DIR/<name>).
# The twin is the SAME binary as SAC_LSTM_Bot but with:
# - distinct identity (SacTwin.json; SACLSTM_BOT_JSON overrides the baked-in
# src json — loadBotInfo gives json total precedence over env, #49 lesson)
# - its OWN weights dir, seeded from a FROZEN copy of weights/sac_best.zip
# (no checkpoint write races with the main bot)
# - its OWN round_counter.txt (main liveness guard untouched)
#
# Re-running resets the twin to the frozen baseline (reproducible opponent).
#
# Usage: ./make_twin.sh [target-archive-dir]
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
TARGET="${1:-${SAMPLE_BOTS_DIR:-/home/davide/Projects/tank-royale/sample-bots/java/build/archive}}/SacTwin"
BIN="$SCRIPT_DIR/SAC_LSTM_Bot" # nimble build -d:release output
SEED="$SCRIPT_DIR/weights/sac_best.zip" # frozen baseline
[ -x "$BIN" ] || { echo ">>> $BIN missing — run 'nimble build -d:release' first"; exit 1; }
[ -f "$SEED" ] || { echo ">>> $SEED missing — need at least one eval'd checkpoint"; exit 1; }
mkdir -p "$TARGET/weights"
cp "$BIN" "$TARGET/SAC_LSTM_Bot"
cat > "$TARGET/SacTwin.json" <<EOF
{
"name": "SacTwin",
"version": "0.1.0",
"authors": ["Davide Cappellini"],
"description": "Mirror-twin sparring partner of SAC_LSTM_Bot (#54), generated by make_twin.sh — own weights dir, frozen seed",
"homepage": "",
"countryCodes": ["IT"],
"gameTypes": ["classic", "melee", "1v1"],
"platform": "Nim",
"programmingLang": "Nim"
}
EOF
cat > "$TARGET/SacTwin.sh" <<'EOF'
#!/bin/sh
# Twin launcher (#54): identity + weights fully decoupled from the main bot.
DIR="$(cd "$(dirname "$0")" && pwd)"
export SACLSTM_BOT_JSON="$DIR/SacTwin.json"
export SACLSTM_WEIGHTS_PATH="$DIR/weights/sac_latest.zip"
# Freeze contract (#54): the twin is a FROZEN sparring partner, not a
# co-learner. Eval-mode gate (lever 4) suppresses all sendTrainingMsg traffic,
# so the twin never trains — not even in-RAM within a battle. Without this,
# any main-bot checkpoint-interval change would let twin drift accumulate.
export SACLSTM_EVAL_MODE=1
exec "$DIR/SAC_LSTM_Bot"
EOF
chmod +x "$TARGET/SacTwin.sh" "$TARGET/SAC_LSTM_Bot"
cp "$SEED" "$TARGET/weights/sac_latest.zip"
cp "$SEED" "$TARGET/weights/sac_best.zip"
echo 0 > "$TARGET/weights/round_counter.txt"
echo ">>> twin ready: $TARGET (seeded from $(stat -c %y "$SEED" | cut -d. -f1) snapshot of sac_best.zip)"