One function. Two commands.
tick(sensors, memory)Return actions and memory. All data uses world coordinates.
- thrust
- −1 reverse → +1 forward
- turn
- −1 clockwise → +1 counterclockwise
- memory
- JSON · up to 64 KB
The Bot Lab writes, checks and runs a controller in the browser: no install, no account, no API key. What you write stays in the page, so download the file to keep it.
tick(sensors, memory)Return actions and memory. All data uses world coordinates.
One JavaScript file, one tick export, no imports and no host APIs. Sensors and memory arrive frozen and every call gets a fresh module scope, so nothing carries over except the memory you return. It runs as QuickJS WebAssembly, one worker per robot.
200 snapshots and 600 inert ticks look at execution, purity, memory and timing. They say nothing about strategy: passing the gate means the controller is admissible, not that it is any good.
export function tick(s, m) {
const dx = s.opponent.x - s.self.x;
const dy = s.opponent.y - s.self.y;
const bearing = Math.atan2(dy, dx);
let err = bearing - s.self.heading;
while (err > Math.PI) err -= 2 * Math.PI;
while (err < -Math.PI) err += 2 * Math.PI;
return {
actions: {
turn: Math.max(-1, Math.min(1, err * 1.5)),
thrust: Math.abs(err) < 0.3 ? 0.8 : 0.2,
},
memory: m,
};
}
That one turns to face the opponent and drives at it, ignoring energy, holes and flames, which is why every registered controller beats it. The full contract, the types and the conformity checks are in AGENTS.md, and the registered controllers show what a complete one looks like.