Add DevControlBot garage: skeleton bot with release/debug build script
A minimal Tank Royale bot that boots and stands still. Body, gun and radar are set to white once at init (team convention: white = not programmed yet); the tick loop only calls go(). - DevControlBot/ holds the single bot module, its metadata JSON, the BotLauncher entry script and the nimble file - DevControlBot.sh is a thin wrapper around the runBot nimble task: release build by default, --debug for the classic diagnostic build - dependencies resolve at run time from the global nimble store via `nimble path`; optional .env (gitignored) supplies env vars such as SERVER_URL, with existing environment variables taking precedence - build happens in a throwaway mktemp dir removed on exit; no artifacts
This commit is contained in:
+92
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env bash
|
||||
# BotLauncher entry point for DevControlBot.
|
||||
#
|
||||
# Thin wrapper: all build/run/cleanup logic lives in the `runBot` nimble task
|
||||
# of DevControlBot.nimble. This script only locates itself, moves next to the
|
||||
# .nimble so Nimble finds it, forwards caller arguments, calls the task and
|
||||
# propagates the real exit code. Signals are forwarded to Nimble so the task's
|
||||
# own EXIT/INT/TERM cleanup always runs.
|
||||
#
|
||||
# Usage: DevControlBot.sh [--debug] [<metadata.json>] [extra args for the bot]
|
||||
#
|
||||
# (no args) RELEASE build + run with the bundled DevControlBot.json
|
||||
# (no flag) RELEASE build (nim c -d:release), quiet output
|
||||
# --debug classic DEBUG build (plain nim c): compiler hints + diagnostics
|
||||
#
|
||||
# --debug is a build-mode flag for this wrapper only: it is stripped here and
|
||||
# never reaches the bot binary or nimble's task arguments. It travels to the
|
||||
# runBot task as $DEVCONTROLBOT_DEBUG (exported), because an env var cannot be
|
||||
# confused with a bot argument, cannot collide with the status file mechanism
|
||||
# and keeps the task's argument parsing untouched. Repeated --debug is harmless.
|
||||
#
|
||||
# Configuration (SERVER_URL, SERVER_SECRET, ...) is NOT handled here at all: the
|
||||
# API's start() reads those from the environment, and the optional .env file is
|
||||
# loaded by the runBot task, so it also works with a direct `nimble runBot`.
|
||||
set -uo pipefail
|
||||
set -m # job control: the background job gets its own process group
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $(basename "$0") [--debug] [<metadata.json>] [extra args for the bot]
|
||||
|
||||
--debug classic debug build: shows compiler hints and diagnostics
|
||||
(default is a quiet RELEASE build, nim c -d:release)
|
||||
-h,--help show this help
|
||||
|
||||
Examples:
|
||||
$(basename "$0") # release build + run, bundled DevControlBot.json
|
||||
$(basename "$0") my.json # release build + run with custom metadata
|
||||
$(basename "$0") -h # this help
|
||||
$(basename "$0") --debug # debug build
|
||||
$(basename "$0") --debug my.json # debug build with custom metadata
|
||||
EOF
|
||||
}
|
||||
|
||||
# Split caller args: everything except --debug is forwarded verbatim.
|
||||
BUILD_MODE=release
|
||||
FORWARDED=()
|
||||
for a in "$@"; do
|
||||
case "$a" in
|
||||
--debug) BUILD_MODE=debug ;;
|
||||
*) FORWARDED+=("$a") ;;
|
||||
esac
|
||||
done
|
||||
set -- ${FORWARDED+"${FORWARDED[@]}"}
|
||||
|
||||
# No arguments is the normal case: build and run with the bundled metadata.
|
||||
# Usage is printed ONLY for an explicit -h/--help.
|
||||
case "${1:-}" in
|
||||
-h|--help) usage; exit 0 ;;
|
||||
esac
|
||||
|
||||
export DEVCONTROLBOT_DEBUG="$BUILD_MODE"
|
||||
|
||||
# The runBot task's shell always exits 0 (otherwise Nimble raises a NimScript
|
||||
# exception with a stack trace and a dump of the whole script) and writes the
|
||||
# bot's real exit code here instead. We read it back and exit with it, so
|
||||
# BotLauncher still sees the faithful status: 1 = no game server on 7654,
|
||||
# 2 = a dependency is missing, 3 = compile failure, anything else = the bot's
|
||||
# own code, 0 = clean run.
|
||||
STATUS_FILE="$(mktemp "${TMPDIR:-/tmp}/devcontrolbot.status.XXXXXX")"
|
||||
export DEVCONTROLBOT_STATUS_FILE="$STATUS_FILE"
|
||||
trap 'rm -f "$STATUS_FILE"' EXIT
|
||||
|
||||
# Forward to the whole job process group (nimble + the shell it spawned) so the
|
||||
# task's own EXIT/INT/TERM cleanup runs. No cleanup logic here.
|
||||
forward() { kill -s "$1" -- "-$NIMBLE_PID" 2>/dev/null; }
|
||||
trap 'forward TERM' TERM
|
||||
trap 'forward INT' INT
|
||||
|
||||
nimble runBot ${1+"$@"} &
|
||||
NIMBLE_PID=$!
|
||||
wait "$NIMBLE_PID"
|
||||
rc=$?
|
||||
trap - TERM INT
|
||||
# Prefer the code the run actually produced; fall back to Nimble's own status if
|
||||
# the task died before it could report (e.g. Nimble itself failed).
|
||||
real_rc="$(head -n 1 "$STATUS_FILE" 2>/dev/null | tr -d '[:space:]')"
|
||||
[ -n "$real_rc" ] || real_rc=$rc
|
||||
exit "$real_rc"
|
||||
Reference in New Issue
Block a user