Generate living quests
Build objectives, rewards, hooks, and branching outcomes from player and world state—within limits you define.
Narra is a strongly typed TypeScript runtime for dynamic quests, adaptive stories, game-safe NPC decisions, world events, memory, lore, and player-aware narrative systems.
What Narra changes
Narra turns probabilistic provider output into schema-validated, developer-authorized data grounded in player history, world state, lore, and memory.
Only the bounded context needed for the current narrative decision.
Generate. Parse. Validate. Guard.
One provider contract, strict Zod schemas, bounded retries, and deterministic action checks.
{
status: "ready",
type: "quest",
objectives: 4,
authorized: true
}
Typed narrative data returns to your authoritative game server for execution.
Use capable models for narrative variation, character voice, and story possibility.
Validate schemas, enforce limits, and reject actions your game never authorized.
Return typed data to the backend that already owns your rules, state, and execution.
Capabilities
Six focused systems for building responsive narrative without handing authority to a model.
Build objectives, rewards, hooks, and branching outcomes from player and world state—within limits you define.
Validate model output with strict schemas and reject NPC decisions outside your explicit allowedActions.
Carry player history, relationships, lore, and session memory into the next narrative decision.
Create contextual NPC dialogue and decisions without handing execution authority to a model.
Generate bounded world events and narrative consequences grounded in current simulation state.
Use OpenAI, xAI, Gemini, Claude, or a custom adapter behind one strongly typed provider contract.
How it works
A clear server-side boundary between probabilistic generation and deterministic game systems, shown as the code your team actually owns.
Your server supplies player state, world state, established lore, memory, and developer-defined constraints.
const context = {
player: {
id: "player_123",
level: 8,
reputation: { ashguard: 40 },
},
worldState: {
location: "Ashen Port",
weather: "storm",
},
constraints: { maxObjectives: 4 },
};Narra builds one structured request and runs it through OpenAI, xAI, Gemini, Claude, or your own provider adapter.
import { Narra } from "naraworks";
const narra = new Narra({
provider: "openai",
apiKey: process.env.OPENAI_API_KEY!,
timeoutMs: 30_000,
maxRetries: 2,
});
const quest = await narra.quests.generate(context);Strict schemas parse the response while deterministic guardrails enforce objective, item, and allowed-action limits.
const decision = await narra.npc.decide({
npc: captainMara,
context,
allowedActions: [
"offer_quest",
"share_rumor",
"refuse_service",
],
});
// Unsupported actions never reach the game.
assertAllowedAction(decision.action);Narra returns typed data. Your authoritative server decides what becomes dialogue, a quest, a world event, or an action.
if (quest.status === "ready") {
await gameServer.quests.create({
playerId: context.player.id,
title: quest.title,
objectives: quest.objectives,
rewards: quest.rewards,
});
}
// The model proposes. Your server executes.Roadmap 2026—2027
Four focused releases that move Narra from server-side SDK to a collaborative system for adaptive game storytelling.
Jun — Aug 2026
Ship typed quests, narrative, NPC decisions, world events, memory, lore, guardrails, and multi-provider support.
Aug — Sep 2026
Build a visual workspace for testing quests, dialogue, world events, player context, and structured narrative output.
Oct — Dec 2026
Deepen Unity, Godot, Unreal, and web integration patterns with production-ready server examples and adapters.
Jan — Mar 2027
Introduce shared lore governance, narrative observability, event histories, evaluation suites, and team-safe release controls.
Questions worth asking
The practical boundaries teams need before generated narrative becomes part of a live game.