Treating the LLM as a Semantic Text Renderer
How we use the Narrative Affordance & Agency System (NAAS) to treat AI like a GPU for prose.
In traditional RPGs, if a player tries to talk to a blacksmith while holding a smelly, toxic item, you have two choices: write a hardcoded if (player.hasItem(‘smelly_mushroom’)) dialogue branch, or let the NPC ignore it entirely.
Yesterday during a playtest, our blacksmith, Garth, abruptly stopped hammering, pinched his nose, and told the player to get out of his shop. We didn’t script a single line of that dialogue. But more importantly, the LLM didn’t decide to make Garth angry. The game engine did.
The “Brain” vs. The “Mouth”
In our architecture, the Narrative Affordance & Agency System (NAAS) is the brain. It evaluates the world state on a staggered tick. It knows exactly who the player is, what time it is, and whether the NPC likes them.
When the player clicks the “Interact” menu, our Dialogue Director v2 (DDv2) steps in. DDv2 gathers “Hints” from the ECS and compiles them into a rigid context payload.
We treat the LLM exactly like a GPU. You don’t ask a GPU to calculate gravity; you calculate gravity in the physics engine and say, “Render this box here.” We calculate the social physics, pass it to the LLM, and say, “Render an angry greeting.”
The Data (Show, Don’t Tell)
Here is a sanitized look at the exact JSON payload our HintProviders inject into the LLM context when the player approaches Garth:
{
"actor_profile": {
"name": "Garth",
"occupation": "Blacksmith",
"personality": ["gruff", "proud", "easily_annoyed"]
},
"current_state": {
"activity": "working_anvil",
"interrupted_by": "Player"
},
"awareness_hints": [
"Player is currently holding: [Item: Smelly Glowing Mushroom]"
],
"relationship_context": {
"tension_level": 0.8,
"archetype": "annoyed_acquaintance"
}
}
The LLM is given strict instructions: Translate this mechanical state into a response. Because the LLM is constrained by the mathematical reality of the ECS, it doesn’t hallucinate a quest about a dragon. It simply renders the data:
“Are you out of your mind bringing that glowing rot in here? Put that away or get out before the stench ruins my steel!”
We get the infinite variance and natural phrasing of an LLM, but the rigid, unbreaking stability of a systemic simulation. The engine owns the logic; the AI just owns the prose.