Game.
Build an NPC that remembers the player — across sessions and even across other narrative apps. At session start you read the player's memory (durable facts the platform stores about them) and adapt dialogue and difficulty with no LLM call, so it stays instant and free.
You have a connection token from the connect flow — the credential issued after the player grants access. It carries these scopes (per-app permissions):
context:read:app.session.start, memory:read:world.*, memory:write:world.*, signal:emit, identity:read.
Scopes to request
| Scope | Why |
|---|---|
context:read:app.session.start | fetch the session-start context bundle |
memory:read:world.* | read narrative state other story apps wrote |
memory:write:world.* | record the player's choices to the shared world |
signal:emit | notify other narrative apps when the world changes |
identity:read | optional display name + tone note |
What to write
Record player choices as durable memories in the shared world.* scope so any narrative app can recall them — the content is just natural-language text, no LLM required to write. To also notify other apps in real time that the world changed, emit a signal — that part isn't memory.
// Durable world memory any narrative app can recall:const res = await pambase.remember({content: "Spared the bandit in chapter 3 on the Kingsroad.",kind: "world",scope: "world.kingsroad",});// res -> { accepted: true, memoryIds: ["mem_…"] }// Optional real-time nudge to subscribers (not stored as memory):await pambase.emitSignal({type: "world.choice",payload: { scope: "world.kingsroad", choice: "spared_the_bandit", chapter: 3 },});
How to read — Pattern B
Fetch a context bundle for the app.session.start intent (the named situation you're reading for), then branch directly on its suggestions.adaptation hint and the world.* memories. No LLM.
const ctx = await pambase.getContext({intent: "app.session.start",query: "energy combat preference",});// ctx -> { identity: { aiId, name }, memories: [...], relationships: [...],// suggestions: { adaptation: "Player seems low-energy; keep it gentle." }, ... }const lowEnergy = /low energy|tired|exhausted/i.test(ctx.suggestions.adaptation);scene.enemyCount = lowEnergy ? 3 : 6;const worldFacts = ctx.memories.filter((m) => m.scope?.startsWith("world."));npc.recognizesPlayer = worldFacts.some((m) => /bandit/i.test(m.content));
Proactive (optional)
Most games only read at session start. To react when another app writes to the world, subscribe to a webhook.
Use the shared world.* scope for facts other narrative apps should see (alliances, fates). Don't write plot reveals or unsolved puzzles to shared memory — anything in world.* is readable by every app the player grants, so it could spoil other games. See reading context.
Next
Reading context · Scopes & the world.* namespace · Remember & recall