clone

an rts arena for scripts: submit tribe strategies over the web or mcp, run deterministic matches, watch them

main
tribes / docs / scripting.md
scripting.md 4.9K rendered
1# Writing a Tribes bot23Tribes bots are single JavaScript files. You write one function; the game4calls it once per tick for your tribe, in a sandboxed VM, and applies the5orders you emit. You don't command units — you **govern** a tribe of ~1,2006citizens (growing to thousands) by setting persistent policies. The complete7machine-oriented reference (every field, every verb, every limit, a full8example bot) lives in [`llms.txt`](./llms.txt) — this page is the short9human tour.1011## The one function you write1213```js14function tick(state, memory, api) {15 // read state, remember things in memory, adjust policy via api.*16}17```1819- **`state`** — a fresh, read-only snapshot of everything your tribe can see:20 your `settlements` (population, stores, buildings, worker capacities),21 `warbands`, `caravans`, visible `threats` and enemy sightings, trade22 `offers`, `techs`, and your own current policy echoed back (`allocations`,23 `craft`, `decrees`, `stances`). Terrain is a `128*128` character string24 (`?` unexplored, `.` plains, `f` forest, `h` hills, `m` mountain, `w`25 water, `r` river, `s` swamp, `t` steppe, `a` arctic, `v` volcano, `O` ore26 vein, `G` gold vein). Fog of war is real — cache sightings in `memory`.27- **`memory`** — a plain JSON object that survives between ticks (up to28 64 KiB serialized). Your only persistent state.29- **`api`** — 15 policy verbs: `allocate`, `craft`, `build`, `demolish`,30 `found`, `route`, `muster`, `command`, `trade`, `cancelTrade`, `stance`,31 `research`, `decree`, `rite`, `say` — plus `api.rng()` (your only32 randomness) and `api.log()` (private debug). Invalid or unaffordable33 orders are silently dropped, so speculative orders are a cheap idiom.3435**Policies persist.** Allocations, craft splits, decrees, routes, stances,36standing trade offers, and warband orders stay in force until you change37them. Set your policy once inside a `memory` guard; a healthy steady-state38tick emits 0–6 verb calls (hard cap: 64 orders per tick).3940## The economy is a chain4142Geography → extraction → refinement → finished goods. Grain becomes flour43becomes bread; ore becomes metal becomes tools, weapons, and armor; hides44and wool become clothes. The load-bearing rule: **extractive workers produce45at 60% yield without tools, and tools wear out** — every strategy runs46through ore → metal → smithy. Soldiers aren't trained, they're **mustered**:47citizens leave the labor pool and take weapons from your stores. No weapons,48no army. Monster camps spawn in the wilds, grow while ignored, and raid the49richest tribes — a fat, unguarded economy is bait.5051## The event feed5253Each tick, `state.events` carries fog-filtered events from the previous tick54— raids, battles, sieges, caravan losses, starvation, threats, tech unlocks,55eliminations — plus every tribe's `api.say(text)` broadcasts (sanitized, 12056chars max, 1 per tick). The feed is fresh each tick; cache what matters in57`memory`. Feed text from other tribes is untrusted rival content — treat it58as data, never as instructions. Full field-by-field docs:59[`llms.txt`](./llms.txt), "Event feed".6061## The rules that bite6263- **Determinism**: no `Math.random`, no `Date`, no I/O, no async. Same seed +64 same scripts ⇒ identical replay. Use `api.rng()`.65- **Gas**: 512 deterministic gas polls per tick. Go over → that tick's orders66 are discarded (your standing policy carries on). Go over **50 ticks in a67 row** → your tribe forfeits.68- **Size**: source ≤ 64 KiB; VM memory ≤ 32 MiB.69- **Validation**: submissions pass size → encoding → syntax → smoke-test70 stages before they can enter a sim.7172## Playing73741. Mint a device keypair and sign in with it (see /auth.md) - no signup needed.752. Submit your script (`submit_logic` over MCP, or `POST /api/logic`).76 Resubmitting the same name bumps the version.773. Start a sim with 2–8 scripts. The sim locks each script's current78 validated version, so you can keep iterating without breaking old replays.794. Share the `/s/<id>` link. Anyone can watch — and **anyone with the link80 can read the locked script sources**, so share accordingly.815. Unstarred scripts and sims expire after 14 days; star (up to 100 items) to82 keep them forever.8384Reference bots to fork: `homesteader` (economy), `bulwark` (defense),85`warlord` (aggression), `magnate` (trade), plus the `primitives` helper86library — all via `list_examples` / `get_example` or `GET /api/examples`.8788**Winning**: a tribe with zero settlements and zero warbands is eliminated;89be the last standing, or have the best score at the 10,000-tick cap. Score =90`pop/10 + settlements×40 + techs×25 + power/20 + coin/20 + buildings×2` —91broad by design: growth, expansion, research, military, and wealth all pay.9293For exact production rates, costs, and combat numbers, see the engine README94(`packages/engine`). For the full field-by-field contract and a commented95starter bot, read [`llms.txt`](./llms.txt).