Client-agnostic source of truth for everything botable in OSRS: activities, ordering, actions, requirements. AI agents translate entries into client APIs.
Go to file
Claude 34f36d2275 codex: dynamic SII recipe selection + realized rates + validator crash fix (bounce fix attempt 3, owner guidance)
Owner decision (2026-08-28): Superheat Item uses a dynamic recipe table
governed by Smithing level — highest UNLOCKED recipe selected, primary ore
(target_input, never coal) is the spell target, fallback to the next lower
unlocked recipe, else skip SII and stay on LA.

- magic-alch-handoff: per-recipe target_input; selection block
  (mode highest-unlocked / eligible_rule / fallback); full-lifecycle
  actions (buy-staff, equip-staff w/ fire-rune failure path, buy-supplies,
  cast-alch, cast-superheat, bank-loop, take-break); deterministic restock
  (LA/HLA carried_batch 1,000 + threshold 100 -> 901-cast batches; SII
  24-cast bank cycles, bars >= 24); breaks [400,700] COMPLETED casts,
  independent of banking; worked example pinned (prep -> first restock @24
  -> break @550 -> resume -> restock @552); stop conditions + recovery block
- rates REALIZED incl. mandatory breaks + banking: LA 24,500 / SII 27,500 /
  HLA 51,400 xp/hr (formulas pinned; loop-only 837/hr and 305/hr regimes
  superseded); low-alch-f2p also switched (xp 24,500, gp -110,500..-74,000)
- validate.py: rows now collected ONLY after schema validation (schema-
  invalid MAPPINGS incl. 'economy: not-a-mapping' produce normal ERRORs,
  never AttributeError tracebacks — end-to-end subprocess regression added);
  new gates: recipe_model_errors (target_input in declared inputs, coal
  never targetable, unique smithing gates, selection block + SII/fallback
  transitions) and rate_errors (xp_per_hour must match the realized cadence,
  tolerance 2%); highest_unlocked_recipe helper + 6 eligibility fixtures
- entry.schema.json: optional selection block + per-recipe target_input
- Evidence: validate 2 entries 0 errors 0 warnings; --selftest 31 PASS;
  governor's exact direct repro supply_limit_conflicts([('bad.yaml',
  {'economy':'not-a-mapping'})]) -> [] no crash; synthetic 3-way merge of
  main 79cab78 (incl. issue-6 catalog) + head: clean, gate green; git
  diff --check clean
2026-08-28 03:11:07 -05:00
codex codex: dynamic SII recipe selection + realized rates + validator crash fix (bounce fix attempt 3, owner guidance) 2026-08-28 03:11:07 -05:00
docs Codex skeleton: schema contract, action grammar, data-sources rules, JSON schema, validator, golden example (low-alch-f2p, wiki+price verified), README 2026-08-27 02:59:55 -05:00
schemas codex: dynamic SII recipe selection + realized rates + validator crash fix (bounce fix attempt 3, owner guidance) 2026-08-28 03:11:07 -05:00
tools codex: dynamic SII recipe selection + realized rates + validator crash fix (bounce fix attempt 3, owner guidance) 2026-08-28 03:11:07 -05:00
README.md Codex skeleton: schema contract, action grammar, data-sources rules, JSON schema, validator, golden example (low-alch-f2p, wiki+price verified), README 2026-08-27 02:59:55 -05:00

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)

  1. One entry = one activity. State machine + action list, both mandatory.
  2. 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 against prices.runescape.wiki on every bump.
  3. 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 requires improvised: true.
  4. Anti-ban is first-class. Every action declares delay bounds and movement style; entries carry risk.ban_level + notes.
  5. The gate must pass before a PR merges: python3 tools/validate.py.
  6. 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.