The Swift binding
Clunkyard's Swift API calls the shared core through its generated C ABI.
The generator emits subsystem methods, records and conformance bridges
from protocol/v2/api.json. The run loop and exception mapping are written
by hand. Protocol parsing, tracking, physics and act serialization stay in
the core.
Install with make install SDK=/opt/clunkyard/sdk. Build a robot with:
swiftc -O -parse-as-library -I/opt/clunkyard/sdk/bindings/swift bot.swift \
-L/opt/clunkyard/sdk/bindings/swift -lClunkyardSwift \
-L/opt/clunkyard/sdk/lib -Xlinker -l:libclunkyard.a -lm -ldl -lpthread -o bot
Properties and methods throw CoreError, which carries the core status.
Optional results are nil. Lists and text are owned Swift values. Records
use C layouts; snake-case fields also have camelCase accessors. Enum values
are Int32 constants, allowing unknown values to reach the core for validation.
Controls take named optional fields and merge within the turn. Getter
methods such as drive.getThrottle() read pending controls. Throw
Forfeit(code,message) to forfeit; other callback errors are logged with a
stack trace before sending the controls already set. play(lines) uses an
in-memory core session.
A tiny robot
import Clunkyard
@main final class Bot:Robot {
override func onTurn() throws {
guard let target=try sensors.nearest else {
try drive.set(throttle:0.75,turn:0.25)
try scanner.set(heading:me.heading,arc:40)
try status.set(text:"SEARCH",value:scanner.last.arc)
return
}
let power=try gun.powerForFlightTime(target.range,1),aim=try gun.lead(target,power)
try gun.aim(heading:aim?.heading ?? target.bearing,pitch:aim?.pitch ?? target.elevation)
if try gun.canFire(power,10) {try gun.fire(power:power)}
try drive.set(throttle:0.5,turn:angles.clamp(angles.angleDiff(target.bearing,me.heading),-1,1))
try scanner.set(heading:target.bearing,arc:10)
try status.set(text:"TRACK",value:target.range)
}
static func main() throws {try Bot().run()}
}
make test SDK=... compares the Swift wrappers with every API vector,
including exact floating-point bits and act lines.
Names
Every entry of the robot API 2.0.0 in Swift. names.md has every language side by side.
| Canonical | Form | Swift |
|---|---|---|
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() |
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() |
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() |
drive.hover_lift |
property | drive.hoverLift |
drive.set |
control | drive.set() |
drive.forces |
control | drive.forces() |
drive.get |
call | drive.get() |
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() |
gun.shot_speed |
call | gun.shotSpeed() |
gun.shot_cost |
call | gun.shotCost() |
gun.reload_ticks |
call | gun.reloadTicks() |
gun.shot_damage |
call | gun.shotDamage() |
gun.power_for_speed |
call | gun.powerForSpeed() |
gun.power_for_flight_time |
call | gun.powerForFlightTime() |
gun.lead |
call | gun.lead() |
gun.lead_point |
call | gun.leadPoint() |
gun.aim |
control | gun.aim() |
gun.fire |
control | gun.fire() |
gun.get |
call | gun.get() |
scanner.last |
property | scanner.last |
scanner.proximity_range |
property | scanner.proximityRange |
scanner.reach |
call | scanner.reach() |
scanner.arc_for_reach |
call | scanner.arcForReach() |
scanner.set |
control | scanner.set() |
scanner.get |
call | scanner.get() |
sensors.contacts |
property | sensors.contacts |
sensors.nearest |
property | sensors.nearest |
sensors.cues |
property | sensors.cues |
sensors.contact |
call | sensors.contact() |
sensors.position_of |
call | sensors.positionOf() |
tracker.cue |
property | tracker.cue |
tracker.nearest_bearing_rate |
property | tracker.nearestBearingRate |
tracker.velocity |
call | tracker.velocity() |
tracker.position |
call | tracker.position() |
tracker.last_seen |
call | tracker.lastSeen() |
tracker.configure |
call | tracker.configure() |
nav.zone |
property | nav.zone |
nav.zone.margin |
call | nav.zoneMargin() |
nav.zone.contains |
call | nav.zoneContains() |
nav.zone.distance_from |
call | nav.zoneDistanceFrom() |
nav.storm |
property | nav.storm |
nav.storm.margin |
call | nav.stormMargin() |
nav.storm.contains |
call | nav.stormContains() |
nav.storm.distance_from |
call | nav.stormDistanceFrom() |
nav.hill |
property | nav.hill |
nav.hill.margin |
call | nav.hillMargin() |
nav.hill.contains |
call | nav.hillContains() |
nav.hill.distance_from |
call | nav.hillDistanceFrom() |
nav.pickups |
property | nav.pickups |
nav.nearest_pickup |
call | nav.nearestPickup() |
nav.field_distance |
call | nav.fieldDistance() |
score.me |
property | score.me |
score.best |
property | score.best |
score.armour |
property | score.armour |
angles.normalize |
call | angles.normalize() |
angles.angle_diff |
call | angles.angleDiff() |
angles.bearing_to |
call | angles.bearingTo() |
angles.elevation_to |
call | angles.elevationTo() |
angles.direction |
call | angles.direction() |
angles.distance |
call | angles.distance() |
angles.clamp |
call | angles.clamp() |
status.set |
control | status.set() |
status.get |
call | status.get() |
raw.number |
call | raw.number() |
raw.text |
call | raw.text() |
raw.has |
call | raw.has() |
raw.flag |
call | raw.flag() |
raw.count |
call | raw.count() |
raw.line |
call | raw.line() |
raw.extra |
call | raw.extra() |
session.event |
property | session.event |
session.next |
call | session.next() |
session.send |
call | session.send() |
session.forfeit |
call | session.forfeit() |
session.log |
call | session.log() |
session.feed |
call | session.feed() |
session.reply |
call | session.reply() |