Story Engine Core
Relevant source files
The following files were used as context for generating this wiki page:
The Story Engine Core is a central TypeScript package within the MCP Games monorepo responsible for managing game logic, state transitions, and narrative progression. It serves as the primary state machine for Choose Your Own Adventure (CYOA) experiences, handling the complex interplay between user choices, story variables, and scene navigation.
The engine is designed to be consumed by front-end applications like the cyoa-engine and works in tandem with the shared-types package to ensure data consistency across the ecosystem. Its primary scope includes choice tree management, variable tracking (including increment/decrement operations), and state serialization for save/load functionality.
Sources: packages/story-engine/README.md:1-12, README.md:38-44, packages/story-engine/package.json:1-10
Architecture and State Management
The core of the system is the StoryEngine class, which encapsulates the logic for traversing a defined Story structure. It maintains the current state of a player's journey, including their position in the narrative and any modified game variables.
State Representation
The StoryState interface tracks the active session, including the user identity, the current scene, and a history of choices made.
The state object is the single source of truth for a player's progress at any given moment.
Sources: packages/story-engine/src/index.ts:18-31, packages/shared-types/src/index.ts:88-90
Core Engine Logic
The StoryEngine provides methods to initialize, progress, and query the story state.
| Method | Description | Return Type |
|---|---|---|
start(userId) | Initializes a new state using the first scene of the story and default variables. | StoryState |
makeChoice(state, choiceId) | Validates requirements, applies variable effects, and transitions to the next scene. | StoryState |
getAvailableChoices(state) | Filters choices in the current scene based on met requirements. | Choice[] |
getProgress(state) | Calculates the percentage of unique scenes visited relative to the total story size. | number |
isEnded(state) | Determines if the current scene is a terminal node (no choices available). | boolean |
Sources: packages/story-engine/src/index.ts:39-115
Narrative Flow and Choice Processing
The engine processes transitions between Scene objects through Choice interactions. Each choice can contain requirements that must be met to be visible/selectable and effects that modify the global story state.
Choice Execution Flow
When a player selects a choice, the engine performs a series of sequential checks and updates.
This flow ensures that state mutations only occur if the transition is logically valid according to the story definition.
Sources: packages/story-engine/src/index.ts:58-82
Variable Manipulation
The engine supports multiple operations for modifying StoryVariables through VariableEffect definitions.
| Operation | Logic | Source Implementation |
|---|---|---|
set | Directly overwrites the variable with a new value. | newVariables[variable] = value |
increment | Adds the value to the existing numeric variable. | (Number(prev) || 0) + Number(value) |
decrement | Subtracts the value from the existing numeric variable. | (Number(prev) || 0) - Number(value) |
append | Adds a value to an array or initializes a new array. | array.push(value) |
Sources: packages/story-engine/src/index.ts:162-187, packages/shared-types/src/index.ts:74-78
Data Structures
The Story Engine relies on structural definitions from shared-types to represent the narrative tree.
Choice Requirements
Choices can be gated by specific conditions. Currently, the engine implements variable-based checks:
- Variable Requirements: Compares current
StoryState.variablesagainst theChoiceRequirements.variablesmap. - MCP Data Requirements: (Placeholder) Intended for future integration with the
mcp-connectorto gate choices based on external data (e.g., GitHub activity).
Sources: packages/story-engine/src/index.ts:141-158, packages/shared-types/src/index.ts:69-72
Persistence and Serialization
The engine facilitates saving and loading game progress by providing serialization utilities.
serializeState(state): Converts the liveStoryStateinto a JSON string for storage.deserializeState(serialized): Reconstructs theStoryStateobject from a JSON string.toGameProgress(state): Maps the internal engine state to theGameProgressinterface used for user profile management.
Sources: packages/story-engine/src/index.ts:117-135, packages/shared-types/src/index.ts:110-116
Summary
The Story Engine Core provides the foundational logic for the MCP Games ecosystem. By abstracting scene navigation and variable management into a standalone, type-safe package, it enables consistent narrative experiences across different platforms. Its state-driven approach allows for complex branching paths and persistent player progress, while its extensible requirement system prepares the project for deep integration with Model Context Protocol (MCP) data sources.
Sources: README.md:83-88, packages/story-engine/README.md:1-5