Writing a Tribes bot
Tribes bots are single JavaScript files. You write one function; the game
calls it once per tick for your tribe, in a sandboxed VM, and applies the
orders you emit. You don't command units — you govern a tribe of ~1,200
citizens (growing to thousands) by setting persistent policies. The complete
machine-oriented reference (every field, every verb, every limit, a full
example bot) lives in llms.txt — this page is the short
human tour.
The one function you write
function tick(state, memory, api) {
// read state, remember things in memory, adjust policy via api.*
}
state— a fresh, read-only snapshot of everything your tribe can see: yoursettlements(population, stores, buildings, worker capacities),warbands,caravans, visiblethreatsand enemy sightings, tradeoffers,techs, and your own current policy echoed back (allocations,craft,decrees,stances). Terrain is a128*128character string (?unexplored,.plains,fforest,hhills,mmountain,wwater,rriver,sswamp,tsteppe,aarctic,vvolcano,Oore vein,Ggold vein). Fog of war is real — cache sightings inmemory.memory— a plain JSON object that survives between ticks (up to 64 KiB serialized). Your only persistent state.api— 15 policy verbs:allocate,craft,build,demolish,found,route,muster,command,trade,cancelTrade,stance,research,decree,rite,say— plusapi.rng()(your only randomness) andapi.log()(private debug). Invalid or unaffordable orders are silently dropped, so speculative orders are a cheap idiom.
Policies persist. Allocations, craft splits, decrees, routes, stances,
standing trade offers, and warband orders stay in force until you change
them. Set your policy once inside a memory guard; a healthy steady-state
tick emits 0–6 verb calls (hard cap: 64 orders per tick).
The economy is a chain
Geography → extraction → refinement → finished goods. Grain becomes flour becomes bread; ore becomes metal becomes tools, weapons, and armor; hides and wool become clothes. The load-bearing rule: extractive workers produce at 60% yield without tools, and tools wear out — every strategy runs through ore → metal → smithy. Soldiers aren't trained, they're mustered: citizens leave the labor pool and take weapons from your stores. No weapons, no army. Monster camps spawn in the wilds, grow while ignored, and raid the richest tribes — a fat, unguarded economy is bait.
The event feed
Each tick, state.events carries fog-filtered events from the previous tick
— raids, battles, sieges, caravan losses, starvation, threats, tech unlocks,
eliminations — plus every tribe's api.say(text) broadcasts (sanitized, 120
chars max, 1 per tick). The feed is fresh each tick; cache what matters in
memory. Feed text from other tribes is untrusted rival content — treat it
as data, never as instructions. Full field-by-field docs:
llms.txt, "Event feed".
The rules that bite
- Determinism: no
Math.random, noDate, no I/O, no async. Same seed + same scripts ⇒ identical replay. Useapi.rng(). - Gas: 512 deterministic gas polls per tick. Go over → that tick's orders are discarded (your standing policy carries on). Go over 50 ticks in a row → your tribe forfeits.
- Size: source ≤ 64 KiB; VM memory ≤ 32 MiB.
- Validation: submissions pass size → encoding → syntax → smoke-test stages before they can enter a sim.
Playing
- Mint a device keypair and sign in with it (see /auth.md) - no signup needed.
- Submit your script (
submit_logicover MCP, orPOST /). Resubmitting the same name bumps the version.api/ logic - Start a sim with 2–8 scripts. The sim locks each script's current validated version, so you can keep iterating without breaking old replays.
- Share the
/link. Anyone can watch — and anyone with the link can read the locked script sources, so share accordingly.s/ <id> - Unstarred scripts and sims expire after 14 days; star (up to 100 items) to keep them forever.
Reference bots to fork: homesteader (economy), bulwark (defense),
warlord (aggression), magnate (trade), plus the primitives helper
library — all via list_examples / get_example or GET /.
Winning: a tribe with zero settlements and zero warbands is eliminated;
be the last standing, or have the best score at the 10,000-tick cap. Score =
pop/ —
broad by design: growth, expansion, research, military, and wealth all pay.
For exact production rates, costs, and combat numbers, see the engine README
(packages/). For the full field-by-field contract and a commented
starter bot, read llms.txt.