553 commands · checked live by the real engine

Write a bot as a text file.

No Java, no compiler, no programming to read first. You write what you want it to do, the engine reads it, and if anything is wrong it tells you the line and refuses to start. Either the script is right and it runs, or it is wrong and you get a list of what to fix — nothing ever fails halfway through a bank trip.

Playground

Type a script. It's lexed, parsed and checked by the exact engine the loader runs — as you type.
Load an example:
Ctrl/⌘ + Enter

        
      

Nothing here runs — there is no game on a web server. Everything short of running it (does it parse, does it type-check, what will it be told to fix) is real.

The shape of a file

A header, some settings and variables, then the events. on loop runs, ends, and runs again — it never loops by itself; return 1000 means "wait a second, then run me again". The language guide covers every construct.

script "My First Bot"
author "you"
every 600            # one game tick

var picked = 0

on start { print("off we go") }

on loop {
    print("this runs over and over")
    return 1000      # come back in one second
}

on stop { print("picked", picked) }

Where to go next

  • The language — events, states, settings, variables, your own funs, and waiting. The parts that are not commands.
  • Drawing & painton render and the paint commands, to draw a live HUD over the game.
  • Bags & JSON — records, tables you can filter and sum, saving across runs, and reading JSON.
  • Write with Claude — install our Claude skill and describe the bot you want; it writes checked scripts for you.
  • The command reference in the sidebar — one page per group, each command with its signature, parameters and an example.
  • The search box finds any command from any page and jumps straight to it.

The five mistakes everybody makes

1 · Using something that might not be there

Every "find" command can return none. Test it once — if rock == none { return 1000 } — and the engine trusts it for the rest of the block.

2 · A capital letter in a command name

invIsfull and invIsFull are different names, and only one exists. The error usually suggests the right one.

3 · Using a name you never made

Nothing is created just by writing it. var trips = 0 at the top to keep it between passes, let inside a block for one pass.

4 · Gluing text and numbers with +

+ joins two strings or adds two ints, not a mix. Write print("trip", trips) — it spaces them for you.

5 · Waiting with no time limit

An untimed wait until is the one loop that can never finish. Always give a timeout, and an else for when it runs out.

A handle is a photograph, not a window

goblin.tile is where it was. Find things again inside the loop that uses them — the engine refuses a stale handle.