11 Commits

Author SHA1 Message Date
SirStone d3e4540e7f chore: add missing OscillatorBot.nimble 2026-08-27 18:42:35 +02:00
SirStone 259e67d7ff chore: standardize internal bot dir structure (src/, tests/, out/)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-27 18:42:03 +02:00
SirStone c5115fdf61 chore: standardize Nim builds to out/ subdir, simplify .gitignore
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-27 18:35:54 +02:00
SirStone e276548223 chore: remove exported/ from AGENTS.md, generalize binary ignores in .gitignore
- Removed non-existent exported/ directory from layout docs
- Replaced hardcoded bot binary entries with *_garage/out/ pattern for build directories
- Added all known bot binaries (GotoTest, OscillatorBot, PPO_Bot, QBot, SAC_LSTM_Bot)
  to .gitignore with clarifying comment about Nim's compilation target structure

Nim places compiled binaries at bot root (no extension) and in out/ subdirs.
The out/ pattern catches all build outputs; specific bot binaries listed for
root-level executables since gitignore lacks a reliable "no-extension files" glob.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-08-27 18:32:09 +02:00
SirStone 2097c2e6fa chore: gitignore binaries/artifacts, remove drafts and stale files 2026-08-27 18:28:21 +02:00
SirStone 06ed905033 docs(AGENTS): generalize layout rules, remove hardcoded bot list 2026-08-27 18:22:38 +02:00
SirStone eab85be8b3 docs(AGENTS): update directory layout to match current structure 2026-08-27 18:19:37 +02:00
SirStone b509195ee9 chore: rename libs→common_libs, all bot dirs to _garage suffix, fix all path refs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-27 18:18:41 +02:00
SirStone f8c0c871c6 chore: remove unused prototypes/ and spike/ dirs 2026-08-27 18:16:34 +02:00
SirStone b9877bfff5 chore: add .gitignore 2026-08-27 18:12:08 +02:00
SirStone 8ba4bae21a chore: rename CLAUDE.md → AGENTS.md, move research doc to docs/ 2026-08-27 18:11:56 +02:00
848 changed files with 4812 additions and 590 deletions
+36
View File
@@ -0,0 +1,36 @@
# Compiled output
*.out
# Python cache
__pycache__/
*.pyc
*.pyo
# Log files
*.log
# Training logs
*.jsonl
# Test binaries (but keep .nim source files)
**/tests/test_*
!**/tests/test_*.nim
!**/tests/test_*.nims
# User-specific dev environment
.envrc
devbox.json
devbox.lock
# Compiled bot binaries — all builds go to *_garage/out/
*_garage/out/
# Java compiled classes
*.class
# Log and snapshot directories
**/logs/
**/snapshots/
# Git worktrees
worktrees/
+47
View File
@@ -0,0 +1,47 @@
## Agent skills
### Issue tracker
Gitea Issues at git.fossellini.top:SirStone/SirRoboGarage. See `docs/agents/issue-tracker.md`.
### Triage labels
Default label vocabulary. See `docs/agents/triage-labels.md`.
### Domain docs
Single-context layout. See `docs/agents/domain.md`.
### Folders
## SirGarage Directory Layout
**SirGarage** (root directory)
- `botname_garage/` — each bot gets its own directory following this pattern
- src/
- botname.nim
- botname.json
- botname.sh
- config.nim
- botname/ — bot-specific modules
- *.nim files
- tests/
- test*.nim files
- out/
- compiled binaries
- prototypes or spikes for this bot (not at root)
- docs/ — generic project documentation
- tools/ — generic tools valid for all bots (battle runners, scripts, etc.)
- common_libs/ — shared libraries valid for all bots
- worktrees/ — git worktrees (gitignored)
- AGENTS.md
- CONTEXT.md
- README.md
- .gitignore
## How to use
- These indications are for files that are always present, for files not mentioned here should be claer from context where belongs too.
- Each bot development must be done in each folder in isolation.
- If the bot requires extra folders during runtime, these must be created by the bot itself if not present already.
-13
View File
@@ -1,13 +0,0 @@
## Agent skills
### Issue tracker
Gitea Issues at git.fossellini.top:SirStone/SirRoboGarage. See `docs/agents/issue-tracker.md`.
### Triage labels
Default label vocabulary. See `docs/agents/triage-labels.md`.
### Domain docs
Single-context layout. See `docs/agents/domain.md`.
BIN
View File
Binary file not shown.
@@ -3,6 +3,7 @@ version = "0.1.0"
author = "Davide Cappellini"
description = "GotoTest — throwaway goto(x,y) controller prototype"
license = "MIT"
srcDir = "src"
bin = @["GotoTest"]
# Dependencies
@@ -1,3 +1,4 @@
switch("outdir", "out")
# begin Nimble config (version 2)
when withDir(thisDir(), system.fileExists("nimble.paths")):
include "nimble.paths"
View File
-3
View File
@@ -1,3 +0,0 @@
#!/bin/sh
cd "$(dirname "$0")"
exec ./OscillatorBot 2>> /tmp/oscillatorbot_stderr.log
-1
View File
@@ -1 +0,0 @@
--path:"../libs"
+12
View File
@@ -0,0 +1,12 @@
# Package
version = "0.1.0"
author = "Davide Cappellini"
description = "Oscillator pattern Tank Royale bot"
license = "MIT"
srcDir = "src"
bin = @["OscillatorBot"]
# Dependencies
requires "nim >= 2.0.0"
# tankroyale_botapi and radar_lock are vendored in-tree (common_libs/) and wired via
# config.nims --path; no nimble dependency so builds never touch ~/.nimble/pkgs2.
+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh
cd "$(dirname "$0")"
exec ./out/OscillatorBot 2>> /tmp/oscillatorbot_stderr.log
+2
View File
@@ -0,0 +1,2 @@
--path:"../common_libs"
switch("outdir", "out")
View File
View File
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
@@ -3,10 +3,11 @@ version = "0.1.0"
author = "Davide Cappellini"
description = "PPO-trained Tank Royale bot"
license = "MIT"
srcDir = "src"
bin = @["PPO_Bot"]
# Dependencies
requires "nim >= 2.0.0"
# tankroyale_botapi is vendored in-tree (libs/tankroyale_botapi) and wired via
# tankroyale_botapi is vendored in-tree (common_libs/tankroyale_botapi) and wired via
# config.nims --path; no nimble dependency so builds never touch ~/.nimble/pkgs2.
requires "arraymancer >= 0.7.0"
@@ -4,4 +4,4 @@
# which deadlock when called from within a multi-threaded Nim bot process.
export OPENBLAS_NUM_THREADS=1
cd -- "$(dirname -- "$0")"
exec "./PPO_Bot"
exec "./out/PPO_Bot"
@@ -2,12 +2,14 @@
# ponytail: adjust path per machine, or use pkg-config
switch("passL", "-L/nix/store/v07svn2y92bvzjl51aj7c9ca1cwg7rw7-openblas-0.3.32/lib -lopenblas")
switch("threads", "on")
switch("outdir", "out")
switch("path", thisDir() & "/src")
# begin Nimble config (version 2)
when withDir(thisDir(), system.fileExists("nimble.paths")):
include "nimble.paths"
# end Nimble config
# Use the repo-vendored Tank Royale bot API (libs/) instead of the nimble pkg.
# Use the repo-vendored Tank Royale bot API (common_libs/) instead of the nimble pkg.
# The pkg copy lived in ~/.nimble/pkgs2 and was patched ad-hoc; vendoring makes
# the build self-contained and keeps the cross-thread Channel fix in-tree.
# Must come AFTER the nimble.paths include: later --path wins the import search.
switch("path", thisDir() & "/../libs/tankroyale_botapi")
switch("path", thisDir() & "/../common_libs/tankroyale_botapi")
View File
@@ -4,12 +4,12 @@
import std/[os, strformat, strutils, math, times, algorithm]
import arraymancer
import tankroyale_botapi
import network
import actions
import training
import weights
import ./enemy_tracker
import ./state_vector
import PPO_Bot/network
import PPO_Bot/actions
import PPO_Bot/training
import PPO_Bot/weights
import PPO_Bot/enemy_tracker
import PPO_Bot/state_vector
# ── Hyperparameters from env vars (PPOB_ prefix) ─────────────────────────────
# All optional; defaults match ppoUpdate signature in training.nim.
@@ -64,7 +64,7 @@ proc hyperparmSnapshot(): string =
&"\"logStdFloor\":{logStdFloor},\"logStdCeiling\":{logStdCeiling},\"initialLogStd\":{initialLogStd}"
const botJsonPath = currentSourcePath().parentDir / "PPO_Bot.json"
const weightsRoot = currentSourcePath().parentDir / "weights"
const weightsRoot = currentSourcePath().parentDir / "../weights"
type
InFlightBullet = object
+2
View File
@@ -0,0 +1,2 @@
switch("path", "../src")
switch("path", "../../common_libs/tankroyale_botapi")
Binary file not shown.
@@ -0,0 +1,36 @@
## diag_ppo_fullbuffer.nim — run ppoUpdate on a FULL 8192-transition buffer.
## Verifies whether the round-10 death (first ppoUpdate at buffer capacity)
## is a real crash in ppoUpdate or purely the saveAdamStates empty-shape bug.
import std/[math, random]
import arraymancer
import PPO_Bot/network
import PPO_Bot/training
var ac = initActorCritic()
var adam: ACAdamStates # uninitialised → ppoUpdate must reinit (fresh-process path)
var buf = initTrajectoryBuffer()
randomize(1)
while buf.len < MAX_TRANSITIONS:
var t: Transition
for i in 0..<STATE_DIM: t.state[i] = rand(1.0'f32) - 0.5'f32
for i in 0..<ACTION_DIM: t.action[i] = rand(1.0'f32) - 0.5'f32
t.logProb = rand(1.0'f32) - 1.0'f32
t.reward = rand(0.02'f32) - 0.01'f32
t.value = rand(0.1'f32)
t.done = buf.len mod 300 == 299
buf.add(t)
echo "buffer.len = ", buf.len, " (MAX=", MAX_TRANSITIONS, ")"
var ac2 = ac
var adam2: ACAdamStates
try:
let m = ppoUpdate(ac2, buf, lastValue = 0.0'f32, adamStates = adam2)
echo "ppoUpdate OK: aLoss=", m.actorLoss, " vLoss=", m.valueLoss, " gNorm=", m.gradNorm
except CatchableError as e:
echo "CAUGHT CatchableError: ", e.msg
echo getStackTrace(e)
except Defect as e:
echo "CAUGHT Defect: ", e.msg
echo getStackTrace(e)
Binary file not shown.
@@ -0,0 +1,31 @@
## diag_savecheckpoint.nim — reproduce the startup+saveCheckpoint path that
## crashes with `io_npy.nim(143, 3) `0 < t.shape.len`` under the boot server.
## Run: nim c -d:release tests/diag_savecheckpoint.nim && ./tests/diag_savecheckpoint
import std/[os]
import arraymancer
import PPO_Bot/network
import PPO_Bot/training
import PPO_Bot/weights
const weightsRoot = currentSourcePath().parentDir.parentDir / "weights"
var ac = initActorCritic()
var adam: ACAdamStates
let loadResult = loadBestAvailable(ac, adam, weightsRoot)
echo "loaded=", loadResult.loaded, " roundNum=", loadResult.roundNum
echo "adam.initialized=", adam.initialized
echo "adam.aw1.m.shape=", adam.aw1.m.shape, " aw1.v.shape=", adam.aw1.v.shape
echo "adam.logStd.m.shape=", adam.logStd.m.shape
echo "adam.aw1.t=", adam.aw1.t
try:
saveCheckpoint(ac, adam, weightsRoot, 1)
echo "saveCheckpoint OK"
except CatchableError as e:
echo "CAUGHT CatchableError: ", e.msg
echo getStackTrace(e)
except Defect as e:
echo "CAUGHT Defect: ", e.msg
echo getStackTrace(e)
@@ -3,7 +3,7 @@
import arraymancer
import std/math
import "../actions"
import PPO_Bot/actions
template check(cond: bool, msg: string) =
if not cond:
@@ -2,7 +2,7 @@
## Run: nim c -r tests/test_controllers.nim
import std/math
import "../controllers"
import PPO_Bot/controllers
template check(cond: bool, msg: string) =
if not cond:
@@ -3,8 +3,8 @@
import arraymancer
import std/[math, strformat]
import ../network
import ../actions
import PPO_Bot/network
import PPO_Bot/actions
func isFiniteF(x: float32): bool = classify(x) notin {fcNan, fcInf, fcNegInf}
func isNaNF(x: float32): bool = classify(x) == fcNan
@@ -2,7 +2,7 @@
## Run: nim c -r tests/test_radar_lock.nim
import std/[math, strformat]
import "../enemy_tracker"
import PPO_Bot/enemy_tracker
template check(cond: bool, msg: string) =
if not cond:
@@ -5,8 +5,8 @@ import std/[math, strformat]
import arraymancer
# Import from parent dir
import "../enemy_tracker"
import "../state_vector"
import PPO_Bot/enemy_tracker
import PPO_Bot/state_vector
template check(cond: bool, msg: string) =
if not cond:
@@ -3,8 +3,8 @@
import std/[math, random]
import arraymancer
import "../network"
import "../training"
import PPO_Bot/network
import PPO_Bot/training
template check(cond: bool, msg: string) =
if not cond:
@@ -3,9 +3,9 @@
import std/[os, math]
import arraymancer
import "../network"
import "../training"
import "../weights"
import PPO_Bot/network
import PPO_Bot/training
import PPO_Bot/weights
template check(cond: bool, msg: string) =
if not cond:

Some files were not shown because too many files have changed in this diff Show More