Purge AGENTS.md of code explanation; keep inventory and diagrams
AGENTS.md is now an inventory of what exists plus the mermaid behaviour diagrams — not a narration of the code. The source and its doc comments are the carrier of truth for how the bot works; a prose retelling in AGENTS.md only goes stale against them. Removed: blocks that duplicated what the source already says, a stale line that contradicted DevControlBot.sh's actual no-argument behaviour, and the prior bug-fix history (which is a record of the past, not guidance for the next change). 384 -> 238 lines. Kept byte-identical: the behaviour diagrams, the rules (git, version/tag, colour convention), the build and run commands, and the physics and coordinates references. Two constraints stay as one-liners, because they are the two ways this bot has actually been broken: command the radar BEFORE go(), and keep all radar logic in modules/radar.nim.
This commit is contained in:
+111
-216
@@ -8,7 +8,10 @@
|
|||||||
> from it on purpose and must stay that way.**
|
> from it on purpose and must stay that way.**
|
||||||
>
|
>
|
||||||
> **Do NOT, even to "fix" a perceived inconsistency:**
|
> **Do NOT, even to "fix" a perceived inconsistency:**
|
||||||
> - create `src/`, `tests/`, or `out/`
|
> - create `src/` or `out/`, or put anything inside `DevControlBot/` for testing
|
||||||
|
> (the one exception is the intended `DevControlBot_garage/tests/`, see
|
||||||
|
> "Layout of this folder" — it does not exist yet, create it only when the
|
||||||
|
> first test is actually written)
|
||||||
> - add a `config.nims`, `nimble.paths`, `--path` flags, or a vendor/ directory
|
> - add a `config.nims`, `nimble.paths`, `--path` flags, or a vendor/ directory
|
||||||
> - restructure `DevControlBot/` to match the root template
|
> - restructure `DevControlBot/` to match the root template
|
||||||
>
|
>
|
||||||
@@ -32,222 +35,51 @@
|
|||||||
|
|
||||||
## Start here
|
## Start here
|
||||||
|
|
||||||
This file is the working rules for the bot. The human-facing description lives in
|
The code is the source of truth; this file is an inventory of what exists and how
|
||||||
[README.md](README.md) — read it first.
|
the pieces interact — not a description of what the code does. If the two
|
||||||
|
disagree, the code wins and this file is stale.
|
||||||
|
|
||||||
Garage-specific rules for `DevControlBot_garage/`. Repo-wide rules live in
|
The human-facing description lives in [README.md](README.md). Repo-wide rules live
|
||||||
[`../../AGENTS.md`](../../AGENTS.md) (issue tracker, Nim conventions, test
|
in [`../../AGENTS.md`](../../AGENTS.md) (issue tracker, Nim conventions, test
|
||||||
framework) — read it for that context, but note again: **its folder-layout
|
framework) — read it for that context, but note again: **its folder-layout
|
||||||
template does not govern this garage.**
|
template does not govern this garage.**
|
||||||
|
|
||||||
## Conventions
|
## Conventions
|
||||||
|
|
||||||
|
### Git rule for this garage
|
||||||
|
|
||||||
|
- **EVERYTHING** under `DevControlBot_garage/` gets committed — sources, modules,
|
||||||
|
docs, `PLAN.md` — **unless it is explicitly listed in a `.gitignore`**.
|
||||||
|
- This includes files that look like scratch or generated output, and files an agent
|
||||||
|
did not create: if not gitignored, they belong in the commit.
|
||||||
|
- Do not silently leave a file untracked, and do **not** add entries to
|
||||||
|
`.gitignore` to avoid committing something. The only things that stay out are
|
||||||
|
those the user has deliberately gitignored (e.g. `.env`).
|
||||||
|
|
||||||
|
### Version bumps and tags — the user's decision
|
||||||
|
|
||||||
|
Agents **MUST NOT** bump the version in `DevControlBot.nimble` or
|
||||||
|
`DevControlBot.json`, and **MUST NOT** create git tags. A version bump and its tag
|
||||||
|
are honoured **only** when the user explicitly asks in that conversation; a bump is
|
||||||
|
never a side effect of ordinary work or of a commit. Never amend, rewrite or retag
|
||||||
|
an existing commit or tag.
|
||||||
|
|
||||||
|
### Scope and colour
|
||||||
|
|
||||||
- This bot's code lives **only** inside `DevControlBot_garage/`. Do not edit other
|
- This bot's code lives **only** inside `DevControlBot_garage/`. Do not edit other
|
||||||
garages to make this bot work.
|
garages to make this bot work, and do not reuse another bot's game logic
|
||||||
- Do not reuse or copy another bot's game logic (movement/scanning/firing, radar
|
without explicit permission; shared, bot-agnostic code belongs in
|
||||||
tables, targeting heuristics) without explicit permission from the user. Shared,
|
`common_libs/`, and only with permission.
|
||||||
bot-agnostic code belongs in `common_libs/`, and only with permission.
|
- Team colour convention: **white = not programmed, black = radar active**.
|
||||||
- The radar is the one part currently driven. **All of it is
|
- Provenance: ModularBot / common_libs (Davide Cappellini, Apache-2.0).
|
||||||
`DevControlBot/modules/radar.nim`** — two procs (`onScan`, `commandRadar`),
|
|
||||||
three variables (the target's position, whether we have one, ticks since it was
|
### Constraints worth remembering
|
||||||
last scanned), three constants. Nothing else; do not split it back into
|
|
||||||
|
Not explanations — real invariants that broke things when violated:
|
||||||
|
|
||||||
|
- **Command the radar BEFORE `go()`** — a real bug the other way round.
|
||||||
|
- All radar logic is `modules/radar.nim`, in one piece. Do not split it back into
|
||||||
harness/lock/melee modules.
|
harness/lock/melee modules.
|
||||||
`commandRadar()` issues exactly one `setRadarTurnRate` per tick on every path:
|
|
||||||
lock when `getEnemyCount() == 1` and we hold a target scanned within
|
|
||||||
`FreshScanTurns`, the 45 deg/tick sweep otherwise (that same sweep is both the
|
|
||||||
search and the multi-enemy answer — there is no separate melee mode). No
|
|
||||||
counter, no seen-id set, no mode enum; the server's enemy count drives the
|
|
||||||
choice, so a death switches modes on the spot and no tick is ever left without
|
|
||||||
a command.
|
|
||||||
The lock commands the delta to the target's bearing **plus `OvershootDeg` past
|
|
||||||
it**, so the radar sweeps across the bearing every tick and re-scans the target
|
|
||||||
every tick. That overshoot is the whole reason the lock works, and it is why
|
|
||||||
`setRescan()` is not needed (the radar is never idle). **Never** turn by the
|
|
||||||
bare error and never hold at rate 0: that parks the radar on the bearing, the
|
|
||||||
scans stop, and the target is lost until a sweep re-finds it.
|
|
||||||
A lock is only taken on a target seen within `FreshScanTurns`; a working lock
|
|
||||||
re-scans every tick, so that threshold can never throw a good lock away, and it
|
|
||||||
prevents a blind slew at a stale position just after the count drops to 1.
|
|
||||||
`run()` commands the radar before every `go()`, so the command is part of the
|
|
||||||
tick's intent; `onScannedBot` is a one-liner, `onScan(e.x, e.y)`, which
|
|
||||||
remembers the target's absolute position and issues no command. Angles are
|
|
||||||
0° = east, positive = counter-clockwise = **left** (see README for the API
|
|
||||||
proof). Never the blocking `rescan()`.
|
|
||||||
Provenance: ModularBot / common_libs (Davide Cappellini, Apache-2.0); see README.
|
|
||||||
|
|
||||||
## Build artifacts / binaries
|
|
||||||
|
|
||||||
- **Rule:** never write a binary, log or build output into this garage. The
|
|
||||||
`runBot` task builds into a `mktemp -d` throwaway dir and removes it with an
|
|
||||||
`EXIT`/`INT`/`TERM` trap, so **no `out/` directory is ever created** here.
|
|
||||||
- **Rule:** never commit binaries or nimble cache dirs (`~/.nimble`,
|
|
||||||
`nimbledeps/`). `nimbledeps/` only appears with `nimble develop`; ignore it.
|
|
||||||
- **Rule:** dependencies come from the global nimble store. Do **not** vendor a
|
|
||||||
copy or add `nimble.paths`/`nimble develop` — `nimble install
|
|
||||||
robocode_tankroyale_botapi` is the only setup step. (The package was renamed
|
|
||||||
from `tankroyale_botapi`; the old name is gone.)
|
|
||||||
Exception: the `runBot` task *derives* `--path:` flags at run time from
|
|
||||||
`nimble path <pkg>`, because the compiler's bundled
|
|
||||||
`nimblepath="$home/.nimble/pkgs2/"` only resolves when `$HOME` is set. That is
|
|
||||||
resolution, not vendoring; keep it.
|
|
||||||
- Build/run with the folder task, never raw `nim c`:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
cd DevControlBot_garage/DevControlBot
|
|
||||||
nimble runBot
|
|
||||||
```
|
|
||||||
|
|
||||||
- Note: the root `.gitignore` claims "all builds go to `*_garage/out/`". That is
|
|
||||||
no longer true for this garage — do not rely on that rule, and do not add an
|
|
||||||
`out/` directory just to satisfy it. (Root `.gitignore` is not this garage's
|
|
||||||
file; leave it alone unless the user asks.)
|
|
||||||
|
|
||||||
## Running the bot
|
|
||||||
|
|
||||||
`DevControlBot/DevControlBot.sh` is the canonical entry point and works from any
|
|
||||||
cwd — it resolves `SCRIPT_DIR` from `BASH_SOURCE`, `cd`s to the `.nimble` dir,
|
|
||||||
forwards args and signals to `nimble runBot`, and propagates the exit code.
|
|
||||||
|
|
||||||
```sh
|
|
||||||
./DevControlBot/DevControlBot.sh # from the garage root: bundled metadata
|
|
||||||
./DevControlBot/DevControlBot.sh /path.json # alternate metadata (first arg, must end in .json)
|
|
||||||
./DevControlBot/DevControlBot.sh --debug # classic debug build
|
|
||||||
./DevControlBot/DevControlBot.sh --help # usage, exits 0 without building
|
|
||||||
```
|
|
||||||
|
|
||||||
- **Rule: no arguments means RUN, not usage.** A bare `./DevControlBot.sh`
|
|
||||||
performs a quiet RELEASE build and runs the bot with the bundled
|
|
||||||
`DevControlBot.json`, exactly as if that path had been passed. Usage is
|
|
||||||
printed **only** for an explicit `-h` / `--help`, which exits 0 without
|
|
||||||
building. (An earlier version printed usage and exited 0 with no arguments —
|
|
||||||
that was the bug, and it is fixed.)
|
|
||||||
- There is **no `--json` flag**: the metadata path is the first positional
|
|
||||||
argument and is used when it ends in `.json`. Anything else is forwarded to
|
|
||||||
the bot verbatim.
|
|
||||||
|
|
||||||
- **Build mode:** default is **release** (`nim c -d:release`, quiet: no compiler
|
|
||||||
hints, no dot-progress line, just `[devcontrolbot] build ok (release)`).
|
|
||||||
`--debug` selects the classic debug build (`nim c`, full hints/diagnostics).
|
|
||||||
The flag is stripped by the wrapper in any position and reaches the `runBot`
|
|
||||||
task through the exported env var `$DEVCONTROLBOT_DEBUG` (`debug`/`release`),
|
|
||||||
never as a bot argument. Compiler errors are shown in **both** modes; a failed
|
|
||||||
release build replays the captured compiler log, so it is never silent.
|
|
||||||
- With no arguments (or `--help`) the wrapper prints usage and exits 0 without
|
|
||||||
building.
|
|
||||||
|
|
||||||
- **Gotcha:** `nimble runBot` must be invoked from `DevControlBot/`, the
|
|
||||||
directory containing the `.nimble`. From `DevControlBot_garage/` it fails with
|
|
||||||
`Could not find a file with a .nimble extension inside the specified directory`.
|
|
||||||
- `compile`/`build` are reserved Nimble builtin names — hence `runBot`.
|
|
||||||
- Without a Tank Royale server at `SERVER_URL` the run fails with
|
|
||||||
`[start] Cannot connect ... Connection refused` and exit code 1. That is
|
|
||||||
expected during local verification, not a bug.
|
|
||||||
|
|
||||||
## Configuration = environment variables (the API's own mechanism)
|
|
||||||
|
|
||||||
- **Rule: never add env-reading code to `DevControlBot.nim`.** The bot API
|
|
||||||
already reads its configuration from the process environment inside
|
|
||||||
`start()`: `SERVER_URL` and `SERVER_SECRET`
|
|
||||||
(`robocode_tankroyale_botapi.nim:424-425`, documented at `:396-397`) and
|
|
||||||
`BOT_NAME` / `BOT_VERSION` / `BOT_AUTHORS` / … in `bot_info.nim:117-130`
|
|
||||||
(used when no JSON metadata is found). That is the supported mechanism the
|
|
||||||
official BotLauncher uses; `DevControlBot.nim` calls plain `start(bot,
|
|
||||||
jsonPath)` and needs no change.
|
|
||||||
- The `runBot` task makes those variables **present** for local runs (see the
|
|
||||||
`.env` section). That is all it does; it does not interpret them.
|
|
||||||
|
|
||||||
## Optional `.env` (local runs only)
|
|
||||||
|
|
||||||
`DevControlBot/.env` holds the local configuration (typically `SERVER_URL` and
|
|
||||||
`SERVER_SECRET`). Rules:
|
|
||||||
|
|
||||||
- **It is optional.** If it is missing the run is unchanged: no error, no
|
|
||||||
non-zero exit, just one informational line and the API defaults.
|
|
||||||
- **Loaded in the `runBot` task's shell**, not in `DevControlBot.sh`, so it works
|
|
||||||
for both `./DevControlBot.sh` and a direct `nimble runBot` and the wrapper
|
|
||||||
stays a thin wrapper. `$DEVCONTROLBOT_ENV_FILE` overrides the path.
|
|
||||||
- **Precedence — CRITICAL: the environment always wins.** A variable already
|
|
||||||
present in the environment is **never** overridden by `.env`, so the official
|
|
||||||
BotLauncher's values keep winning. It is achieved by *filtering*: a
|
|
||||||
`NAME=value` line is dropped when `NAME` is already set (`[ -n "${NAME+x}" ]`,
|
|
||||||
set-but-maybe-empty), and only the still-unset names are `set -a`-exported and
|
|
||||||
sourced. Do **not** "simplify" this into a plain `set -a; . .env` — sourcing
|
|
||||||
does the opposite and would let the file beat the launcher.
|
|
||||||
- Accepts `FOO=bar` and `export FOO=bar`, strips `CR` (CRLF), skips blanks,
|
|
||||||
`#` comments and any line that is not a plain `NAME=value` identifier.
|
|
||||||
- **Never print values** and never use `set -x`: report variable *names* only.
|
|
||||||
- **Never commit it** — it holds secrets. The root `.gitignore` covers
|
|
||||||
`ModularBot_garage/.env` only and does **not** ignore this one; the rule to
|
|
||||||
add (ask the user before touching the root file) is
|
|
||||||
`DevControlBot_garage/DevControlBot/.env`.
|
|
||||||
|
|
||||||
## Failure reporting / exit codes
|
|
||||||
|
|
||||||
- **Rule:** an expected failure must never surface as a Nimble/NimScript
|
|
||||||
exception. `exec` raises on any non-zero exit, printing a stack trace and an
|
|
||||||
escaped copy of `runScript`. So the shell always exits 0 and writes the real
|
|
||||||
code to `$DEVCONTROLBOT_STATUS_FILE`; `DevControlBot.sh` exports that path and
|
|
||||||
re-exits with the code. Never mask it to 0, never let the shell's code be
|
|
||||||
swallowed.
|
|
||||||
- Exit codes (keep them distinct, they are what BotLauncher branches on):
|
|
||||||
`0` clean, `1` no game server at `SERVER_URL` (expected), `2` dependency not
|
|
||||||
installed, `3` compile failure, anything else = the bot's own code.
|
|
||||||
Each prints its own short, actionable line; compile failures keep the raw
|
|
||||||
compiler errors.
|
|
||||||
- Running `nimble runBot` directly (no status file) intentionally falls back to
|
|
||||||
the legacy behaviour: the shell exits with the real code and Nimble raises.
|
|
||||||
|
|
||||||
## Test organization
|
|
||||||
|
|
||||||
- **There are currently no tests in this garage.** No `tests/` directory, no
|
|
||||||
`tests/config.nims`, and the `.nimble` has exactly one task (`runBot`) — the old
|
|
||||||
`test`, `compileBot` and `setupVendor` tasks are gone. `nimble test` does not
|
|
||||||
exist; do not invoke it and do not document it.
|
|
||||||
- Convention **when** tests are added (repo-wide, see
|
|
||||||
[`../../AGENTS.md`](../../AGENTS.md) and
|
|
||||||
`common_libs/test_framework/README.md`):
|
|
||||||
- create `DevControlBot_garage/tests/` with `tests/config.nims` containing
|
|
||||||
`--path:"../../common_libs"` (depth must match the garage location), one
|
|
||||||
`test<concern>.nim` per concern (e.g. `test_basic_battle.nim`);
|
|
||||||
- add a `test` task to `DevControlBot.nimble` running
|
|
||||||
`nim c -r --path:../common_libs tests/test_basic_battle.nim`;
|
|
||||||
- guard first, import second — tests must pass with no Java present:
|
|
||||||
|
|
||||||
```nim
|
|
||||||
import std/os
|
|
||||||
if not existsEnv("TR_SERVER_JAR") or not existsEnv("TR_BATTLE_RUNNER"):
|
|
||||||
echo "Skipping: TR_SERVER_JAR / TR_BATTLE_RUNNER not set"
|
|
||||||
quit(0)
|
|
||||||
|
|
||||||
import test_framework/test_framework
|
|
||||||
```
|
|
||||||
|
|
||||||
- shared adversaries: `common_libs/test_framework/adversaries/SittingDuck`
|
|
||||||
(passive) and `OscillatorBot` (fights back); standard call is
|
|
||||||
`runBattle(@[myBotDir, adversaryDir], rounds = 10)`.
|
|
||||||
- env vars: `TR_SERVER_JAR`, `TR_BATTLE_RUNNER`. Failures surface as `OSError`
|
|
||||||
(bot compile failed), `IOError` (runner non-zero), `TimeoutError`
|
|
||||||
(server 15s / compile 30s per bot / battle runner).
|
|
||||||
|
|
||||||
## Onboarding — full sequence
|
|
||||||
|
|
||||||
```sh
|
|
||||||
# 1. dependency (once; already global if nimble install says "already installed")
|
|
||||||
nimble install robocode_tankroyale_botapi
|
|
||||||
|
|
||||||
# 2. run the bot (compiles to a temp dir, runs, cleans up; nothing left behind)
|
|
||||||
./DevControlBot/DevControlBot.sh
|
|
||||||
|
|
||||||
# 2b. same thing via the task — must be run from DevControlBot/
|
|
||||||
cd DevControlBot && nimble runBot
|
|
||||||
|
|
||||||
# 3. tests — none exist yet; see "Test organization" above
|
|
||||||
```
|
|
||||||
|
|
||||||
Checklist after touching build config:
|
|
||||||
- `cd DevControlBot && nimble runBot` compiles (fails only on "Cannot connect"
|
|
||||||
without a server) and leaves the garage tree unchanged (`ls DevControlBot_garage`
|
|
||||||
still shows only `AGENTS.md`, `README.md`, `DevControlBot/`).
|
|
||||||
|
|
||||||
## Layout of this folder
|
## Layout of this folder
|
||||||
|
|
||||||
@@ -255,14 +87,77 @@ Checklist after touching build config:
|
|||||||
DevControlBot_garage/
|
DevControlBot_garage/
|
||||||
├── AGENTS.md # this file
|
├── AGENTS.md # this file
|
||||||
├── README.md # human-facing description
|
├── README.md # human-facing description
|
||||||
└── DevControlBot/
|
├── PLAN.md # the user's own notes — never edit (see header)
|
||||||
├── DevControlBot.nim # bot type + entry point (isMainModule)
|
├── .gitignore # ignores .env
|
||||||
├── DevControlBot.json # bot metadata
|
├── DevControlBot/
|
||||||
├── DevControlBot.nimble # single task: runBot
|
│ ├── DevControlBot.nim # bot type + entry point (isMainModule)
|
||||||
├── DevControlBot.sh # BotLauncher entry point (thin wrapper)
|
│ ├── DevControlBot.json # bot metadata
|
||||||
└── .env # OPTIONAL local config; secrets, never commit
|
│ ├── DevControlBot.nimble # single task: runBot
|
||||||
|
│ ├── DevControlBot.sh # BotLauncher entry point (thin wrapper)
|
||||||
|
│ ├── .env # OPTIONAL local config; secrets, never commit
|
||||||
|
│ └── modules/
|
||||||
|
│ └── radar.nim # all radar logic
|
||||||
|
└── tests/ # INTENDED, does not exist yet — create it on
|
||||||
|
# the first real test
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- `DevControlBot/` holds only what the bot needs to run.
|
||||||
|
- `tests/` is a sibling of `DevControlBot/`, never inside it, and holds **test
|
||||||
|
code worth keeping**: drivers, harnesses, reusable battle/probe scripts.
|
||||||
|
- **Throwaway output does NOT go here or anywhere in the repo — it goes to
|
||||||
|
`/tmp`**: logs, temporary binaries, dumps, telemetry, scratch output.
|
||||||
|
- No `out/`, no binaries, no `nimbledeps/` here. Builds are throwaway by design.
|
||||||
|
|
||||||
|
## Build and run
|
||||||
|
|
||||||
|
Use the folder task, never raw `nim c`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd DevControlBot_garage/DevControlBot
|
||||||
|
nimble runBot # quiet release build + run
|
||||||
|
```
|
||||||
|
|
||||||
|
Or via the wrapper, which works from any cwd:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./DevControlBot/DevControlBot.sh # bundled metadata
|
||||||
|
./DevControlBot/DevControlBot.sh my.json # first positional arg, must end in .json
|
||||||
|
./DevControlBot/DevControlBot.sh --debug # classic debug build (hints + diagnostics)
|
||||||
|
./DevControlBot/DevControlBot.sh --help # usage, exits 0 without building
|
||||||
|
```
|
||||||
|
|
||||||
|
- **No arguments means RUN, not usage.** Usage prints only for `-h` / `--help`.
|
||||||
|
There is no `--json` flag; a first positional ending in `.json` overrides the
|
||||||
|
metadata, anything else is forwarded to the bot verbatim.
|
||||||
|
- **Gotcha:** `nimble runBot` must run from `DevControlBot/` (where the
|
||||||
|
`.nimble` lives); from `DevControlBot_garage/` it fails with
|
||||||
|
`Could not find a file with a .nimble extension...`. `compile`/`build` are
|
||||||
|
reserved Nimble builtin names — hence `runBot`.
|
||||||
|
- **Config is environment-only.** The bot API's `start()` reads `SERVER_URL` /
|
||||||
|
`SERVER_SECRET` itself; **never add env-reading code to `DevControlBot.nim`.**
|
||||||
|
The optional `.env` (loaded by the `runBot` task, `$DEVCONTROLBOT_ENV_FILE`
|
||||||
|
overrides the path) is local-runs-only and **never overrides a variable already
|
||||||
|
present in the environment** — the BotLauncher's values always win. Never print
|
||||||
|
its values, never `set -x`, never commit it.
|
||||||
|
- Dependency setup is `nimble install robocode_tankroyale_botapi`; dependencies
|
||||||
|
come from the global nimble store. Do not vendor, do not add
|
||||||
|
`nimble.paths` / `nimble develop`.
|
||||||
|
- Without a game server at `SERVER_URL` the run fails with
|
||||||
|
`[start] Cannot connect ... Connection refused`. That is expected locally, not a
|
||||||
|
bug.
|
||||||
|
- Exit codes are distinct because BotLauncher branches on them: `0` clean,
|
||||||
|
`1` no server (expected), `2` dependency missing, `3` compile failure,
|
||||||
|
anything else = the bot's own code.
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
|
There are **no tests yet** — no `tests/` directory and no `test` task; `nimble test`
|
||||||
|
does not exist. When the first test is written, follow the repo-wide convention in
|
||||||
|
[`../../AGENTS.md`](../../AGENTS.md) and
|
||||||
|
`common_libs/test_framework/README.md`: `tests/config.nims` with
|
||||||
|
`--path:"../../common_libs"`, one `test<concern>.nim` per concern, a `test` task
|
||||||
|
in the `.nimble`, and a guard-first block so tests pass with no Java present.
|
||||||
|
|
||||||
## Coordinates & angles (source: robocode.dev/articles/coordinates-and-angles.html)
|
## Coordinates & angles (source: robocode.dev/articles/coordinates-and-angles.html)
|
||||||
|
|
||||||
Source: https://robocode.dev/articles/coordinates-and-angles.html (Tank Royale docs)
|
Source: https://robocode.dev/articles/coordinates-and-angles.html (Tank Royale docs)
|
||||||
@@ -341,4 +236,4 @@ Source: https://robocode.dev/articles/physics.html (Tank Royale docs)
|
|||||||
- Collision with bot/wall stops the bot, except when moving away from the bot that hit it.
|
- Collision with bot/wall stops the bot, except when moving away from the bot that hit it.
|
||||||
- Bot-vs-bot collision: 0.6 damage to each.
|
- Bot-vs-bot collision: 0.6 damage to each.
|
||||||
- Ramming (moving forward into another bot): both take damage; rammer gets ramming kill bonus. Wall damage: |v|/2 - 1, clamped at 0 if negative.
|
- Ramming (moving forward into another bot): both take damage; rammer gets ramming kill bonus. Wall damage: |v|/2 - 1, clamped at 0 if negative.
|
||||||
- NOT stated on this page: coordinate system/axes/units, Y up or down, angle origin & clockwise/CCW sense, distance/bearing formulas, angle normalization/wrapping, max energy, per-turn energy regain from inactivity.
|
- NOT stated on this page: coordinate system/axes/units, Y up or down, angle origin & clockwise/CCW sense, distance/bearing formulas, angle normalization/wrapping, max energy, per-turn energy regain from inactivity.
|
||||||
Reference in New Issue
Block a user