Story Forge — Nonlinear Narrative Game

A three-day hackathon game in which AI-driven characters respond to free-form player actions while a dependency tree keeps the story coherent.

Technologies Used

Narrative SystemsReactTypeScriptWebSocketsLLMDocker
⋮⋮

Table of Contents

Why we made it

When I first heard the idea, I wanted to build it immediately. Most narrative games offer branches, but the important events and their meaning are still decided in advance. We wondered whether players could act more freely while the game preserved enough structure to reach a deliberate ending.

Our team built Story Forge in three days for a hackathon and won first prize in the software-development track. The first playable stories were written in Chinese, which was also the audience for the original deployment.

Narrative model

Story Forge separates the story’s fixed conditions from the language used to present them. A dependency tree records prerequisites, active events, and terminal conditions. The player can enter an action in natural language, but an arbiter checks that action against the current world state before the narrator continues.

This structure let us keep a shared destination without forcing every player through the same sequence. Two sessions may reach the same ending with very different histories, so the ending carries different context for each player.

Application architecture

The frontend is written in React and TypeScript. It includes the main scene, a command interface, action controls, and a tree view for the path already taken. WebSockets carry player actions and streamed narrative updates because a generated response arrives over time rather than as one short API payload.

The backend is split into an engine and several roles: an arbiter validates actions, a narrator writes the next scene, and a reality agent updates the state of the world. Story definitions use YAML for the world and condition tree, while JSON is the boundary between model output and application code. The application was containerized with Docker for deployment.

The hard parts

Model output had to be imaginative enough to feel responsive and structured enough for the engine to parse. We built a prompt layer that requested a strict JSON shape, then added validation and error handling instead of assuming every response would be usable.

Session isolation was equally important. Each browser and each saved game needed its own state; otherwise, one player’s generated events could leak into another story. We also used streaming and lazy loading to hide some of the latency from third-party model calls.

To move quickly without tangling everything together, we developed the tree renderer separately and proved a minimal frontend-to-backend WebSocket exchange before building the full interface. That decision saved time during integration.

Status

The hackathon deployment and source are no longer public. Story Forge remains a prototype, but it changed how I think about AI in games: the model is most useful inside explicit rules, state transitions, and recovery paths—not as a replacement for the game engine.