๐ŸŒŒ Inspiration

Text-based RPGs and Multi-User Dungeons (MUDs) represent the gold standard of narrative-driven gaming. By removing the constraints of pre-rendered 3D assets, they leverage the most powerful graphics card in existence: the human imagination.

However, modern attempts to marry these classic genres with Large Language Models (LLMs) invariably run into structural boundaries.

During testing of existing AI game engines, we identified a persistent architectural flaw: Context Window State Decay. Traditional conversational applications treat game loops as open-ended chats. Over multiple turns, crucial contextual anchorsโ€”such as precise inventory counts, status modifiers, and positional coordinatesโ€”drift away into the model's context window. The game master begins to hallucinate, forgetting that a player consumed their last health potion or stepped into an adjacent dungeon three turns ago.

Furthermore, developers attempting to force structural integrity onto LLMs typically rely on JSON mode outputs. While this approach works well for standard REST API requests, it is inherently incompatible with continuous streaming. If an LLM reaches its token limit or experiences a network interruption mid-response, the trailing JSON becomes malformed, causing immediate parsing failures and runtime exceptions.

We were inspired to design an architecture that bridges these gaps. We wanted to build a dark fantasy simulator where descriptive prose flows naturally while inventories, coordinates, and progression systems remain deterministic and engineering-grade reliable.


๐Ÿ”ฎ What It Does

Lore and Abyss is an infinite, persistent dark fantasy text roguelike powered by a real-time streaming pipeline. Instead of relying on a human Game Master or branching dialogue trees, the game uses an AI-driven engine responsible for narrative generation, state management, and persistence.

[ PLAYER VIEWPORT INTERFACE ]
โ”œโ”€โ”€ Dynamic Live Narrative Timeline
โ”œโ”€โ”€ Character Status Dashboard
โ””โ”€โ”€ Adaptive Ambient Audio System

1. Dual-Stream Token Separation Engine

When a player submits an action, the AI streams its response in real time. The frontend continuously reads incoming chunks and separates narrative prose from structured metadata.

  • Narrative is rendered immediately.
  • Backend metadata updates inventory, stats, choices, and world state without interrupting the stream.

2. Tension-Reactive Audio System

The game continuously updates a tensionScore with every turn.

This value dynamically adjusts the ambient soundtrack, increasing or decreasing intensity based on how dangerous the current situation becomes, creating an immersive atmosphere that evolves alongside the story.

3. Structural Journaling & Session Export

Because every narrative event is stored sequentially, players can export their complete adventure into a clean Markdown document with a single click.


๐Ÿ› ๏ธ How We Built It

The application is built with:

  • Next.js 15 (App Router)
  • React 19
  • TypeScript (Strict Mode)
  • Tailwind CSS
  • Amazon DynamoDB
  • Google Gemini API

Overall Architecture

+-------------------+        Streaming        +---------------------------+
|    NemoTron 3     | ---------------------> | Dual Stream Parser Engine |
+-------------------+                        +-------------+-------------+
                                                          |
                            +-----------------------------+-----------------------------+
                            |                                                           |
                            v                                                           v
                  Narrative Rendering                                        Structured Metadata
                            |                                                           |
                            v                                                           v
                 React UI Timeline                                         DynamoDB State Updates

Amazon DynamoDB State Layer

Instead of using a relational database, the game stores all sessions in Amazon DynamoDB using a single-table design.

Each active sessionId serves as the partition key.

Rather than rewriting the complete game history every turn, only small state deltas are updated, including:

  • Player HP
  • Inventory
  • Current location
  • Active NPCs
  • Tension score

This minimizes latency while keeping the entire world synchronized.


Streaming Protocol

The /api/turn endpoint streams Gemini responses.

Each response contains two sections separated by a delimiter:

||METADATA_SPLIT||

The first section contains the narrative.

The second contains structured JSON:

{
  "choices": [
    "Force the iron gate",
    "Retreat into the shadows"
  ],
  "worldState": {
    "hp": 9,
    "maxHp": 12,
    "tensionScore": 75
  }
}

The frontend streams the prose immediately while safely parsing the metadata once the delimiter arrives.


๐ŸŽต Dynamic Audio Engine

Instead of static sound effects, the game generates an adaptive soundtrack that changes with gameplay.

The audio system reacts to the current tensionScore, making the atmosphere increasingly intense as danger rises.

Conceptually, the audio pipeline looks like this:

Audio Source
      โ”‚
      โ–ผ
 Ambient Processing
      โ”‚
      โ–ผ
 Volume & Intensity Scaling
      โ”‚
      โ–ผ
 Browser Audio Output

๐Ÿšจ Challenges We Ran Into

1. Truncated Streaming Responses

Streaming AI responses can terminate before the JSON metadata is fully transmitted.

For example:

{
  "worldState": {
    "hp": 12,
    "inventory": [
      "Iron Sword",
      "Leat

Attempting to parse incomplete JSON immediately crashes the client.

We solved this by delaying metadata parsing until the complete delimiter section is received.


2. DynamoDB Latency

Initially, every turn loaded the entire game history before generating the next response.

As sessions became longer, this noticeably delayed streaming.

Moving to a state-delta architecture dramatically reduced response times.


๐Ÿ† Accomplishments We're Proud Of

Robust Streaming Parser

We successfully built a parser capable of separating streamed narrative from structured metadata without interrupting the player's reading experience.


Dynamic Audio

The game features an adaptive ambient soundtrack whose intensity evolves alongside the game's tension, making every encounter feel more immersive.


Optimized State Pipeline

By storing only incremental changes in DynamoDB, we significantly reduced database operations and improved responsiveness during gameplay.


๐Ÿง  What We Learned

Building streaming AI applications requires treating structured state separately from natural language.

Rather than asking the LLM to regenerate the entire world every turn, sending only the immediate state delta greatly improves reliability, reduces latency, and simplifies parsing.

We also learned how much adaptive audio contributes to immersion in a text-based experience.


๐Ÿš€ What's Next

Multiplayer Campaigns

Allow multiple players to participate in the same persistent world with shared inventories and synchronized progression.


Procedural Dungeon Maps

Generate live dungeon layouts from location metadata using the HTML5 Canvas API.


Dice-Based Combat

Introduce deterministic combat resolution using traditional RPG dice mechanics before sending combat outcomes to the AI narrator.

Built With

Share this project:

Updates