Moonborn — Developers
Interactive fiction prototyping
Stand up a playable prototype with three NPCs in an afternoon. Wire Moonborn into a minimal CLI or web shell; iterate on writing before committing to an engine.
You don't need a game engine to test whether a cast holds together. A CLI + the chat API is enough for the writing iteration.
The minimum
import Moonborn from '@moonborn/sdk';
import readline from 'node:readline';
const client = new Moonborn({ apiKey: process.env.MOONBORN_API_KEY });
// 1. Pull or create three personas + relationships.
const [merchant, traveler, tavern] = await loadCast();
// 2. Open one shared session.
const session = await client.chat.createSession({
personaId: tavern.id,
ensemble: [merchant.id, traveler.id],
metadata: { sceneId: 'tavern_prototype' },
});
// 3. Loop.
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
function prompt(): void {
rl.question('You > ', async (text) => {
if (text.trim() === ':quit') return rl.close();
// Author picks the speaker by name prefix:
// "merchant: We don't serve outsiders." → merchant says this line.
// "what just happened?" → narrator-mode, pick whoever fits.
const [tag, ...rest] = text.split(':');
const speakerName = rest.length > 0 ? tag.trim() : 'narrator';
const content = rest.length > 0 ? rest.join(':').trim() : text;
const speaker = matchSpeaker(speakerName) ?? tavern;
const reply = await client.chat.sendMessage({
sessionId: session.id,
speaker: speaker.id,
content,
});
console.log(`${speaker.surface.name.display} > ${reply.content}`);
if (reply.driftAlert) console.warn(' (drift)');
prompt();
});
}
prompt();What you get
- Writing iteration in minutes, not weeks.
- Drift scores per turn — see which character starts slipping when the scene heats up.
- Long-term memory persists across runs — your prototype can have callbacks.
What you lose vs a real engine
- Player UI (just CLI text).
- Branching scene state (you script linearly).
- Save / load beyond the session ID.
Graduating to a real engine
When the cast holds together in the CLI, the session IDs port unchanged into your engine of choice — Unity, Godot, Twine, custom. The Moonborn side doesn't care which UI hosts the conversation.