Owner lifecycle addendum (2026-08-28) + governor bounce 4 (lifecycle contract):
- state machine now covers the ENTIRE buy -> sell -> collect flow with no
stranded state: partial fills tracked per slot (filled_qty ledger), 4h-lapse
buys go to a new cancel_requote state (ge_cancel: units return to inventory,
cash refunds, slot freed) instead of collect, cancelled units still sell at
the high edge, lapse sells re-quote or lower rather than strand
- action grammar + schema extended ONCE with the cancellation mutation
ge_cancel (was missing; ge_clear/ge_offers_done are predicates only) and
used explicitly in the new a8 cancel-requote action
- concrete runtime state: minimum per-slot capital table (buy x 4h limit),
members 8-slot vs F2P 3-slot paths, per-slot offer phase + quantities,
buy-limit window, inventory/collection reconciliation in a9
- breaks connected to an explicit safe/resume path: resting offers persist
server-side + per-slot ledger survive the pause; resume = re-open GE,
re-check offers, continue current phase; never break mid-collect/mid-place
- rates qualified against the full lifecycle: 149,500 gp/h is named the 4h
buy-limit CEILING; realized range = ceiling x fill_factor (~0.5-0.9) x
duty_cycle (~0.90-0.95) ~ 96,300 gp/h midpoint; gp_per_hour_low 74,750
- pinned worked example: capital 22.5M -> 8 slot quotes -> arrowtips partial
fill (4,000/10,000 tracked) -> iron bar full fill sell (90,000 net) ->
cosmic no-fill ge_cancel + requote -> arrowtips partial matures at lapse
(cancel, sell 4,000, 68,000 net) -> first break after 6-10 rotations ->
resume -> stop conditions
- version 2 -> 3; evidence: validate 2 entries 0 errors 1 pre-existing WARN,
selftest 4 PASS (fractional-tax fail, ge non-margin pass, floored pass,
above-cap pass), synthetic merge main
|
||
|---|---|---|
| codex/economy | ||
| docs | ||
| schemas | ||
| tools | ||
| README.md | ||
OSRS Codex
One source of truth for everything that can be botted in OSRS.
Every bot-able activity — alching, mining, slayer, bosses, trading — is described here once, in a strict client-agnostic YAML structure: requirements, execution order (state machine), the exact action sequence, economics, best-in-class setup, and anti-ban notes.
AI agents building scripts do not re-learn the game. They read a codex entry and translate it into the target client API (DreamBot / Microbot / Storm / RuneLite plugins / …). The game knowledge lives in this repo; the client glue lives in whatever script is being written.
client-agnostic client-specific (NOT in this repo)
+----------------+ +-------------------+
| codex entry | translate | DreamBot Java |
| (YAML, strict) | ---------> | Microbot JS |
| actions: verbs | | RuneLite plugin |
+----------------+ +-------------------+
Layout
codex/<domain>/<entry-id>.yaml # one entry per activity
economy/ trading, alching, flipping
training/ skill grinds (magic, mining, woodcutting, ...)
combat/ bosses
combat-slayers/
quests/ quest entries (referenced by requires_quest)
transport/ teleport/teleport-reach recipes (shared by many entries)
meta/ account rotation, world hopping, break scheduling
docs/schema.md # the entry contract (read this first)
docs/action-grammar.md # the universal verb vocabulary
docs/data-sources.md # where every fact must come from + how to verify
schemas/entry.schema.json
tools/validate.py # the gate: python3 tools/validate.py (must exit 0)
The rules (short version)
- One entry = one activity. State machine + action list, both mandatory.
- Every fact carries a source. Wiki-cited or
researched <date>(a TODO: follow-up issue must land the proper citation). Live prices are re-verified againstprices.runescape.wikion every bump. - Best-in-class setup is mandatory (
best_practice). Top-operator execution: staff of fire for alchemy, noted items, shortest routes. Translators adopt it by default; deviating requiresimprovised: true. - Anti-ban is first-class. Every action declares delay bounds and
movement style; entries carry
risk.ban_level+ notes. - The gate must pass before a PR merges:
python3 tools/validate.py. - Never mix in client knowledge. No DreamBot/Microbot/Storm API names in entries. Translations live in script repos, referencing the entry id.
Entry lifecycle
draft → verified (all facts sourced, prices re-checked, validator
clean) → stale (facts > 30d old or prices moved materially). Stale
entries are skipped by translators unless explicitly allowed.
Contributing
This repo is issue-driven: all content is specified in Gitea issues
(acceptance criteria + source URLs + expected output path), implemented in
branches, and gated by tools/validate.py in CI. No direct pushes.