# Brass Lantern > An npm library for classic parser text adventures (go north, take lamp) in a CRT terminal. Worlds are data: rooms, items, characters, rules and events in one typed object. It also plays Z-machine story files such as Zork. The whole documentation in one file: [llms-full.txt](https://mrballistic.github.io/brass-lantern/llms-full.txt) ## Start here - [Home](https://mrballistic.github.io/brass-lantern/index.md): Three library packages for classic parser games in a CRT terminal, plus an MCP server for coding agents. Write your own world as data, mount it on a page, or load a Z-machine story file. The demo plays the Zork trilogy. ## Guide - [Getting started](https://mrballistic.github.io/brass-lantern/guide/getting-started.md): Brass Lantern is a small engine for classic parser text adventures (*go north*, *take lamp*, *give the mug to Gary*) that runs in the browser inside a CRT terminal. You write a game as data; the engine runs it. - [Using the library](https://mrballistic.github.io/brass-lantern/guide/using-the-library.md): Brass Lantern is three library packages, plus an MCP server for coding agents (Coding agents). Use the libraries to put a game in your own app, run one headless in Node, or add the intent server to a backend you already have. - [Coding agents](https://mrballistic.github.io/brass-lantern/guide/coding-agents.md): Two ways to give a coding agent (Claude Code, Cursor, Codex and the like) what it needs to build a Brass Lantern world: the docs as one file, and a local MCP server that can also audit and play the world it writes. - [Playing story files (Zork)](https://mrballistic.github.io/brass-lantern/guide/z-machine.md): Brass Lantern also runs **Z-machine story files**, the format Infocom’s games shipped in. The demo includes the **Zork trilogy** (Zork I Release 119, Zork II Release 63, Zork III Release 25), which Microsoft released under the MIT License in 2025. It plays exactly as Infocom wrote it, in the same CRT terminal as native worlds. The npm packages bring the interpreter, not the games: see Cartridges for adding story files to your own app. - [Porting Zork](https://mrballistic.github.io/brass-lantern/guide/porting-zork.md): Brass Lantern ships Zork I twice: the original story file, run by the Z-machine interpreter, and **ZORK I · NATIVE**, a rebuild as an ordinary Brass Lantern world (`packages/engine/src/worlds/zork1.ts`). The native version is how the engine proves it can carry an Infocom-class game. A test plays both side by side and fails if they disagree. - [How it works](https://mrballistic.github.io/brass-lantern/guide/how-it-works.md): Three parts, kept deliberately apart, and shipped as three library packages (Using the library), plus an MCP server for coding agents (Coding agents): the engine and parser are `@brass-lantern/engine`, the terminal and stores are `@brass-lantern/vue`, and the intent server is `@brass-lantern/server`. The engine imports no Vue, Pinia or browser globals, so the same turn loop runs in a browser, in Node (`createGame`) and in tests. - [The intent server](https://mrballistic.github.io/brass-lantern/guide/intent-server.md): Players don’t type like parsers. The intent server hears what the regex parser couldn’t handle, such as “make that thing stop beeping” or “pocket my billfold”, and asks an LLM which of the engine’s verbs and IDs that means. It’s optional: without it the game is fully playable, and loose phrasing just gets a “didn’t understand” reply. - [Deploying](https://mrballistic.github.io/brass-lantern/guide/deploying.md): A Brass Lantern game is a static site, plus the intent server if you want loose phrasing understood. If you use the packages in your own app (Using the library), deploy your app the way you already do and mount `intentRoute` in your backend; this page is about the repo’s demo site and server. ## Building worlds - [Overview](https://mrballistic.github.io/brass-lantern/guide/building-worlds/index.md): A world is one TypeScript object, typed by `World`. There’s no build step, no scripting language and no engine code to write: rooms, items, people and rules are data, and the engine plays them. - [A two-room game](https://mrballistic.github.io/brass-lantern/guide/building-worlds/two-rooms.md): This page builds the smallest complete game, `packages/engine/src/worlds/examples/two-rooms.ts`, from nothing. You’re home after a long time away; the door is locked, and you left the key somewhere obvious. A test plays it to the end. - [The demo game: Snack Attack](https://mrballistic.github.io/brass-lantern/guide/your-first-world.md): A world is one TypeScript object: rooms, items, people, the lines they say, and the rules that join them. If you haven’t written one yet, start with a two-room game; this page goes further, and builds **Snack Attack**, the tutorial world (`tutorial` in `@brass-lantern/engine/worlds`, source on GitHub), piece by piece. A test plays that exact file to the end, so everything here matches what the engine does. - [Recipes](https://mrballistic.github.io/brass-lantern/guide/building-worlds/recipes.md): Each recipe is a small, complete world about one idea, in `packages/engine/src/worlds/examples/`. Every transcript on this page is what a test gets by typing its commands into that world. - [Testing a world](https://mrballistic.github.io/brass-lantern/guide/testing.md): A world is data, and data rots quietly: an exit points at a renamed room, a flag label gets a typo, the ending becomes unreachable. Two kinds of test catch nearly all of it, and both run in plain Node with any test runner. The examples here use Vitest. ## Reference - [World schema](https://mrballistic.github.io/brass-lantern/reference/world-schema.md): Every field a world can use. The source of truth is `packages/engine/src/types/world.ts`, which has a comment on each one. “Condition” means a condition string; “event” means a key in `events`. - [Conditions and events](https://mrballistic.github.io/brass-lantern/reference/conditions-and-events.md): Conditions are strings, used by `requires`, exits (`if`, `denials`), room `descriptions`, `onEnter`, rules (`instead`, `after`, `onUse`), dialogue keys, hints, scoring, daemons, the finale’s epilogue and ambient lines. One parser handles all of them. A missing or blank condition always holds, so a trigger (`onEnter` and the like) may leave out `if`. - [Player commands](https://mrballistic.github.io/brass-lantern/reference/commands.md): The built-in verbs are fixed; a world gives them things to act on, and can add verbs of its own. Anything the regex parser doesn’t recognize, or recognizes but can’t act on, can go to the intent server, which maps loose phrasing onto these. - [Cartridges and storage](https://mrballistic.github.io/brass-lantern/reference/cartridges.md): Cartridges are what you pass in `GameOptions.cartridges` (see Using the library). The types, `Cartridge`, `WorldCartridge` and `ZCodeCartridge`, are exported from both `@brass-lantern/engine` and `@brass-lantern/vue`.