Clunkyard robot SDK

Start from the working project for your language in the workbench. Change its tactics, save and build. The arena supplies the robot core and its language binding; a project does not need to copy the SDK.

For your own editor, clone a language starter and follow Develop a robot on your computer. Use your installed toolchain, download only its SDK, and run real matches with make match. Use private Git to push changes back to a saved arena bot. The small Makefile calls the shared npm CLI. Without Make, run npx @clunkyard/cli build, match and replay from the project.

JavaScript and TypeScript can install the Node 20+ API from npm:

npm install clunkyard@npm:@clunkyard/sdk

The clunkyard alias keeps local and hosted imports the same. The package includes TypeScript declarations and the WebAssembly core. Use the language starter and shared @clunkyard/cli for the separate match engine and replay tools. Install @clunkyard/git to clone and push your saved arena projects; the setup guide covers platform-specific installation and sign-in.

The core owns protocol 2 parsing, observations, contact tracking, geometry, shot solutions, finite checks and act serialization. Each binding exposes those operations in its language's style. A call to a control changes only the fields supplied; a later call replaces those fields and keeps the rest.

API names lists every operation across the languages. The generated pages in docs/sdk and the READMEs under bindings include complete small robots and each language's build and launch instructions. The full starter tactics live in src/public/starters.

Choose a surface

Language family Surface supplied by the arena
C Generated header and native core library
C++, Rust, Go, Hew, Swift, Zig, Haskell, OCaml, Fortran, D, Ada, Nim, Mercury, Pascal, FreeBASIC Generated native binding; hosted builds link the installed core
Python, R, Ruby, Perl, Lua, PHP, Julia, Common Lisp Installed runtime package and native core
Java, Kotlin, Scala, Clojure Shared Java binding through the Foreign Function and Memory API
C#, F#, PowerShell Shared .NET binding and launcher
Erlang, Elixir Native module and generated BEAM API
Prolog, CHR Native module and generated predicates
JavaScript, TypeScript Generated Node API on the core's WebAssembly build
CLIPS, Forth, APL, MiniZinc Language adapter on the Python core binding
BQN Language adapter on the Node core binding
Vane, Cadence, Glyph Built-in interpreter using the core
WAT, AssemblyScript, C, Rust, Zig compiled to WebAssembly ABI 4 core imports
Shell A small jq protocol helper in shell

Protocol 2 is the only robot wire protocol. A raw protocol robot may read and write its own JSON; the protocol reference describes the messages. The binding is the normal starting point.

Write a robot

A Python robot subclasses Robot, overrides on_start when it needs match-wide setup and implements on_turn:

import clunkyard as cy

class Scout(cy.Robot):
    def on_turn(self):
        self.drive.set(throttle=0.5, turn=0.3)
        target = self.sensors.nearest
        if target:
            power = self.gun.power_for_flight_time(target.range, 1)
            aim = self.gun.lead(target, power)
            heading = aim.heading if aim else target.bearing
            pitch = aim.pitch if aim else target.elevation
            self.scanner.set(heading=target.bearing, arc=20, pitch=target.elevation)
            self.gun.aim(heading, pitch)
            now = self.gun.aim_now
            if (abs(cy.angles.angle_diff(heading, now.heading)) < 3
                    and abs(pitch - now.pitch) < 3
                    and self.gun.can_fire(power, 10)):
                self.gun.fire(power)

cy.run(Scout())

The ready reply identifies the binding and core API version, for example clunkyard-python and 2.0.0. The wire protocol version and core API version are separate contracts.

Observations describe the current turn. Optional results, such as a missing precise contact or an unreachable shot, use the language's absent value. Native C callers receive CY_NONE. Controls reject non-finite numbers. Use the named subsystems for both reads and writes: me, match, arena, battery, gun, scanner, sensors, tracker, nav, clock, drive, status, rng, angles and session.

Diagnostics and failures

Write diagnostics to standard error. Binding launchers preserve the protocol output stream and redirect ordinary user diagnostics where the runtime supports it. A raw protocol implementation must send exactly the reply due for each input line and flush it.

A recoverable core fault answers the affected state with an empty act, resets tracking at the next state and continues. After three core faults, the handle answers later states with empty acts. A core fault is never reported as the robot's crash. An unrecoverable output failure ends the run. Language exceptions in user tactics follow the binding's documented rules; uncatchable language or process failures can still end the robot.

A deliberate forfeit sends the core's forfeit reply. See the language's README for its exception, predicate or function.

Hosted builds

Builds have no network access. Use the standard library, the installed core binding or source included in the project. The builder supplies include, module and library paths. Compiled programs carry the robot's own output; shared core packages stay in the runtime image. The runtime image contains no compiler, assembler or linker.

A Go project with its own go.mod uses a builder-owned workspace to resolve clunkyard locally. The builder does not rewrite the project's module. C# and F# projects reference the installed binding with the ClunkyardSdk MSBuild property; the .NET launcher loads that binding from the image.

Standard CPU limits depend on the runtime's frozen Season 3 tier and measured overhead floor. Reflex uses DSL operations or WebAssembly fuel. Open uses own time and supports a remote strategist. The selected match shows its limits; the manual explains the classes.

Develop off the platform

Install the native core and the binding under one SDK directory, then follow the binding's README. CLUNKYARD_LIB may select the native shared library for local checks. JavaScript and TypeScript use the core's WebAssembly build through the supplied Node launcher. ABI 4 robots run through the Wasmtime host; see the WebAssembly SDK.

The JavaScript npm package runs on Windows, macOS and Linux with Node 20+. Native SDKs also support selected languages on Apple Silicon, Intel macOS and Windows x86-64, alongside Linux x86-64/glibc 2.39+. The player kit lists the language and platform combinations, official toolchain installers and normal build commands.

Maintain the API

protocol/v2/api.js is the API model. make api regenerates the C ABI, record layouts, bindings, conformance drivers, references and name tables. Edit the model or a generator template, then regenerate; do not edit a generated surface by hand.

make api-check rejects stale output and reserved names. make sdk-test checks the available language bindings against the shared conformance vectors and compares the READMEs' small robots act for act. Local checks report absent toolchains; make sdk-test-image requires every toolchain. make starter-test-image builds and plays the complete starter projects through all rulesets. make check combines the release checks.

Reference pages

Download this page as Markdown