# robocode_fixture_capture Reproduces the classic-Robocode **DrussGT movement fixtures** in `tools/fixtures/` (see `tools/fixtures/DRUSSGT_FIXTURES.md` for the data, conversion and caveats). ## Run it ```sh tools/robocode_fixture_capture/capture.sh # writes to tools/fixtures tools/robocode_fixture_capture/capture.sh /tmp/out # or another directory ``` The script: 1. downloads classic Robocode 1.9.5.5 from SourceForge into `/tmp/robocode/` (its "setup jar" is a plain zip of the full install), 2. downloads the third-party `DrussGT.jar` from the Robocode archive, 3. builds the trivial `trivial.StraightLine` contrast bot as a jar, 4. compiles `Capture.java` and runs the headless battles, 5. writes `*.jsonl` fixtures plus `drussgt_meta/*.rounds.json` sidecars. **The Robocode distribution and the DrussGT jar are third-party redistributables and are intentionally kept out of the repository** — they live only under `/tmp/robocode/`. Nothing under `/tmp` is committed. ## Files | File | Purpose | |---|---| | `capture.sh` | download + build + run everything | | `Capture.java` | headless `RobocodeEngine` observer that dumps per-turn state to JSONL | | `StraightLine.java` / `StraightLine.properties` | trivial constant-speed contrast bot | | `analyze.py` | conversion validation + movement statistics | ## Running the engine headlessly Robocode 1.9.5.5 installs a `SecurityManager` and reflects into `sun.net.www.protocol.jar`. On Java 21 both are blocked by default, so the JVM needs (this is what `capture.sh` uses): ``` -Djava.security.manager=allow --add-opens=java.base/sun.net.www.protocol.jar=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.desktop/sun.awt=ALL-UNNAMED ``` Java 17/11 work with fewer flags (the `--add-opens` for `sun.net` is still required on 17+). ## Key API gotchas found while building this - `RobocodeEngine.getLocalRepository(name)` requires the **full class name** (`jk.mega.DrussGT`, not `DrussGT`). A robot added as loose `.class` files is indexed but marked unusable (`trivial.StraightLine*`) and cannot be selected; packaging it as a **jar** with a `robots:` manifest entry fixes it. Delete `robots/robot.database` to force a repository rescan. - `IRobotSnapshot.getBodyHeading()` / `getGunHeading()` / `getRadarHeading()` return **radians** (classic convention: 0=north, clockwise) — the rest of the classic robot API uses degrees. `getVelocity()` is signed px/turn. See the conversion in `tools/fixtures/DRUSSGT_FIXTURES.md`. ## Validate / analyse ```sh python3 tools/robocode_fixture_capture/analyze.py \ tools/fixtures/drussgt_vs_*.jsonl tools/fixtures/contrast_*.jsonl ``` `analyze.py` reports the coordinate-conversion check (mean angular error between recorded displacement and the direction implied by `eh`+`es`; expect 0.000°), speed / heading-change distributions, range statistics and the perpendicular-vs-radial split.