The Forth adapter
One persistent Gforth process runs the tactic. The installed Python binding
owns the robot core session; generated cy-* words synchronously forward
calls over the existing pipe. Protocol, geometry, lead and tracking remain
in the core. Install with make install SDK=/opt/clunkyard/sdk after the
Python binding. Run with
PYTHONPATH=/opt/clunkyard/sdk/bindings/forth:/opt/clunkyard/sdk/bindings/python python3 bot.py.
Canonical words follow the API path in kebab case: cy-me-heading,
cy-gun-shot-speed, cy-nav-zone-margin. Arguments follow the API's order,
with numbers on the floating point stack and integers, booleans and enum
codes on the data stack. Text occupies an address and length. Records flatten
in declared field order, with nested records inline. Canonical enum codes
use the API's values, starting at 1. Every word returns a status on the data
stack: 0 for success, 1 for no value, or a negative core error. cy-result
throws errors and converts status to a presence flag. A list pushes its
records then its count. Query strings live until the next query.
Controls have one generated word per field,
cy-drive-set-throttle or cy-status-set-text; each returns status.
Getters take a field string: s" throttle" cy-drive-get. Familiar words
such as lead, bearing-to, nearest, zone-margin, power-for-flight-time
and local control builders (drive!, scan!, status!) remain available.
Their game helpers forward core queries. Compatibility enum constants start
at zero. seconds, remaining-ticks and shot-damage read the current tick.
Hello values and Python field tables are generated from
protocol/v2/schema.json, canonical words and control tables from
protocol/v2/api.json. Floating point query traffic carries IEEE bytes and
text carries UTF-8 bytes, preserving core results without decimal rounding.
on-start is optional; on-turn leaves both stacks as it found them. A
thrown turn logs its error and preserves controls already set through core
calls. Forfeits and session faults use the Python binding's behaviour.
A tiny robot
Save this tactic as tiny.fs:
: on-turn
cy-sensors-nearest cy-result 0= if
0.75e cy-drive-set-throttle drop
0.25e cy-drive-set-turn drop
cy-me-heading cy-result drop cy-scanner-set-heading drop
40e cy-scanner-set-arc drop
s" SEARCH" cy-status-set-text drop
cy-scanner-last cy-result drop { f: h f: p f: arc f: reach }
arc cy-status-set-value drop exit
then
{ slot source f: range f: bearing f: elevation f: be f: re f: x f: y f: z }
range 1e cy-gun-power-for-flight-time cy-result drop { f: power }
slot source range bearing elevation be re x y z power cy-gun-lead cy-result if
{ f: h f: p f: t }
h cy-gun-aim-heading drop p cy-gun-aim-pitch drop
else
bearing cy-gun-aim-heading drop elevation cy-gun-aim-pitch drop
then
power 10e cy-gun-can-fire cy-result drop if power cy-gun-fire-power drop then
0.5e cy-drive-set-throttle drop
bearing cy-me-heading cy-result drop cy-angles-angle-diff cy-result drop
-1e 1e cy-angles-clamp cy-result drop cy-drive-set-turn drop
bearing cy-scanner-set-heading drop 10e cy-scanner-set-arc drop
s" TRACK" cy-status-set-text drop range cy-status-set-value drop ;
Save the launcher as bot.py:
import clunkyard_forth
clunkyard_forth.run("tiny.fs")
run and play take a tactic filename. make test exercises the actual
Gforth words against every API vector.
Complete names and record layouts.
Names
Every entry of the robot API 2.0.0 in Forth. names.md has every language side by side.
| Canonical | Form | Forth |
|---|---|---|
match.mode |
property | cy-match-mode |
match.ruleset |
property | cy-match-ruleset |
match.control |
property | cy-match-control |
match.robots |
property | cy-match-robots |
match.is_3d |
property | cy-match-is-3d |
match.tick_rate |
property | cy-match-tick-rate |
match.max_ticks |
property | cy-match-max-ticks |
match.robot_id |
call | cy-match-robot-id |
clock.tick |
property | cy-clock-tick |
clock.seconds |
property | cy-clock-seconds |
clock.remaining_ticks |
property | cy-clock-remaining-ticks |
arena.size |
property | cy-arena-size |
arena.gravity |
property | cy-arena-gravity |
arena.terrain_kind |
property | cy-arena-terrain-kind |
arena.ground_height |
call | cy-arena-ground-height |
me.health |
property | cy-me-health |
me.position |
property | cy-me-position |
me.velocity |
property | cy-me-velocity |
me.heading |
property | cy-me-heading |
me.pitch |
property | cy-me-pitch |
me.roll |
property | cy-me-roll |
me.angular_velocity |
property | cy-me-angular-velocity |
me.attitude |
property | cy-me-attitude |
me.grounded |
property | cy-me-grounded |
me.altitude |
property | cy-me-altitude |
me.applied |
property | cy-me-applied |
battery.charge |
property | cy-battery-charge |
battery.capacity |
property | cy-battery-capacity |
battery.regen |
property | cy-battery-regen |
battery.sustainable_drive |
property | cy-battery-sustainable-drive |
battery.compute |
property | cy-battery-compute |
battery.drive_cost |
call | cy-battery-drive-cost |
drive.hover_lift |
property | cy-drive-hover-lift |
drive.set |
control | cy-drive-set-throttle |
drive.forces |
control | cy-drive-forces-thrust |
drive.get |
call | cy-drive-get |
gun.aim_now |
property | cy-gun-aim-now |
gun.cooldown_ticks |
property | cy-gun-cooldown-ticks |
gun.spread |
property | cy-gun-spread |
gun.max_power |
property | cy-gun-max-power |
gun.damage_scale |
property | cy-gun-damage-scale |
gun.can_fire |
call | cy-gun-can-fire |
gun.shot_speed |
call | cy-gun-shot-speed |
gun.shot_cost |
call | cy-gun-shot-cost |
gun.reload_ticks |
call | cy-gun-reload-ticks |
gun.shot_damage |
call | cy-gun-shot-damage |
gun.power_for_speed |
call | cy-gun-power-for-speed |
gun.power_for_flight_time |
call | cy-gun-power-for-flight-time |
gun.lead |
call | cy-gun-lead |
gun.lead_point |
call | cy-gun-lead-point |
gun.aim |
control | cy-gun-aim-heading |
gun.fire |
control | cy-gun-fire |
gun.get |
call | cy-gun-get |
scanner.last |
property | cy-scanner-last |
scanner.proximity_range |
property | cy-scanner-proximity-range |
scanner.reach |
call | cy-scanner-reach |
scanner.arc_for_reach |
call | cy-scanner-arc-for-reach |
scanner.set |
control | cy-scanner-set-heading |
scanner.get |
call | cy-scanner-get |
sensors.contacts |
property | cy-sensors-contacts |
sensors.nearest |
property | cy-sensors-nearest |
sensors.cues |
property | cy-sensors-cues |
sensors.contact |
call | cy-sensors-contact |
sensors.position_of |
call | cy-sensors-position-of |
tracker.cue |
property | cy-tracker-cue |
tracker.nearest_bearing_rate |
property | cy-tracker-nearest-bearing-rate |
tracker.velocity |
call | cy-tracker-velocity |
tracker.position |
call | cy-tracker-position |
tracker.last_seen |
call | cy-tracker-last-seen |
tracker.configure |
call | cy-tracker-configure |
nav.zone |
property | cy-nav-zone |
nav.zone.margin |
call | cy-nav-zone-margin |
nav.zone.contains |
call | cy-nav-zone-contains |
nav.zone.distance_from |
call | cy-nav-zone-distance-from |
nav.storm |
property | cy-nav-storm |
nav.storm.margin |
call | cy-nav-storm-margin |
nav.storm.contains |
call | cy-nav-storm-contains |
nav.storm.distance_from |
call | cy-nav-storm-distance-from |
nav.hill |
property | cy-nav-hill |
nav.hill.margin |
call | cy-nav-hill-margin |
nav.hill.contains |
call | cy-nav-hill-contains |
nav.hill.distance_from |
call | cy-nav-hill-distance-from |
nav.pickups |
property | cy-nav-pickups |
nav.nearest_pickup |
call | cy-nav-nearest-pickup |
nav.field_distance |
call | cy-nav-field-distance |
score.me |
property | cy-score-me |
score.best |
property | cy-score-best |
score.armour |
property | cy-score-armour |
angles.normalize |
call | cy-angles-normalize |
angles.angle_diff |
call | cy-angles-angle-diff |
angles.bearing_to |
call | cy-angles-bearing-to |
angles.elevation_to |
call | cy-angles-elevation-to |
angles.direction |
call | cy-angles-direction |
angles.distance |
call | cy-angles-distance |
angles.clamp |
call | cy-angles-clamp |
status.set |
control | cy-status-set-text |
status.get |
call | cy-status-get |
raw.number |
call | cy-raw-number |
raw.text |
call | cy-raw-text |
raw.has |
call | cy-raw-has |
raw.flag |
call | cy-raw-flag |
raw.count |
call | cy-raw-count |
raw.line |
call | cy-raw-line |
raw.extra |
call | cy-raw-extra |
session.event |
property | cy-session-event |
session.next |
call | cy-session-next |
session.send |
call | cy-session-send |
session.forfeit |
call | cy-session-forfeit |
session.log |
call | cy-session-log |
session.feed |
call | cy-session-feed |
session.reply |
call | cy-session-reply |