BotGuilds

What this is

One persistent world, ticking forever at a fixed rate. You register a guild, run a bot, and your bot plays: it recruits characters, sends them into the dungeon, fights, loots, trades, and brings the gold home. There are no matches and no rounds — if your bot is offline, your characters simply stand still and rest.

You can absolutely write your bot by hand — the whole interface fits on this page — but the game is built for playing through a coding agent: tell it what you want your guild to do, point it at the starter kit (which ships agent-ready docs), and iterate. Your strategy is the game; the Python is negotiable.

1. Get playing in three steps

a. Register your guild. The token is shown once — copy it.

Already have a guild? Paste your guild_token.json to sign this browser in:

b. Get the starter kit — a working bot plus the client library. Clone it:

git clone /starter.git my-bot

or download starter_kit.zip if you would rather not use git. Same files either way; cloning means git pull picks up updates to the client library. The kit holds two example bots — starter_bot.py (wander and punch) and farmer_bot.py (remembers the map, path-finds, retreats and sells) — plus AGENTS.md, a reference written for your coding agent.

c. Run it:

pip install pyzmq
python starter_bot.py

Your token file carries the server address that works from where you registered — the client speaks ZeroMQ to it. Details in the starter kit's README.

The starter bot works unmodified: it recruits a full party, embarks, wanders and punches whatever it meets. You fork it by rewriting one method, on_frame. Auth, reconnects and logging are already handled by the library. Then open the Player tab and watch your party go.

2. The tick

Every tick (default 0.25 s) the server collects one action per character, resolves them, and sends you one frame per world you have characters in. Order within a tick:

  1. All non-move actions resolve, in descending speed order (speed is rolled per tick from AGI; ties break randomly).
  2. Then all moves resolve, in descending speed order.

Because attacks resolve before moves, you cannot dodge by moving away: an attack hits whoever is on the target tile when it resolves. Two characters can kill each other on the same tick. Moving into a solid or occupied tile fails and still costs stamina.

3. The frame

A frame carries your characters in full, plus everything inside the union of their vision squares (Chebyshev radius, and walls block sight — a tile is visible only if no solid tile stands on the line to it, so corners hide and corridors tunnel your view), plus the events that happened where you could see them. Other guilds' characters show name, look, outfit, position, a health fraction and what they last held in hand — never their stats, statuses or inventory.

{"type": "frame", "tick": 10412, "world": "vale", "bounds": [72, 200],
 "next_refresh": {"band": 2, "in_ticks": 1180},
 "chars": [{"char_uid": "g_ab12_c1", "pos": [14, 87], "hp": 22, "max_hp": 36,
            "stamina": 40, "mana": 10, "stats": {...}, "gifts": ["str", "agi"],
            "spells": [], "spell_cap": 1, "essences": [], "essence_cap": 2,
            "thread": null, "carry": {"used": 7, "cap": 27},
            "craft": null, "xp": 45, "inventory": [...],
            "equipment": {"hand": {...}, "offhand": null, "outfit": "..."}}],
 "visible": {"tiles": [[12, 85, "floor", 210], ...], "entities": [...],
             "items": [...], "gold": [...], "surfaces": [...]},
 "events": [{"kind": "attack", "attacker": 311, "target": 902, "dmg": 5, ...}]}

Every item you can see (inventory, equipment, ground) carries a tier (0–3), a bulk, a list of uses — the verbs it answers to, which is how you find out a book is use-able or a mushroom is brew-able — and a desc that hints at what it is for but never gives numbers.

The village frame has no visible; it carries your guild block (gold, guild inventory, market listings, where your characters are) and the shop stock.

4. Actions

Every target is a tile [x, y] — attacks hit whatever occupies the tile when they resolve, never an entity id.

One per character per tick; a second action for the same character in the same tick replaces the first. Rejected actions come back as action_err with a reason and cost nothing.

actionargswherenotes
movedir: N/S/E/Wmapsingle axis; walking south off row 0 returns you to the village. Diagonal dirs (NE/NW/SE/SW) exist but error no_diagonal_step unless your gear grants them (×1.5 stamina when it does)
ridedir: N/S/E/Wmapstanding on a minecart track only: slide along the rail to its end (up to ride_max_tiles) for a flat cost — fast, cheap, and no stopping early; whatever blocks the rail gets rammed
attacktarget [x,y]mapyour equipped weapon decides: a melee swing (or punch) in reach, or — for bows and magic implements — a shot down a straight rank, file, or true diagonal that stops at the first wall; implements also cost mana
chargetarget [x,y]mapweapons with a run-up attack only: rush an open straight line (target at least 2 away) and land a multiplied blow that shoves the victim
castspell [, essence, target, focus]mapweave a learned form (veil / step / bolt / field / ring — from tomes) with an essence; aether is always in reach (and is what you weave if you name no essence), other essences need attunement or a consumed focus ingredient (item_id). Costs mana and stamina
throwitem_id, targetmapthrowable items only; the item stays where it lands, unless it bursts
useitem_id [, target]anywhereconsumables; using a tome reads it; a few items target a tile — some blast it, some put you on it
pickup / drop[item_id] / item_idanywhereyour own tile (everything, or just item_id), up to your carry cap; in the village these move items out of and into the infinite guild inventory
equipslot [, item_id]anywhereslots: hand, offhand, outfit, trinket, boots; some gear has stat requirements. A bare slot takes the item off (into your pack, bulk permitting)
opentargetmapadjacent containers, crops and herb plants; some containers need several consecutive opens
spend_xpstatanywhere+1 to a stat: costs 8 × v × 2^(v//10) where v is the stat's current value, half for your two gifted stats; stats cap at 24
saytextmapvisible flavor, 40 characters
tasteitem_idanywheretaste a component to learn what it brews (destructive)
brewitem_idsanywhereone command starts the whole brew and occupies the character for some ticks (see crafting below)
smelt / forgeitem_ids / product, item_idsanywhereone command each, likewise timed (see crafting below)
buy / sellkind / item_idvillageshop
list / unlist / buy_listingitem_id, price / listing_idvillageplayer market
recruit[name]villagefree level-0 character, up to roster_cap
renamenamevillagerename a character; trimmed, max 32 characters
embarkmap, char_uidsvillagesend a party — capped per map (party_cap) and across all maps (world_cap)

recruit, embark, buy, list, unlist and buy_listing are guild-level: send them with no char_uid.

There is no rest action — a character you send nothing rests automatically: double stamina regen, and it heals a little (more with VIT) once it has gone unhit for a couple of seconds. Free healing in the field is a finite reserve per expedition (field_heal_mult × max HP, then resting only restores stamina): camping forever does not work. Pack or forage food, carry potions, or walk home — returning to the village refills the reserve. Your own frames carry field_healed so you can budget it. Idling in the village restores stamina fully and heals faster. Doing nothing is a real move.

5. Characters

Six stats. Every formula uses the effective bonus B(s), a published soft cap: full value up to 8, half rate from 9–16, quarter rate past 16 — so B(8)=8, B(16)=12, B(24)=14. Stats cap at 24.

statgoverns
STRheavy-weapon damage, carry cap (18 + 3×B), cheaper melee swings (−B//3 stamina)
DEXlight/ranged damage, shoot and throw range, cheaper shots and throws (−B//3 stamina)
INTimplement damage, max mana (6 + 4×B), mana regen, casting forms you can know (1 + B//4), essences you can attune (2 + B//6), potion potency (+0.05×B on the drinker's multiplier, capped ×2)
VITmax HP (18 + 6×B); out-of-combat idling heals 1 + B//4 HP
ENDmax stamina (40 + 8×B); regen is 5 + B//3 per tick
AGIspeed (AGI×5 + d4, rolled per tick) and cheaper moves (−B//2)

Recruits roll 1–2 in each stat and cost nothing. Every recruit also rolls two gifts — stats that cost half XP to raise, listed in the frame — so specialists come cheap and generalists come dear. XP comes from kills (split by damage dealt, and worth less once you far outlevel the victim — grinding easy bands stops paying) and discoveries; spend it with spend_xp. There are no classes. A character's level is a derived shorthand — total stat points above the 1-per-stat floor — so every purchased point is exactly +1 level.

Death is permanent. A dead character drops its whole inventory and equipment on its tile — for anyone to pick up. Your guild keeps its gold and guild inventory. Recruiting a replacement is free.

Unattended parties come home. If you send a character no action for 2000 ticks (about eight minutes), it is recalled to the village and your village frame gets a recalled event naming it. Resting counts as unattended — send any action, even say, to keep a party in the field. This is why a bot you left running overnight is standing in the village when you come back, with everything it was carrying intact. Nothing is lost; you just have to embark again.

When no guild has anyone fielded, the server stops simulating and only ticks for a few seconds after a request. Your bot does not need to know: it keeps receiving village frames, and anything it sends wakes the world.

6. Stamina

Stamina sets the pace: roughly one meaningful action every four or five ticks.

actionstamina
move20 − B(AGI)//2, plus gear; terrain changes it — webs and rime double it, trails cut it, diagonal steps (gear-gated) cost ×1.5
ride12 flat, however far the rail carries you
punch20 − B(STR)//3
chargethe weapon's own run-up cost, −B(STR)//3
weapon attackthe weapon's own cost, roughly 12–42 (light and fast to heavy and slow); melee −B(STR)//3, shots −B(DEX)//3
throw15 − B(DEX)//3
use / pickup / drop / equip / open / taste10
brew / forge15, paid once — the craft then runs on its own
smelt10
castper spell
village economy actions, say0

No cost drops below 5. You may act only when you can afford the cost; an idle tick regenerates stamina and mana at double rate.

7. Damage

Damage is deterministic — there are no to-hit rolls, so bots can plan: (weapon base + the weapon's own stat scaling) × quality tier − target armor, minimum 1 on a real hit. Every weapon scales off its own stats — daggers off DEX, mauls off STR, wands off INT — and owns a niche: reach, cleave, throwability, stun. What a weapon does shows in its uses and desc; the numbers you discover by using it. Armor is flat reduction. Magic ignores half of armor, and some gear and creatures resist or shrug it off entirely. Wards (from certain brews and a certain spell) soak damage before HP. Friendly fire is on: attacks hit whatever is on the tile, including your own guildmates and other guilds' characters. PvP is simply attacking an occupied tile.

Position multiplies force: striking from concealment (tall grass, held still) lands savage bonus damage with the right weapon. Heavy blows can stun or stagger (no regen while staggered), and force moves bodies: some attacks and spells shove, some drag their catch adjacent — walls stop all of it. Status effects exist — poison, burn, chill, sleep, haste, regen and more. Your own characters carry a full statuses list with remaining ticks; visible monsters show only which statuses they have; other guilds' characters show none. What causes each one is for you to find out.

8. Magic

Mana is a second pool, grown and regenerated by INT. It is spent two ways:

Implements — wands and scepters are hand weapons that fire magic bolts costing stamina and mana. Each carries an element, and elements interact with the world: ember burns and sets grass alight, leaving burning ground; frost chills and leaves slick rime underfoot; spark arcs to whoever stands beside the mark. Fire spreads through tall grass — the battlefield is flammable, yours included.

Spellweaving — implement-free casting speaks the same six-essence language as brewing. A cast is a form woven with an essence: cast {spell: form, essence, target}. Forms are the geometry, learned by use-ing a tome (consumed; INT gates the tome and how many forms you can hold, 1 + B//4): veil lays a lasting touch on one (range 3 or self), step teleports (range 4), bolt flies an 8-way line (range 5, first entity), field paints a 3×3 patch (range 4), ring takes everything within 2 of the caster. Essences are the payload: ember burns, frost slows, venom sickens, vigor mends (magic mending draws the same finite field reserve as resting), clarity reveals and purges workings, aether moves and shields. Not every weaving answers — the gaps are part of the grammar. Rings and fields hit whoever is there, friend or rival.

Attunement — aether is the weave itself, always in reach. The five material essences must be attuned: cast with focus: item_id naming any brewable ingredient you carry. The focus is consumed; if it truly bears the essence you named, the spell fires and you attune (cap 2 + B//6; at the cap the new bond displaces your oldest). A wrong focus miscasts — the working fizzles and the event names what the focus really carried, the same lesson taste sells. A held implement counts as attuned to its own element.

The weave — the six essences sit on a circle that differs world to world. Your previous cast is your thread (shown in your char frame); weaving an essence adjacent on the circle to your thread resounds (a veil on yourself is weave-neutral — the circle answers only under real stakes) (stronger), one directly across frays (weaker), and the cast event says which. Where each essence sits this world is yours to infer.

Heavy armor taxes casting: plate outfits add mana to every cast. The wizard in full harness is possible, just expensive.

9. Crafting

A craft is one command. brew, smelt and forge consume their inputs immediately and occupy the character for some ticks — a bigger job takes longer — and the result (or the failure, which always says why) arrives when the timer runs out. The in-progress state rides on your character as craft (watch craft.ticks_left); until it hits zero, every other action for that character errors crafting. Walking home abandons the work. The grammar is public; the vocabulary is discovered per world — identification is an inference puzzle, not a grind.

Brewing. Stand by a cauldron (or in the village) and brew 2–4 ingredients — an empty bottle in inventory is also consumed (the shop sells them). Every ingredient carries one of six essences, and the majority essence in the pot decides what you get; an exact tie between two can combine into something better, opposed essences curdle, and combinations that don't agree come out murky. Which herb carries which essence is shuffled every worldtaste one (destructive, gives a hint) or brew and read the result. Monster parts are fixed freebies that teach the grammar: venom_sac=venom, ectoplasm=aether, bone=vigor. Quality (tier 0–3, draught / potion / elixir / grand, scaling the effect ×0.6 / ×1.0 / ×1.6 / ×2.4) comes from what you put in: stronger ingredients help, and ingredients that agree with each other help more. When the pot finishes — success or failure — it tells you something about what went in: acrid smoke, sweet mist, a pale crust, a dark sheen. What those tells mean for your world's ingredients is yours to work out, one combination at a time. Finished potions can go back into the pot as ingredients.

Forging. By a forge (or in the village), smelt 2 matching ore into an ingot, then forge a product from ingots and lumber (felled trees drop it). Quality — tier 0–3, crude / sound / fine / masterwork, multiplying weapon damage ×0.8 / ×1.0 / ×1.2 / ×1.5 — comes from the metal and from an optional extra ingredient thrown in as flux: each metal favors something different in each world, the right flux perfects the piece, the wrong one mars it, and the anvil gives the same kind of tells the pot does. The metal caps the tier: copper only goes so far, rarer metal goes further. Masterwork bears its maker's name. A forged item can also be smelted back down for part of its metal — found gear is feedstock.

Found gear and potions on the ground turn up worn — never better than the lower tiers; good gear is crafted, bought, or taken. Village crafting is capped at tier 2: masterwork and grand elixirs need a real station out on a map — cauldrons and forges are contested infrastructure. The recipe pairs, each world's herbs, and what carries which tell are deliberately unpublished: log your results and iterate.

10. Carrying

Carrying is bulk, not slots. Every item has a bulk — an egg is 1, a maul is 5 — and a character carries 18 + 3×B(STR). Your frame shows carry: {used, cap}; picking up past the cap leaves the rest on the ground. Gold weighs nothing and goes straight to the guild.

11. The maps

Three, in rising order of challenge, and you choose which to embark on. Each anchors one crafting pillar. Every band of every map has several independent ways up, so a rival guild can never plug the only route — expect company, and expect to be able to go around it. All run bottom to top: you spawn in the band at the bottom, the exit is the bottom edge (move S from row 0), and enemies, loot and containers get better the further north you push. The village frame lists them under maps. Beyond the terrain, maps hold themed encounters, rare special places, and things that roam — what and where is yours to discover.

mapsizewhat it is
vale — The Vale72 x 200 the gentle overworld: meadows, forests, lakes and farmland. Tall grass (hold still to hide) conceals the motionless from monsters and rival guilds alike, trails are fast lanes, fences and bushes can be hacked through or bombed, crops and critters feed a party living off the land, and standing portals shortcut the climb. Herbs grow everywhere — the brewing map, with cauldrons out in the field
mines — The Embermines64 x 176 dug galleries and caverns threaded by wandering channels. Ore veins to mine, richer with depth; old minecart rails to ride; magma vents in the deeps; forges to work — the forging map. Something big guards the great forge at the top
spire — The Hollow Spire56 x 208 the haunted tower: rooms and corridors around three parallel spines, libraries, crypts. Tomes, gems and reagents — the magic map, and the hardest: nothing here is a starter monster, and what holds the sanctum at the top will not fall to a lone party

Bands refresh. Each map regenerates one horizontal band at a time on a schedule. Every map frame carries next_refresh, and a band_refresh_warning event fires a minute ahead. A band with characters still inside defers its refresh — but only for a while, and then it happens anyway. Loot left in a refreshed band is gone, and the band boundaries themselves shift a little over time — trust the frame, not a memorized row.

12. Economy

Gold is guild-level. The shop sells a small stock of basics at list price and buys anything back at 20%, scaled by its quality tier — which is exactly why the player market exists: list items at your own price, other guilds buy them, and the seller keeps every coin. Listings are public in every village frame. Guild inventory is free and infinite.

13. Connecting

ZeroMQ DEALER to the server's bot port, one JSON object per message. The client library does this for you; if you want to write your own:

-> {"type": "hello", "guild_id": "g_ab12", "token": "…"}
<- {"type": "hello_ok", "tick": 10411, "config": {...}, "guild": {...}}
<- {"type": "hello_err", "reason": "bad_token"}   check your guild_token.json
<- {"type": "frame", ...}                one per world per tick
-> {"type": "actions", "tick": 10412, "actions": [ ... ]}
<- {"type": "action_err", "char_uid": "…", "reason": "out_of_range"}
<- {"type": "server_pause"}              live restart — reconnect shortly
<- {"type": "kick", "reason": "superseded"}   another session hello'd as you
-> {"type": "bye"}                       polite hangup, optional

A new hello for your guild retires the previous session, so you never run two bots against each other by accident. A slow bot just misses ticks.

14. What isn't written down

This page describes the interaction surface completely. It deliberately does not list the items, outfits, enemies, recipes, each world's ingredient vocabulary, containers, traps, special places, what roams, or boss mechanics — the contents of the world are content. Your bot's local database (guild_log.db) records everything you have seen, which is where your map knowledge, drop tables and bestiary come from. Go find out.

Open your guild page →