The Java binding
The Clunkyard robot API in Java, over the robot core's C ABI through the
Foreign Function and Memory API on JDK 25
(docs/design/robot-core.md, sections 5.3
and 5.4). The classes are generated by protocol/v2/codegen/bindings/java.js
(make api), except Robot, Clunkyard, Forfeit and
ClunkyardException, which are written by hand, as is the reflective
conformance test, test/TestConformance.java.
docs/sdk/names.md gives every name.
- Install:
make install SDK=/opt/clunkyard/sdkbuilds$(SDK)/bindings/java/clunkyard.jar. - Build and run:
javac -cp /opt/clunkyard/sdk/bindings/java/clunkyard.jar Bot.java, thenjava --enable-native-access=ALL-UNNAMED -cp .:/opt/clunkyard/sdk/bindings/java/clunkyard.jar Bot. The jar loadslibclunkyard.so.2through the loader's cache, or the fileCLUNKYARD_LIBnames. - Test:
make test SDK=...runs the installed jar against every API vector, exact against the core.
Subsystems are methods of the robot (me(), match(),
scanner().last()). An absent result is an empty Optional,
OptionalDouble or OptionalInt. A control takes its fields in order
(gun().aim(heading, pitch)), and one with several fields also takes a
builder (drive().set(Drive.turn(0.5))); either way only the fields given are
set, so a later call merges, and drive().get("throttle") reads one back.
angles() holds the angle helpers, the core's to the last bit, so no robot
needs Math.atan2. Throw new Forfeit(code, message) to forfeit; any other
exception is logged with its trace and the turn answers with what it had set.
A tiny robot
import clunkyard.*;
public final class Bot extends Robot {
@Override protected void onTurn() {
var nearest = sensors().nearest();
if (nearest.isEmpty()) {
drive().set(Drive.throttle(0.75).turn(0.25));
scanner().set(me().heading(), 40);
status().set("SEARCH", scanner().last().arc());
return;
}
Contact target = nearest.get();
double power = gun().powerForFlightTime(target.range(), 1);
var aim = gun().lead(target, power);
if (aim.isEmpty()) gun().aim(target.bearing(), target.elevation());
else gun().aim(aim.get().heading(), aim.get().pitch());
if (gun().canFire(power, 10)) gun().fire(power);
drive().set(Drive.throttle(0.5).turn(angles().clamp(angles().angleDiff(target.bearing(), me().heading()))));
scanner().set(target.bearing(), 10);
status().set("TRACK", target.range());
}
public static void main(String[] args) {
Clunkyard.run(new Bot());
}
}
Names
Every entry of the robot API 2.0.0 in Java. names.md has every language side by side.
| Canonical | Form | Java |
|---|---|---|
match.mode |
property | match().mode() |
match.ruleset |
property | match().ruleset() |
match.control |
property | match().control() |
match.robots |
property | match().robots() |
match.is_3d |
property | match().is3d() |
match.tick_rate |
property | match().tickRate() |
match.max_ticks |
property | match().maxTicks() |
match.robot_id |
call | match().robotId(slot) |
clock.tick |
property | clock().tick() |
clock.seconds |
property | clock().seconds() |
clock.remaining_ticks |
property | clock().remainingTicks() |
arena.size |
property | arena().size() |
arena.gravity |
property | arena().gravity() |
arena.terrain_kind |
property | arena().terrainKind() |
arena.ground_height |
call | arena().groundHeight(x, y) |
me.health |
property | me().health() |
me.position |
property | me().position() |
me.velocity |
property | me().velocity() |
me.heading |
property | me().heading() |
me.pitch |
property | me().pitch() |
me.roll |
property | me().roll() |
me.angular_velocity |
property | me().angularVelocity() |
me.attitude |
property | me().attitude() |
me.grounded |
property | me().grounded() |
me.altitude |
property | me().altitude() |
me.applied |
property | me().applied() |
battery.charge |
property | battery().charge() |
battery.capacity |
property | battery().capacity() |
battery.regen |
property | battery().regen() |
battery.sustainable_drive |
property | battery().sustainableDrive() |
battery.compute |
property | battery().compute() |
battery.drive_cost |
call | battery().driveCost(fraction) |
drive.hover_lift |
property | drive().hoverLift() |
drive.set |
control | drive().set(throttle, turn, pitchTurn), drive().set(Drive.pitchTurn(x)) |
drive.forces |
control | drive().forces(thrust, strafe, lift, yawTorque, pitchTorque, rollTorque, brake), drive().forces(Drive.brake(x)) |
drive.get |
call | drive().get("throttle") |
gun.aim_now |
property | gun().aimNow() |
gun.cooldown_ticks |
property | gun().cooldownTicks() |
gun.spread |
property | gun().spread() |
gun.max_power |
property | gun().maxPower() |
gun.damage_scale |
property | gun().damageScale() |
gun.can_fire |
call | gun().canFire(power, reserve) |
gun.shot_speed |
call | gun().shotSpeed(power) |
gun.shot_cost |
call | gun().shotCost(power) |
gun.reload_ticks |
call | gun().reloadTicks(power) |
gun.shot_damage |
call | gun().shotDamage(power) |
gun.power_for_speed |
call | gun().powerForSpeed(speed) |
gun.power_for_flight_time |
call | gun().powerForFlightTime(range, seconds) |
gun.lead |
call | gun().lead(contact, power) |
gun.lead_point |
call | gun().leadPoint(position, velocity, power) |
gun.aim |
control | gun().aim(heading, pitch), gun().aim(Gun.pitch(x)) |
gun.fire |
control | gun().fire(power) |
gun.get |
call | gun().get("heading") |
scanner.last |
property | scanner().last() |
scanner.proximity_range |
property | scanner().proximityRange() |
scanner.reach |
call | scanner().reach(arc) |
scanner.arc_for_reach |
call | scanner().arcForReach(range) |
scanner.set |
control | scanner().set(heading, arc, pitch), scanner().set(Scanner.pitch(x)) |
scanner.get |
call | scanner().get("heading") |
sensors.contacts |
property | sensors().contacts() |
sensors.nearest |
property | sensors().nearest() |
sensors.cues |
property | sensors().cues() |
sensors.contact |
call | sensors().contact(slot) |
sensors.position_of |
call | sensors().positionOf(contact) |
tracker.cue |
property | tracker().cue() |
tracker.nearest_bearing_rate |
property | tracker().nearestBearingRate() |
tracker.velocity |
call | tracker().velocity(slot) |
tracker.position |
call | tracker().position(slot) |
tracker.last_seen |
call | tracker().lastSeen(slot) |
tracker.configure |
call | tracker().configure(smoothing, forgetTicks, cueTicks) |
nav.zone |
property | nav().zone() |
nav.zone.margin |
call | nav().zone().margin(point) |
nav.zone.contains |
call | nav().zone().contains(point, margin) |
nav.zone.distance_from |
call | nav().zone().distanceFrom(point) |
nav.storm |
property | nav().storm() |
nav.storm.margin |
call | nav().storm().margin(point) |
nav.storm.contains |
call | nav().storm().contains(point, margin) |
nav.storm.distance_from |
call | nav().storm().distanceFrom(point) |
nav.hill |
property | nav().hill() |
nav.hill.margin |
call | nav().hill().margin(point) |
nav.hill.contains |
call | nav().hill().contains(point, margin) |
nav.hill.distance_from |
call | nav().hill().distanceFrom(point) |
nav.pickups |
property | nav().pickups() |
nav.nearest_pickup |
call | nav().nearestPickup(kind) |
nav.field_distance |
call | nav().fieldDistance(a, b) |
score.me |
property | score().me() |
score.best |
property | score().best() |
score.armour |
property | score().armour() |
angles.normalize |
call | angles().normalize(degrees) |
angles.angle_diff |
call | angles().angleDiff(target, current) |
angles.bearing_to |
call | angles().bearingTo(from, to) |
angles.elevation_to |
call | angles().elevationTo(from, to) |
angles.direction |
call | angles().direction(heading, pitch) |
angles.distance |
call | angles().distance(a, b) |
angles.clamp |
call | angles().clamp(value, low, high) |
status.set |
control | status().set(text, value), status().set(Status.value(x)) |
status.get |
call | status().get("text") |
raw.number |
call | raw().number(path) |
raw.text |
call | raw().text(path) |
raw.has |
call | raw().has(path) |
raw.flag |
call | raw().flag(path) |
raw.count |
call | raw().count(path) |
raw.line |
call | raw().line() |
raw.extra |
call | raw().extra(json) |
session.next |
call | session().next() |
session.send |
call | session().send() |
session.forfeit |
call | session().forfeit(code, message) |
session.log |
call | session().log(line) |