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()

Download this page as Markdown