The Hew binding
import hew.clunkyard; exposes typed records, subsystem methods, Option
for absent values and Vec for lists. Methods use fails CoreError and ?.
Controls take optional fields: robot.drive.set(throttle: .Some(0.5))?
changes the throttle while retaining any turn already set this tick.
match_info names the match subsystem because match is a Hew keyword.
Install with make install SDK=/opt/clunkyard/sdk. Build a robot with
hew build --release --pkg-path /opt/clunkyard/sdk/bindings/hew/packages --link-lib /opt/clunkyard/sdk/bindings/hew/libclunkyard_hew.a --link-lib /opt/clunkyard/sdk/lib/libclunkyard.a bot.hew -o bot.
The executable links both the core and Hew runtime statically. The generated
C shim copies native fields through Hew's scalar and bytes FFI; parsing,
tracking, geometry and control decisions stay in the core.
Implement Strategy.on_turn(var self, robot) and optionally on_start.
clunkyard.run(strategy) owns the protocol loop; clunkyard.play(strategy, lines) returns replies from a memory session. Returned strategy errors are
logged and controls already set are sent. Return error clunkyard.forfeit( code, message) for an explicit forfeit. A core fault sends the empty reply
and resumes on the next state. Hew panics terminate the process; use returned
errors for recoverable strategy failures. Keep the robot handle within its
session and let run or play close it.
A tiny robot
import hew.clunkyard;
import hew.clunkyard.{Robot, Strategy, CoreError, Direction};
type Tiny {}
impl Strategy for Tiny {
fn on_turn(var self, robot: Robot) fails CoreError {
let target = match robot.sensors.nearest()? {
.Some(target) => target,
.None => {
robot.drive.set(.Some(0.75), .Some(0.25))?;
robot.scanner.set(.Some(robot.me.heading()?), .Some(40.0))?;
robot.status.set(.Some("SEARCH"), .Some((robot.scanner.last()?).arc))?;
return;
}
};
let power = robot.gun.power_for_flight_time(target.range, 1.0)?;
let aim = match robot.gun.lead(target, power)? {
.Some(aim) => Direction { heading: aim.heading, pitch: aim.pitch },
.None => Direction { heading: target.bearing, pitch: target.elevation },
};
robot.gun.aim(.Some(aim.heading), .Some(aim.pitch))?;
if robot.gun.can_fire(power, 10.0)? { robot.gun.fire(.Some(power))?; }
robot.drive.set(.Some(0.5), .Some(robot.angles.clamp(robot.angles.angle_diff(target.bearing, robot.me.heading()?)?)?))?;
robot.scanner.set(.Some(target.bearing), .Some(10.0))?;
robot.status.set(.Some("TRACK"), .Some(target.range))?;
}
}
fn main() { let _ = clunkyard.run(Tiny {}); }
make test checks every generated Hew method against the core's full vectors,
including typed arguments, records, optional values, lists, text, exact
floating-point results and serialized acts.
Names
Every entry of the robot API 2.0.0 in Hew. names.md has every language side by side.
| Canonical | Form | Hew |
|---|---|---|
match.mode |
property | match_info.mode() |
match.ruleset |
property | match_info.ruleset() |
match.control |
property | match_info.control() |
match.robots |
property | match_info.robots() |
match.is_3d |
property | match_info.is_3d() |
match.tick_rate |
property | match_info.tick_rate() |
match.max_ticks |
property | match_info.max_ticks() |
match.robot_id |
call | match_info.robot_id() |
clock.tick |
property | clock.tick() |
clock.seconds |
property | clock.seconds() |
clock.remaining_ticks |
property | clock.remaining_ticks() |
arena.size |
property | arena.size() |
arena.gravity |
property | arena.gravity() |
arena.terrain_kind |
property | arena.terrain_kind() |
arena.ground_height |
call | arena.ground_height() |
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.angular_velocity() |
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.sustainable_drive() |
battery.compute |
property | battery.compute() |
battery.drive_cost |
call | battery.drive_cost() |
drive.hover_lift |
property | drive.hover_lift() |
drive.set |
control | drive.set() |
drive.forces |
control | drive.forces() |
drive.get |
call | drive.get_ |
gun.aim_now |
property | gun.aim_now() |
gun.cooldown_ticks |
property | gun.cooldown_ticks() |
gun.spread |
property | gun.spread() |
gun.max_power |
property | gun.max_power() |
gun.damage_scale |
property | gun.damage_scale() |
gun.can_fire |
call | gun.can_fire() |
gun.shot_speed |
call | gun.shot_speed() |
gun.shot_cost |
call | gun.shot_cost() |
gun.reload_ticks |
call | gun.reload_ticks() |
gun.shot_damage |
call | gun.shot_damage() |
gun.power_for_speed |
call | gun.power_for_speed() |
gun.power_for_flight_time |
call | gun.power_for_flight_time() |
gun.lead |
call | gun.lead() |
gun.lead_point |
call | gun.lead_point() |
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.proximity_range() |
scanner.reach |
call | scanner.reach() |
scanner.arc_for_reach |
call | scanner.arc_for_reach() |
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.position_of() |
tracker.cue |
property | tracker.cue() |
tracker.nearest_bearing_rate |
property | tracker.nearest_bearing_rate() |
tracker.velocity |
call | tracker.velocity() |
tracker.position |
call | tracker.position() |
tracker.last_seen |
call | tracker.last_seen() |
tracker.configure |
call | tracker.configure() |
nav.zone |
property | nav.zone() |
nav.zone.margin |
call | nav.zone_margin() |
nav.zone.contains |
call | nav.zone_contains() |
nav.zone.distance_from |
call | nav.zone_distance_from() |
nav.storm |
property | nav.storm() |
nav.storm.margin |
call | nav.storm_margin() |
nav.storm.contains |
call | nav.storm_contains() |
nav.storm.distance_from |
call | nav.storm_distance_from() |
nav.hill |
property | nav.hill() |
nav.hill.margin |
call | nav.hill_margin() |
nav.hill.contains |
call | nav.hill_contains() |
nav.hill.distance_from |
call | nav.hill_distance_from() |
nav.pickups |
property | nav.pickups() |
nav.nearest_pickup |
call | nav.nearest_pickup() |
nav.field_distance |
call | nav.field_distance() |
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.angle_diff() |
angles.bearing_to |
call | angles.bearing_to() |
angles.elevation_to |
call | angles.elevation_to() |
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() |