osrlib
osrlib is a Python library implementing the classic 1981 B/X (Basic/Expert) fantasy adventure game rules for turn-based, grid-based dungeon crawlers in the style of the original Bard's Tale. The rules are sourced from the Old-School Essentials System Reference Document, an Open Game Content restatement of the B/X rules.
osrlib is the rules authority and game-state engine; your game supplies presentation, input, and content. The library is headless and sans-I/O — it never renders, prompts, sleeps, or touches the network — and every game it runs is deterministic: the same seed and the same commands always replay the same game. Adventures carry their own content and behavior — bundled items, gated doors, triggers, and quests — and the library ships the interpreter that plays them through to a victory ending.
Four kinds of consumer are first-class:
- A web or mobile backend — a FastAPI service serving a crawler over HTTP, with JSON Schema for every command and event
- A terminal game — a local TUI crawler driving the engine through synchronous calls
- An LLM referee or narrator — an agent that consumes structured events and drives the engine with typed commands
- Scripts and simulations — balance testing, mass-combat statistics, and content validation, calling the rules kernel with no session at all
Where to start
- The quickstart runs the whole loop — characters, party, adventure, session, commands, events, save, and load — in one sitting.
- Building an adventure teaches the dungeon itself: the grid and its edges, keyed areas, and the content that binds to them.
- Gates, triggers, and quests adds the authored behavior: the door that needs a key, the lever that opens a portcullis, and the quest that ends the adventure in victory.
- The guides teach the contracts: sessions and the command/event loop, visibility, determinism, the rules without a session, listeners, authoring, and ruleset options.
- The front end walk-throughs tour the two example games that ship in the repository, and the LLM referee page maps the same surface onto an agent.
- The reference documents every public symbol, command, event, rejection code, message code, RNG stream, and content id.
- The changelog on GitHub records what each release changed.
What things are called
The project's vocabulary maps one-to-one onto API names, so it pays to learn it early. The common name locates the concept; the linked page teaches the term:
| You may know it as | osrlib calls it | Taught in |
|---|---|---|
| A quest log | the journal | Listeners and flags |
| A scripted event | a trigger | Gates, triggers, and quests |
| A locked door that needs an item | a gate | Gates, triggers, and quests |
| The text an event shows | beats on a narrative block | Gates, triggers, and quests |
| What the player is allowed to see | the player view | Views and visibility |
| Seedable randomness | named streams and draws | Determinism, saves, and replay |
| A save file | a stamped document | Determinism, saves, and replay |
| A win condition | a concluding quest and victory |
Gates, triggers, and quests |
Installation
Install osrlib from PyPI. The library requires Python ≥ 3.14 and its only runtime dependency is pydantic.
or, with pip:
Licensing
Library code is MIT-licensed; the compiled game data is Open Game Content under the Open Game License 1.0a. The licensing page has the full split and the Section 15 notice.