All posts

The NPC Who Did Not Exist Yet

A story branch pointed at an entity that had never been authored

4 min read
scenario-design
game-systems
architecture
playtesting

Midnight Cargo has a branching decision in Act 2. The player can help a desperate mother, negotiate a compromise, or refuse entirely. Two of those branches lead to a cure path in Act 4 where the player needs to find a reclusive herbalist named Hildegard Farrow.

Hildegard did not exist anywhere in the game.

Where the Gap Was

The scenario had six acts with authored objectives, NPCs, and scene direction. Act 2 had the branching decision. Act 4 had an objective requiring interaction with a healer. But between Act 2 and Act 4, nothing connected the choice to the healer. No system registered the NPC. No system made her available as an entity the game could track.

If the player chose the cure path, the narrative system would need to introduce someone who existed only as an idea in the scenario outline. It would invent a name, a description, a role, a location. Then the progression system would need to detect that the player had interacted with this invented character and advance the objective.

That is the same category of problem as letting the AI calculate damage. A progress-bearing entity invented in prose is a game-state decision dressed as narrative.

The Wrong Layer

My first instinct was to pre-populate the NPC in the active roster at campaign creation. But Hildegard should not exist in Act 1. She is not part of the dock scenario. She appears because of a decision the player has not made yet. Putting her in the roster at the start means she is visible to systems that should not know about her.

The right place was the branch itself. When the player chooses to help Mira, that choice should carry its consequences with it: NPCs to register, keywords to merge into future objectives, scene direction to inject. The branch is not just a flag. It is a package of downstream content that activates when the flag fires.

The Second Bug

Building the consequence system was straightforward. The harder problem was underneath it. Multiple systems in the engine need to agree on whether an NPC is present in a scene. The system that detected NPC appearances matched differently from the system that checked progression. One matched loosely. The other matched strictly. An NPC could register as present in one system and invisible in the other.

I fixed the first system. The second still used the old matching. The coupling did not leave. It moved. The same inconsistency appeared at three layers. Each fix pushed it down to the next system that still disagreed about how to identify an NPC. The bug was not deep. It was recursive. It stopped surfacing only when every system in the chain agreed on what counted as the same character.

What It Means for the Next Module

Every module with a foreseeable branch that leads to an objective needs authored entities on the path between them. If the trace from branch decision to objective completion passes through a node with no authored entity, the AI fills that gap. It invents a character who serves the plot. That character has no mechanical presence. The progression system cannot track what it does not know exists.

Midnight Cargo is one case. The working hypothesis is that tracing from branch to objective before authoring catches this class of problem. The next module tests whether that discipline generalizes or whether Midnight Cargo was specific. Either way, the branch consequence system is in place. Future branches carry their content with them.