# Develop a robot on your computer

Choose a language starter from [Clunkyard's game kit](https://github.com/clunkyard/game-kit).
Each repository contains the same starter as the online editor, normal source
files and a small Makefile. Shared build, download and match code lives in the
[@clunkyard/cli](https://www.npmjs.com/package/@clunkyard/cli) npm package.
Bring Node 20+ with npm and your existing compiler or interpreter; the CLI
downloads the common engine and only that language's binding.

For C:

```sh
git clone https://github.com/clunkyard/starter-c.git
cd starter-c
make doctor
make
make match
make replay
```

The first run downloads the CLI through npm, along with the match engine and
your language's SDK. Downloaded files go under `.clunkyard/` in your project.
Install your compiler or interpreter separately. To use an existing matching
native SDK, set `CLUNKYARD_SDK` to its path.

## Supported platforms

Install [Node 20+ with npm](https://nodejs.org/en/download) and your selected
language's compiler or interpreter. The CLI downloads the SDK for your
operating system and CPU, then builds with those tools. It never installs
compilers or the all-language builder.

| Local platform | Native language starters |
| --- | --- |
| Linux x86-64, glibc 2.39+; Ubuntu 24.04+ or WSL2 Ubuntu 24.04+ | All offered native profiles |
| Linux AArch64, glibc 2.39+ | C and C++ |
| macOS, Apple Silicon | C, C++, Python, Rust, Ruby, Swift, Java and C# |
| macOS, Intel | C, C++, Python and Rust |
| Windows 11 x86-64 | C, C++, Python, Rust and C# |

JavaScript, TypeScript and the Vane/Cadence/Glyph Node routes work on Linux,
macOS and Windows through the WebAssembly core. TypeScript also needs its
compiler. Other local profiles, including the Wasmtime-based profiles, use
Linux packages. You can use hosted builds and trials when your computer lacks
a language's local SDK or toolchain.

On macOS, C/C++ use Xcode Command Line Tools. On Windows, use MSVC's Developer
PowerShell or Developer Command Prompt for C/C++, or a working Clang toolchain.
Python, Rust's MSVC toolchain and C# can use ordinary PowerShell; SDK binding
installation needs no Unix shell or GNU Make. Use the direct CLI commands
below if Make is not installed.

| Toolchain | Official setup |
| --- | --- |
| C/C++ on macOS | [Xcode and Command Line Tools](https://developer.apple.com/xcode/resources/) |
| C/C++ on Windows | [Visual Studio C++ tools and Developer Shell](https://learn.microsoft.com/en-us/cpp/build/building-on-the-command-line) |
| Python | [Python downloads](https://www.python.org/downloads/) |
| Rust | [rustup installation](https://www.rust-lang.org/tools/install); choose the MSVC toolchain on Windows |
| Ruby | [Ruby installation](https://www.ruby-lang.org/en/documentation/installation/) |
| Swift | [Swift installation](https://www.swift.org/install/) |
| Java | [JDK setup](https://dev.java/learn/getting-started/); JDK 22+ with javac |
| C# | [.NET SDK downloads](https://dotnet.microsoft.com/en-us/download); the starter targets .NET 10 |

The native macOS core targets macOS 11 or later; Node and your selected
compiler can have a newer OS requirement. Rust's desktop binding loads the
shared C runtime, so it rebuilds with your Rust compiler without bundling
another compiler's standard library. Compiler-specific modules rebuild after
your toolchain version changes. A custom matching installation can be selected
with an absolute or relative `CLUNKYARD_SDK` path.

Without Make, use the CLI directly from the project directory:

```sh
npx @clunkyard/cli doctor
npx @clunkyard/cli build
npx @clunkyard/cli match
npx @clunkyard/cli replay
```

You can also create the same starter without cloning its repository:

```sh
npx @clunkyard/cli new c my-robot
```

Replace `c` with your language and choose a directory that does not exist yet.
The CLI reads `bot.json` from your current directory; use `--project PATH` to
work on another project. `doctor` checks the selected tools and never installs
one automatically.

## Your project

Keep your robot source, `bot.json`, README, `.gitignore`, small Makefile and
any normal language build files. JavaScript and TypeScript projects also keep
`package.json` and `package-lock.json` for the npm SDK.

The Makefile uses `CLUNKYARD ?= npx --yes @clunkyard/cli`, so tooling
updates are available without editing every starter. To record the CLI version
used for a trial:

```sh
npx @clunkyard/cli --version
```

Record that version with your source commit and language lockfiles when
comparing trials. Ordinary setup commands use the current CLI.

## JavaScript and TypeScript from npm

Use [starter-javascript](https://github.com/clunkyard/starter-javascript) or
[starter-typescript](https://github.com/clunkyard/starter-typescript) for the
complete edit, build, match and replay flow. Their robot API is available on
npm as [@clunkyard/sdk](https://www.npmjs.com/package/@clunkyard/sdk). To add it
to another Node 20+ project:

```sh
npm install clunkyard@npm:@clunkyard/sdk
```

Use `require('clunkyard')` or `import ... from 'clunkyard'` in robot source so
the same import works in the hosted arena. The package includes the WebAssembly
core and TypeScript declarations. Keep the generated `package-lock.json` in
Git and use `npm ci` to restore its exact dependency versions. Keep
`node_modules/` ignored. TypeScript also needs your installed TypeScript
compiler. For local matches, use a starter project: its CLI and Make targets
provide the match engine and the matching SDK.

## Install only your adapter's dependencies

`doctor` checks the selected compiler commands and adapter prerequisites. It
reports a missing dependency with an installation hint; it never installs one.
Use the language guide's official installation links for the toolchain.

| Adapter | Additional local requirements |
| --- | --- |
| Java, Kotlin, Scala, Clojure | JDK 22+, including `javac`. Scala and Clojure also need their own runtime libraries. Use `SCALA_LIBRARY_JAR`, `CLOJURE_JAR` or `CLOJURE_CLASSPATH` for a custom installation; the Clojure CLI classpath is also accepted. |
| CLIPS | Python 3 with `clipspy==1.0.6`. Create and activate a virtual environment, then run `python3 -m pip install clipspy==1.0.6`. A standalone CLIPS executable is insufficient. |
| Forth | Python 3 and GForth (`gforth` on PATH). |
| APL | Python 3 and GNU APL 2.0 (`apl` on PATH). |
| BQN | Node and CBQN 0.12.0 (`bqn` on PATH). |
| MiniZinc | Python 3, MiniZinc, Gecode and `fzn-gecode` on PATH. |
| Perl | Perl development headers and a C compiler; the XS shim rebuilds for your Perl. Ubuntu: `libperl-dev` and `build-essential`. |
| Lua | Lua 5.4, its development headers, `pkg-config` and a C compiler. Ubuntu: `liblua5.4-dev`, `pkg-config` and `build-essential`. |
| PHP | PHP's FFI extension; the local launcher enables FFI for its own process. |
| R | R development headers and a C compiler. Ubuntu: `r-base-dev`. |
| Erlang / Elixir | Erlang development headers and a C compiler. Ubuntu: `erlang-dev` and `build-essential`. |
| TypeScript | TypeScript 6+, qualified with 6.0.3. |
| C → WebAssembly | Clang's wasm32 backend and `wasm-ld` (Ubuntu's `lld` package). |
| Rust → WebAssembly | The `wasm32-unknown-unknown` target: `rustup target add wasm32-unknown-unknown`. |
| AssemblyScript | `asc`, qualified with AssemblyScript 0.28.20. |
| Zig / Zig → WebAssembly | Qualified with Zig 0.17.0; older build flags may differ. |
| Hew | Hew 0.10.0 or later and a C compiler. |

Other bindings use their listed compiler/interpreter and normal system
libraries. Compiler-specific SDK modules are rebuilt by that installation.
Native qualification uses Ubuntu 24.04 and the recorded release toolchains;
a different compiler version can still require a language-specific adjustment.

## Repeat a real local trial

```sh
npx @clunkyard/cli match 42 2d classic
npx @clunkyard/cli match 77 3d zero-g
npx @clunkyard/cli replay replays/trial-42.json
```

Edit the entry file, rebuild and repeat several seeds and rulesets. Keep a
baseline commit. The replay records the engine's real states, shots, hits and
failures; pause and step through the first useful difference. Local programs
run as your user. Local timing is useful for compatibility checks but does
not replace authoritative arena budget qualification.

See [local trials](local-trials.md) for matched comparisons and both seat
orders, and the [C API and ABI](sdk/c-api.md) and [adapter guides](sdk/adapters.md)
for the complete API.

## Use a contained toolchain when needed

The C, Python, JavaScript and DSL starters also offer an optional Dockerfile.
It uses official public Node and Ubuntu 24.04 bases and installs the selected
toolchain. It does not require a Clunkyard registry login or download 56
languages. Native SDK packages use the same glibc baseline as the container.

```sh
mkdir -p replays
docker build -t my-clunkyard-c .
docker run --rm -v "$PWD/replays:/workspace/replays" my-clunkyard-c match
```

The first image build downloads its public base and selected OS packages;
the first run downloads its pinned SDK and engine. Containers currently
target Linux x86-64. Other CPUs can request `--platform linux/amd64` for both
commands with emulation overhead. On Linux, output created by the container
may need an ownership adjustment. Use the native Make route when the
toolchain is already installed.

## Connect the project to the arena

Open [New bot](https://clunkyard.com/?create=starter#bots) and choose a
language starter or a published House bot, then choose its source home.
For a private arena project, install the
[@clunkyard/git helper](private-git.md) from npm, sign in with an agent access
key and copy the clone command from the bot's **Connections → Private Git**
panel. Edit, commit and push: each accepted push saves a source revision and
queues its hosted build. The [private Git guide](private-git.md) explains how
to bring an existing language starter into that private clone and merge browser
or WebDAV edits before pushing.

For code already on GitHub, choose
[An existing GitHub project](https://clunkyard.com/?create=github#bots).
Connect your personal account, then pick a repository, branch and project
folder. Clunkyard reads its language from `bot.json`; its first revision
contains your selected source. For a new starter or House copy, choose
**My GitHub account** as its source home and confirm the new private
repository's name and source. Commits pushed to the selected ref become immutable saved source
revisions and queue builds. Run an arena trial, then follow its replay back
to the revision that played.

Save browser edits before syncing, and resolve conflicts explicitly. Keep
SDK downloads, output and access tokens out of Git. Browser editing and
WebDAV remain available for players who prefer them.

Public releases retain their checksums. A changed release requires a new
version, rather than overwriting an asset that an existing checkout pins.


## Connect code running on your computer

Use Node 22+ for the connection's built-in WebSocket client. Copy the connection
settings from your bot's Connections panel into shell environment variables:
`CLUNKYARD_REMOTE_URL`, `CLUNKYARD_REMOTE_TOKEN` and `CLUNKYARD_BOT_ID`. Keep the
key out of source and command arguments. Then run from your robot directory:

```sh
npx @clunkyard/cli connect
npx @clunkyard/cli connect --strategist python3 strategist.py
```

With no command, the CLI builds the project and starts its SDK-aware stdio runner, including the downloaded language binding and native library. Use an explicit command only for a self-contained protocol program with its dependencies already installed.

The shared CLI contains the same remote bridge as the standalone download.
It starts your command without a shell, sends match messages over its standard
input/output and reconnects when the network drops. A remote robot plays Open;
a strategist supplies policy to its hosted reflex between turns. The child
receives no Clunkyard connection keys. For additional environment variables
your program needs, list their names in `CLUNKYARD_BOT_ENV_ALLOW`. Keep the CLI
running until the match ends; Ctrl-C stops the connection and child processes.
