Sharpee

July 3, 2026 · View on GitHub

npm

A parser-based Interactive Fiction authoring platform built in TypeScript.

Quick Start

The sharpee CLI ships in @sharpee/devkit — install it globally:

npm install -g @sharpee/devkit

Scaffold a project, then build and play:

sharpee init my-adventure
cd my-adventure
npm install
sharpee build
open dist/web/index.html
CommandWhat it does
sharpee init <name>Create a new story project
sharpee init-browserAdd browser client to existing project
sharpee buildBuild .sharpee bundle + browser client
sharpee build-browserBuild browser client only
sharpee ifidGenerate or validate an IFID

What's Included

@sharpee/sharpee is the umbrella package — it re-exports the story runtime baseline (ADR-178), the imports a story author needs. It deliberately does not re-export every symbol; for advanced use, import a sub-package directly. All 28 packages below are published individually on npm under the @sharpee scope.

PackageDescription
@sharpee/sharpeeUmbrella package — re-exports the story runtime baseline (ADR-178)
@sharpee/coreEvent system, types, utilities
@sharpee/engineGame engine, turn cycle, command execution
@sharpee/event-processorApplies semantic events to the world model
@sharpee/world-modelEntity system with traits and behaviors
@sharpee/if-domainCore domain model and contracts
@sharpee/if-servicesRuntime service interfaces (perception)
@sharpee/stdlib51 standard IF actions (take, drop, open, lock, etc.)
@sharpee/lang-en-usEnglish language output
@sharpee/parser-en-usEnglish natural language parser
@sharpee/helpersFluent entity builders (world.helpers())
@sharpee/queriesLINQ-style fluent entity query API
@sharpee/characterNPC behavior chain: character model, conversation, goals, influence, propagation
@sharpee/pluginsPlugin contracts for engine turn-cycle extensibility
@sharpee/plugin-npcNPC behaviors and autonomous turn processing
@sharpee/plugin-schedulerDaemons and fuses (timed events)
@sharpee/plugin-state-machineDeclarative puzzle and narrative orchestration
@sharpee/mediaAudio event types, AudioRegistry, and capability negotiation
@sharpee/text-blocksStructured text output interfaces (ITextBlock, IDecoration)
@sharpee/channel-serviceUniversal channel-I/O wire producer (ADR-163)
@sharpee/platform-browserFramework-free browser client infrastructure
@sharpee/ext-basic-combatGeneric skill-based combat extension
@sharpee/ext-testingDebug and testing tools (/debug, /trace, $teleport)
@sharpee/bootstrapStory loader — assembles a .sharpee story into a runnable game
@sharpee/devkitThe sharpee CLI — build/test/verify/scaffold orchestration (ADR-180)
@sharpee/story-runtime-baselineManifest of the canonical baseline packages a bundle may import (ADR-178)
@sharpee/ide-protocolWire types for the IDE project-introspection manifest (ADR-184)
@sharpee/transcript-testerTranscript-based testing framework

Features

  • Event-Driven Architecture — Immutable semantic events for all state changes
  • Natural Language Parser — Complex player commands with slot constraints
  • Rich World Model — Entities with traits, behaviors, and relationships
  • 51 Standard Actions — take, drop, open, close, lock, unlock, wear, eat, drink, attack, and more
  • Four-Phase Action Pattern — Consistent validate/execute/report/blocked flow
  • Capability Dispatch — Entity-specific handling for generic verbs
  • Entity Helpers — Fluent builder API for rooms, objects, containers, doors, actors
  • NPC Behavior Chain — Character model with psychology, constraint-based conversation, goal pursuit, information propagation, and NPC-to-NPC influence
  • Direction Vocabularies — Location-relative directions (compass, naval, minimal, or custom)
  • Audio System — Typed audio events, AudioRegistry, procedural sound, atmosphere builder
  • Daemons & Fuses — Timed events and background processes
  • Perception System — Darkness, blindness, and sensory restrictions
  • Language Layer Separation — All text output goes through localizable message IDs
  • Channel-Based UI — Story→UI signals flow over channels (ADR-163); the same story runs in the CLI, a framework-free browser client, and the Zifmia multi-user server
  • Full TypeScript — Strict typing throughout

Creating a Story

import { Story, StoryConfig } from '@sharpee/engine';
import { WorldModel, IFEntity, Direction } from '@sharpee/world-model';
import '@sharpee/helpers';

export const config: StoryConfig = {
  id: 'my-adventure',
  title: 'My Adventure',
  author: 'Your Name',
  version: '1.0.0',
};

export class MyStory implements Story {
  config = config;

  initializeWorld(world: WorldModel): void {
    const { room, object } = world.helpers();

    const start = room('Starting Room')
      .description('A simple room with a lamp on the floor.')
      .build();

    object('brass lamp')
      .description('A well-polished brass lamp.')
      .in(start)
      .build();

    const player = world.getPlayer();
    world.moveEntity(player!.id, start.id);
  }

  createPlayer(world: WorldModel): IFEntity {
    const { actor } = world.helpers();

    return actor('yourself')
      .description('As good-looking as ever.')
      .aliases('self', 'me')
      .properName()
      .inventory({ maxItems: 10 })
      .build();
  }
}

export const story = new MyStory();
export default story;

See the Getting Started guide for a complete walkthrough.

Entity Helpers

world.helpers() returns fluent builders for common entity types:

import '@sharpee/helpers';

const { room, object, container, actor, door } = world.helpers();

// Rooms
const cave = room('Dark Cave').description('A damp cave.').dark().build();

// Objects with custom traits
const note = object('crumpled note')
  .description('A crumpled piece of paper.')
  .addTrait(new ReadableTrait({ text: 'The code is 4-7-2.' }))
  .in(cave)
  .build();

// Containers
const chest = container('wooden chest')
  .openable({ isOpen: false })
  .lockable({ isLocked: true, keyId: key.id })
  .in(cave)
  .build();

// Items in closed containers (bypasses validation)
object('gold coin').skipValidation().in(chest).build();

// Doors between rooms
door('iron door')
  .between(cave, hallway, Direction.NORTH)
  .openable({ isOpen: false })
  .build();

Architecture

+-----------------------------------------------+
|              Your Story                       |
+--------------------+--------------------------+
| stdlib (actions)   | lang-en-us (messages)    |
| plugins (npc,      | parser-en-us (grammar)   |
|  scheduler, state) |                          |
+--------------------+--------------------------+
| engine | world-model | helpers | channels     |
+-----------------------------------------------+
| if-domain | if-services | event-processor     |
+-----------------------------------------------+
| core (events, types) | media (audio types)   |
+-----------------------------------------------+

Rendering is the engine's prose pipeline producing ITextBlock[], carried to the UI by channels (ADR-163/174) — there is no separate text service.

Key Principles

  1. Actions emit semantic events, not text — The language layer converts message IDs to prose
  2. Behaviors own mutations — Actions coordinate, behaviors perform state changes
  3. Traits compose entity capabilities — Add container, lockable, wearable, etc.
  4. Parser scope is permissive — Actions decide if visibility is truly required

Zifmia Multi-User Server

Zifmia is the multi-user server (ADR-177) for hosting .sharpee story bundles — each player gets their own session over a shared story, with per-room saves. It ships as a self-contained Docker container and is built with sharpee build --zifmia.

Standard Actions

Movement: going, entering, exiting, climbing Manipulation: taking, dropping, putting, inserting, removing, giving, throwing Containers/Doors: opening, closing, locking, unlocking Examination: looking, examining, searching, reading Interaction: talking, showing, attacking Devices: switching on/off, pushing, pulling, raising, lowering Wearables: wearing, taking off Consumables: eating, drinking Senses: touching, smelling, listening Meta: inventory, score, help, save, restore, restart, quit, undo, again, wait, about, version, sleep

Repository Development

git clone https://github.com/ChicagoDave/sharpee.git
cd sharpee
pnpm install

# Build everything (devkit; ADR-180)
./sharpee build dungeo

# Run tests
pnpm test

# Run specific package tests
pnpm --filter '@sharpee/stdlib' test

# Run story transcript tests
node dist/cli/sharpee.js --test stories/dungeo/tests/transcripts/*.transcript

Example Stories

StoryLocationDescription
dungeostories/dungeoMainframe Zork implementation (~191 rooms, 650 points + 100 endgame)
familyzootutorials/familyzoo/v1.5.0, tutorials/familyzoo/v2.0.0The book's Family Zoo — chapter-by-chapter tutorial snapshots, built against the published npm packages. Split into two editions: v1.5.0 (the frozen 1.x line, pins ^1.5) and v2.0.0 (the Phrase Algebra line, pins ^2.0)
entropystories/entropyOriginal sci-fi story with audio system (in progress)

Roadmap

Sharpee is actively developed. These are the open Architecture Decision Records representing planned future work.

Recently Implemented

  • NPC Behavior Chain (ADR-141, 142, 144, 145, 146) — Character psychology, conversation, goal pursuit, information propagation, NPC influence
  • Direction Vocabularies (ADR-143) — Location-relative directions (compass, naval, minimal, custom)
  • Audio System (ADR-138) — SFX, music, ambient, procedural audio, AudioRegistry
  • Entity Helpers (ADR-140) — Fluent builder API for story setup
  • Action Interceptors (ADR-118) — Story-level hooks on standard actions

Accepted (Implementation Planned)

  • Screen Reader Accessibility (ADR-100) — ARIA support for the Zifmia client
  • Speech Accessibility (ADR-139) — TTS/STT for blind and motor-impaired players
  • Equivalent Objects (ADR-147) — Identical object groups, numeric commands, trade/sell/barter

Proposed

AreaADRDescription
Story ParadigmsADR-083Spirit PC — Non-physical player character support
Story ParadigmsADR-102Dialogue Extension — NPC conversation systems (ASK/TELL, menus)
Story ParadigmsADR-103Choice-Based Stories — CYOA-style with parser hybrid
World ModelADR-020Clothing and Pockets — Container hierarchy for wearable items
ClientsADR-098Terminal Client — CLI-based game client
ClientsADR-099GLK Client — Standard IF interpreter protocol
ClientsADR-122Rich Media and Story Styling — Embedded media in output
ZifmiaADR-125Panel and Windowing System — Multi-panel desktop client
ZifmiaADR-128Walkthrough Panel — In-client walkthrough display
ZifmiaADR-130Story Installers — Split runner from author packaging tool
Author ToolsADR-115Map Export CLI — Export story maps from code
Author ToolsADR-116Prompt-to-Playable — AI-assisted story development
Author ToolsADR-131Automated World Explorer — Regression test generator
EngineADR-127Location-Scoped Interceptors — Room-tied action interceptors

See the full ADR index for the complete set of architecture decisions.

License

MIT License — Copyright 2025-2026 David Cornelson