Author the canon. Let AI inhabit it.
An AI-native interactive fiction engine for autonomous NPCs, private memory, and director-guided stories.
Ghost Scene is a server-authoritative Bun/TypeScript framework: authors own the canonical facts, while AI inhabits bounded NPC and Director roles.
- Private NPC memory: each NPC receives only its own profile, state, perceptions, and memories. Characters do not share an all-knowing conversation history.
- Bounded AI Director: the Director chooses among authored possibilities, but cannot invent legal events or rewrite world rules.
- Authoritative atomic turns: the server validates structured actions and model output, then commits an entire turn or rolls it back.
- Declarative story packs: authors define the world, characters, items, beats, events, recovery routes, and endings in replaceable, lazily loaded content packs.
Requires Bun and a compatible Chat Completions endpoint.
bun install
bunx playwright install chromium
cp .env.example .env
# Set LLM_BASE_URL, LLM_API_KEY, and LLM_MODEL.
bun run devThe development server listens on http://localhost:8787 by default.
flowchart LR
UI[Browser Client] --> Engine[Game Engine]
Engine --> Rules[World Rules]
Engine --> Harness[Runtime Harness]
Harness --> Director[AI Director]
Harness --> NPCs[Isolated NPC Contexts]
Engine --> Pack[Declarative Story Pack]
The browser renders only the visible state and legal actions projected by the server. The game engine owns rules, persistence, and atomic turns; its Runtime Harness performs bounded AI calls and private retrieval. Story packs remain the authority for canonical content. The development Harness under scripts/ checks architecture and release boundaries and is not part of the production Runtime Harness.
Each replaceable pack follows the same declarative shape:
stories/my-story/
├── manifest.json
├── world/
├── characters/
├── items.json
├── story/
├── phone/ # optional
└── assets/
Indexes and the current turn determine which story chunks are loaded. Before releasing a replacement pack, validate its schema and fixed solution replays:
STORY_ROOT=stories/my-story bun run story:check:release- Explore a server-projected map and move only through confirmed adjacent locations.
- Inspect, take, drop, and use visible items through authored legal actions.
- Talk locally or by phone when the story enables those channels.
- Search an optional fixed, read-only in-game browser; it never accesses the real internet.
- Keep map deductions and a persistent notebook in local browser storage. Notes do not enter authoritative story state and survive a game restart.
- Prompt injection: player text stays opaque data. It cannot directly become an instruction to the engine, NPCs, or Director.
- Private memory: each NPC call receives only that character's bounded context; private memories are owner-scoped in SQLite.
- Model output: strict structured responses are schema-validated and checked against authored candidates before they can affect the world. Invalid output fails the turn without a partial commit.
- Persistence: authoritative run state and memories live in SQLite. Browser notes are deliberately local and never enter the server's story state.
- Deployment: anonymous installation IDs are not authentication. Public hosting requires an external identity, rate-limiting, and cost-control gateway.
./scripts/check.sh is the sole full project gate. It checks the development Harness, TypeScript, story validation, server and client builds, unit tests, browser tests, and whitespace.
Fresh full-gate result: 321 Bun tests + 32 Playwright tests = 353 automated tests. The default suite uses scripted fake models and makes no paid calls.
Ghost Scene is an Early Alpha framework, not a production-ready hosted service or a completed commercial horror game. The included Mist Village story is a compact end-to-end validation fixture.
- Real NPC and Director responses require a compatible Chat Completions endpoint and may incur provider cost; the default tests use scripted fake models and make no paid calls.
- The server currently runs as one Bun process backed by SQLite.
- Anonymous installation IDs are not authentication, so public hosting needs an external identity and rate-limiting gateway.
- Multiplayer, combat, real-time chases, Godot, real internet browsing, cloud sync, multiple save slots, and the AI authoring assistant are outside this release.
Issues and focused pull requests are welcome. Preserve the server-authoritative boundary, NPC memory isolation, authored story authority, and the distinction between the production Runtime Harness and the development Harness. Run ./scripts/check.sh before submitting changes.
Licensed under the Apache License 2.0.
