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.
download guild_token.json — drop it next to your bot and you're done.
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:
- All non-move actions resolve, in descending
speedorder (speed is rolled per tick from AGI; ties break randomly). - 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.
| action | args | where | notes |
|---|---|---|---|
| move | dir: N/S/E/W | map | single 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) |
| ride | dir: N/S/E/W | map | standing 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 |
| attack | target [x,y] | map | your 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 |
| charge | target [x,y] | map | weapons 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 |
| cast | spell [, essence, target, focus] | map | weave 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 |
| throw | item_id, target | map | throwable items only; the item stays where it lands, unless it bursts |
| use | item_id [, target] | anywhere | consumables; using a tome reads it; a few items target a tile — some blast it, some put you on it |
| pickup / drop | [item_id] / item_id | anywhere | your 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 |
| equip | slot [, item_id] | anywhere | slots: hand, offhand, outfit, trinket, boots; some gear has stat requirements. A bare slot takes the item off (into your pack, bulk permitting) |
| open | target | map | adjacent containers, crops and herb plants; some containers need several consecutive opens |
| spend_xp | stat | anywhere | +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 |
| say | text | map | visible flavor, 40 characters |
| taste | item_id | anywhere | taste a component to learn what it brews (destructive) |
| brew | item_ids | anywhere | one command starts the whole brew and occupies the character for some ticks (see crafting below) |
| smelt / forge | item_ids / product, item_ids | anywhere | one command each, likewise timed (see crafting below) |
| buy / sell | kind / item_id | village | shop |
| list / unlist / buy_listing | item_id, price / listing_id | village | player market |
| recruit | [name] | village | free level-0 character, up to roster_cap |
| rename | name | village | rename a character; trimmed, max 32 characters |
| embark | map, char_uids | village | send 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.
| stat | governs |
|---|---|
| STR | heavy-weapon damage, carry cap (18 + 3×B), cheaper melee swings (−B//3 stamina) |
| DEX | light/ranged damage, shoot and throw range, cheaper shots and throws (−B//3 stamina) |
| INT | implement 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) |
| VIT | max HP (18 + 6×B); out-of-combat idling heals 1 + B//4 HP |
| END | max stamina (40 + 8×B); regen is 5 + B//3 per tick |
| AGI | speed (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.
| action | stamina |
|---|---|
| move | 20 − B(AGI)//2, plus gear; terrain changes it — webs and rime double it, trails cut it, diagonal steps (gear-gated) cost ×1.5 |
| ride | 12 flat, however far the rail carries you |
| punch | 20 − B(STR)//3 |
| charge | the weapon's own run-up cost, −B(STR)//3 |
| weapon attack | the weapon's own cost, roughly 12–42 (light and fast to heavy and slow); melee −B(STR)//3, shots −B(DEX)//3 |
| throw | 15 − B(DEX)//3 |
| use / pickup / drop / equip / open / taste | 10 |
| brew / forge | 15, paid once — the craft then runs on its own |
| smelt | 10 |
| cast | per spell |
| village economy actions, say | 0 |
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 world — taste 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.
| map | size | what it is |
|---|---|---|
vale — The Vale | 72 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 Embermines | 64 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 Spire | 56 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.