Narrative branching in Lumenfall dev blog cover showing branching story paths over terrain
Back to Dev Blog
narrative AI lumenfall game-design

Story That Grows From Terrain: Narrative Branching in Lumenfall

A pre-authored story assumes a known map. Every branch point, every landmark trigger, every encounter location was placed by a writer who knew what the world looked like. When the terrain generates at runtime, none of those assumptions hold. The story hook system we built for Lumenfall had to work differently: it had to read the world the terrain system made and attach story context to what was actually there.

Why the Fixed Narrative Model Fails on Generative Terrain

We built the first version of Lumenfall's narrative layer the way most games build it. Story triggers were attached to geographic coordinates. Enter this area, the system fires this story event. The logic was simple and the tooling was familiar. It also completely broke the moment we turned on runtime terrain generation.

When terrain generates from a seed, no two runs share the same layout. The highland fortress where the story event was supposed to fire does not exist at the same coordinates. Sometimes a version of it generates somewhere in the world. Usually the trigger fires in a dry plain with no terrain context to give it meaning. Players read the same text over a completely different landscape, and the disconnection is immediately obvious.

The fix was not to make story events more resilient to geographic variation. The fix was to stop authoring story events to specific locations entirely. Story hooks needed to attach to terrain properties, not coordinates.

How Terrain Feature Tagging Works

The terrain grammar assigns feature tags to generated terrain elements as it builds them. A section of cliff face above a threshold height gets tagged as a high-vantage point. A depression surrounded by higher terrain on three sides gets tagged as sheltered. A narrow passage between two elevated formations gets tagged as chokepoint. These tags are semantic labels that the narrative layer can read without knowing anything about the specific geometry that generated them.

The tag vocabulary has about 60 entries in the current build. Some are single-condition: a water body of sufficient size is tagged as significant-water. Some are relational: a cluster of ruins within a specified radius of another cluster creates an adjacency tag that marks the relationship. The relational tags are the ones we find most interesting from a narrative standpoint. They create stories about proximity and history without specifying what the objects were or why they ended up near each other. The narrative layer infers the "why" based on which story archetypes are compatible with that spatial relationship.

Story Archetypes as Terrain Readers

We designed story archetypes as pattern-matching filters. Each archetype has a required feature set and an optional feature set. A required feature must be present in the terrain for the archetype to activate. An optional feature modifies the archetype's behavior if present.

The "contested ground" archetype, for example, requires two or more significant-terrain features within a contiguous region and a chokepoint connecting them. When those conditions exist, the archetype activates and seeds the region with tension-carrying hooks: evidence of past occupation, functional geography that implies conflict, NPCs who reference the history of the region in ways that match its actual layout. The player does not experience a pre-written story. They experience a world that behaves consistently with its physical shape.

Optional features extend the archetype. A water feature near the contested ground shifts the economic framing of the conflict. An abandoned settlement tag introduces historical depth. Each optional feature is a modifier that the narrative system incorporates into the hook text it generates, using a small template grammar. The combination of a fixed archetype trigger with variable modifier features produces a large combinatorial space of story textures from a small authored base.

The Riya Test: Reading Without Knowing the Map

Riya proposed a test early in the narrative layer design that we now use regularly. We call it the Riya test internally: can someone reading the story hooks in a region correctly infer the approximate terrain type without seeing the terrain?

If the narrative layer is working, the story and the world should be mutually reinforcing. A player who reads "the old trade road here runs close to the western cliff because the valley below floods seasonally" should be able to look around and see the cliff, the road, the valley. If the story hook fires in flat open grassland with no cliff in sight, the test fails.

We run this test manually on generated regions every few weeks. We feed story hooks from a generated region to someone who has not seen that region's terrain, ask them to describe what they expect the terrain to look like, then compare. The match rate is not perfect and we are not trying to make it perfect. We are trying to prevent the disconnect from being jarring. The current system passes comfortably. Hook text predicts terrain type with roughly 80 percent accuracy, and terrain type prediction failure almost never produces a serious mismatch, just a missing feature.

Story Branch Depth and the Memory Problem

The branching system records which archetypes have activated in a session and uses that state to modify subsequent activations. If a player has already encountered a contested ground archetype, a later instance in a different region can reference the earlier encounter in its hook text. This creates a basic continuity of narrative texture across the session without requiring full story authoring.

The system does not currently persist between sessions. Each new run starts with a clean narrative state. This is a deliberate choice, not a technical limitation. Lumenfall's identity as a game is built around the premise that each run is its own world. Story continuity across runs would require a persistent player identity system that is not in our current scope. We are also skeptical that inter-run narrative persistence is the right direction for a game where the terrain resets completely. The consistency that matters is within a run, not across runs.

What Still Does Not Work

The long-arc story is the unsolved problem. Terrain feature tagging works well for local and regional narrative hooks. It does not produce a coherent world history or a through-line narrative that spans the full run. Individual regions feel storied. The world as a whole feels episodic rather than unified.

We are not claiming to have solved what games with 100-person narrative teams and pre-built worlds struggle with. We are three people. The honest position is that Lumenfall's narrative model is better suited to ambient discovery than to protagonist-driven story arcs. What the terrain-attached system produces very well is the feeling that the world has history without requiring the player to engage with it on a linear timeline. That is a genuinely different experience from authored open-world narrative, and we are starting to think of it as the feature rather than the limitation.

More from the Dev Blog

All posts
Alpha 04 terrain synthesis blog cover

Alpha 04: Terrain Synthesis Gets Smarter

Read post
Generative character system blog cover

Why We Chose a Generative Character System Over a Pre-Built Roster

Read post
Character trait pool synthesis blog cover

Building Characters From Trait Pools, Not Pre-Written Scripts

Read post