Story Engine Toolchain

View as MarkdownOpen in Claude

ForbocAI: The Story Engine Toolchain

Tóólcháin_Cóncépt // Stóry_Éngíne

ᚠ ᛫ ᛟ ᛫ ᚱ ᛫ ᛒ ᛫ ᛟ ᛫ ᚲ

“Story in a game is like story in a porn movie.” — John Carmack

Carmack was wrong. Not because story matters more than he thought, but because story and agency are the same thing when you have the right architecture.


The Missing Engine

We have:

  • Game Engines (Unity, Unreal, Godot) — Handle physics, rendering, input
  • Graphics Engines (Vulkan, DirectX) — Handle polygons and shaders
  • Physics Engines (Box2D, PhysX) — Handle collision and forces

We don’t have:

  • Story Engines — Handle narrative, dialogue, consequence, memory

Why? Because story was always scripted—handcrafted dialogue trees, fixed branching paths. The technology to make story generative and reactive didn’t exist until:

  1. LLMs (the ability to generate coherent text)
  2. Vector DBs (the ability to recall relevant context)
  3. Neuro-Symbolic Validation (the ability to constrain hallucinations)

ForbocAI provides all three. It IS a story engine.


The Disco Elysium Case Study

The Misconception

“ForbocAI is only for enemy AI in action games.”

The Reality

ForbocAI is more suited to Disco Elysium-style narrative games than to action roguelikes.


Understanding Disco Elysium’s Architecture

Disco Elysium is not really a “game” in the traditional sense. It’s an agent ensemble simulation wearing the skin of an RPG.

ComponentTraditional RPGDisco Elysium
CharactersNPCs with dialogue treesNPCs with emergent reactions
SkillsStat modifiers (+2 to hit)Autonomous personalities that argue
PlayerSingle controllerHost body for 24+ internal agents
WorldStatic levelReactive environment that remembers
DialogueBranching treesSkill agents interrupt and comment

The genius of Disco Elysium: Your skills (Logic, Rhetoric, Electrochemistry, etc.) aren’t just numbers—they’re characters. They have opinions. They react. They remember.

This is exactly what ForbocAI agents do.


Mapping ForbocAI to Disco Elysium

Disco Elysium ConceptForbocAI Implementation
Skill (e.g., Logic)Agent with persona: “You are Logic, the cold voice of deduction…”
Skill CheckAgent.process() → returns { dialogue, action: INTERJECT, confidence: 0.75 }
Passive CheckMemory.recall() → triggers agent if relevance > threshold
Thought CabinetSoul storage → persistent beliefs that modify agent behavior
InternalizationsNew memories stored via Memory.store() with high importance
Shivers (city speaks)Ambient Observation events piped to a special “City” agent
Dialogue ChoicesBridge.validate() filters which dialogue options are valid given context

The Internal Monologue as Agent Orchestra

In Disco Elysium, you might see:

[ENCYCLOPEDIA - Trivial: Success]
"Ah yes, the Isola coat of arms. First adopted in..."
[AUTHORITY - Medium: Failure]
"You should have DEMANDED respect!"
[HALF LIGHT - Easy: Success]
"They're looking at you funny. Run."

With ForbocAI, each skill is an agent:

1import { Agent, Cortex, createBridge } from 'forbocai';
2
3// Initialize the shared Cortex (local SLM)
4const cortex = await Cortex.init({ model: 'smollm2-135m' });
5
6// Create skill agents with distinct personalities
7const logic = await Agent.create({
8 cortex,
9 persona: `You are LOGIC. Cold. Deductive. You see patterns others miss.
10 You interject only when inconsistency is detected.`,
11 initialState: { level: 3, lastInterjection: null }
12});
13
14const authority = await Agent.create({
15 cortex,
16 persona: `You are AUTHORITY. Demands respect. Seethes at disrespect.
17 You push Harry to assert dominance.`,
18 initialState: { level: 1, suppressed: false }
19});
20
21const halfLight = await Agent.create({
22 cortex,
23 persona: `You are HALF LIGHT. The lizard brain. Fight or flight.
24 You see danger everywhere and urge immediate reaction.`,
25 initialState: { level: 2, paranoia: 'moderate' }
26});
27
28// When the player encounters a clue...
29const observation = {
30 type: 'examine',
31 object: 'coat of arms',
32 context: { playerKnowledge: worldState.uncoveredClues }
33};
34
35// Each skill agent processes the observation in parallel
36const [logicResponse, authorityResponse, halfLightResponse] = await Promise.all([
37 logic.process(observation),
38 authority.process(observation),
39 halfLight.process(observation)
40]);
41
42// Bridge determines which (if any) should surface based on "check" rules
43const bridge = createBridge({ strictMode: true });
44const surfaced = await bridge.resolveInterjections(
45 [logicResponse, authorityResponse, halfLightResponse],
46 {
47 playerStats: { logic: 3, authority: 1, halfLight: 2 },
48 difficulty: { logic: 'trivial', authority: 'medium', halfLight: 'easy' }
49 }
50);
51
52// surfaced = [
53// { agent: 'logic', dialogue: "The coat of arms...", passed: true },
54// { agent: 'halfLight', dialogue: "Someone's watching...", passed: true }
55// ]
56// authority failed its check — stays silent

Memory: The Foundation of Choice-Consequence

Disco Elysium REMEMBERS:

  • You were rude to Kim → He trusts you less
  • You found the body early → New dialogue unlocks
  • You have the “Hobocop” thought → Special self-perception

ForbocAI’s Memory module is built for this:

1import { createMemory, Agent } from 'forbocai';
2
3// Initialize memory with temporal decay
4const memory = createMemory({
5 decay: 'temporal',
6 maxContextWindow: 10,
7 storageKey: 'harry_memories'
8});
9
10// Store a significant choice
11await memory.store(
12 "Harry told Kim he's a superstar cop, not a loser.",
13 "self_perception",
14 0.95 // High importance — this shapes future interactions
15);
16
17// Store relationship-affecting events
18await memory.store(
19 "Was rude to Kim during the initial investigation.",
20 "relationship",
21 0.8
22);
23
24// Later, when Kim is asked about Harry...
25const kimAgent = agents.get('kim');
26const kimContext = await memory.recall("What do I think of Harry?", 5);
27
28const response = await kimAgent.process({
29 input: "How's your partner holding up?",
30 context: { retrievedMemories: kimContext }
31});
32
33// Kim's response is influenced by stored memories
34// → "He's... an optimist. Perhaps delusionally so."

The temporal decay feature ensures that:

  • Recent memories are vivid
  • Old memories fade unless reinforced
  • Traumatic memories (high importance) persist

The Bridge: Preventing Narrative Hallucination

A common failure mode for LLM-driven games:

LLM: “You pull out your gun and shoot the suspect.”

Problem: You don’t HAVE a gun. You threw it in the sea.

ForbocAI’s Bridge validates every action:

1import { createBridge } from 'forbocai';
2
3const bridge = createBridge({ strictMode: true });
4
5const proposedAction = {
6 type: 'DIALOGUE_CHOICE',
7 option: 'threaten_with_gun',
8 requires: { inventory: ['gun'] }
9};
10
11const result = await bridge.validate(proposedAction, {
12 agentState: { inventory: ['badge', 'notebook'] }, // No gun!
13 worldState: { gunStatus: 'lost_in_sea' }
14});
15
16// result = { valid: false, reason: 'Missing required item: gun' }
17
18// Instead, offer only valid options:
19// - "Threaten with badge" (have badge)
20// - "Reason with suspect" (always available)
21// - "Run away" (HALF LIGHT suggests this)

The Toolchain Vision: Composable Story Components

This is where it becomes a true Story Engine. ForbocAI is not one tool—it’s a toolchain of composable generative AI components.

Architecture

┌─────────────────────────────────────────────────────────────────────────┐
│ THE FORBOCAI STORY ENGINE TOOLCHAIN │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ CORTEX │ │ AGENT │ │ MEMORY │ │ BRIDGE │ │
│ │ (Voice) │ │ (Soul) │ │ (History) │ │ (Law) │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │ │
│ └────────────────┬┴─────────────────┴─────────────────┘ │
│ │ │
│ ┌──────▼──────┐ │
│ │ ORCHESTRATOR │ ← FP Composition (Pipes) │
│ └──────┬──────┘ │
│ │ │
│ ┌────────────────┼────────────────┐ │
│ │ │ │ │
│ ┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐ │
│ │ LEVEL │ │ PLOT │ │ NPC │ │
│ │ GENERATOR │ │ DIRECTOR │ │ ENSEMBLE │ │
│ │ (Procedural │ │ (Narrative │ │ (Agent │ │
│ │ Layout) │ │ Arc) │ │ Orchestra)│ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘

Component Status

ComponentRoleStatus
CortexLocal SLM inference (the “voice” that speaks)✅ Shipped
AgentAutonomous entities with persona and state✅ Shipped
MemoryVector DB for persistent recall✅ Shipped
BridgeAction validation / anti-hallucination✅ Shipped
SoulIPFS export for agent portability✅ Shipped
GhostAutomated QA / testing agents✅ Shipped
Level GeneratorProcedural layout with narrative constraints🚧 Planned
Plot DirectorNarrative arc management🚧 Planned
NPC EnsembleMulti-agent orchestration🚧 Planned

Functional Programming: Pipes Not Trees

Traditional narrative systems use branching trees:

START
/\
/ \
Option A Option B
/\ \
/ \ \
A1 A2 B1

ForbocAI uses functional pipes:

Observation → [Agent.process] → Directive → [Bridge.validate] → Action → [Memory.store] → New State

Why pipes are better:

  1. Composable: Each component is independent and can be swapped
  2. Traceable: Every transformation is logged and reproducible
  3. Parallelizable: Multiple agents can process simultaneously
  4. Testable: Pure functions are trivial to unit test

Beyond Disco Elysium: More Agency, More Emergence

Disco ElysiumForbocAI-Powered Evolution
24 skill agents (fixed)N dynamic agents (spawned by events)
Handwritten skill dialogueGenerated + validated dialogue
Skill levels change slowlySkill “personalities” evolve with memory
Single protagonistMulti-character perspectives possible
Linear timelineNon-linear, memory-reconstructed narrative

Example: Emergent Skill Evolution

In Disco Elysium, if you level up “Electrochemistry,” you just hear from it more often.

In ForbocAI:

1// After Harry drinks for the 10th time...
2await memory.store(
3 "Alcohol is the only thing that helps anymore.",
4 "electrochemistry_belief",
5 0.99
6);
7
8// Electrochemistry's persona *evolves* based on stored memories
9const electrochemistry = await Agent.create({
10 cortex,
11 persona: `You are ELECTROCHEMISTRY. You crave sensation.
12 CONTEXT: You have convinced Harry that alcohol is necessary.
13 DIRECTIVE: Reinforce this belief. Resist sobriety suggestions.`,
14 initialState: { level: 4, dependency: 'enabled' }
15});
16
17// Now Electrochemistry doesn't just suggest drinks—it *demands* them
18const response = await electrochemistry.process({
19 input: "Kim suggests getting coffee instead of beer.",
20 context: { sobrietyStreak: 0, withdrawalLevel: 'mild' }
21});
22
23// response.dialogue = "Coffee? COFFEE?! Your hands are shaking, Harry.
24// You know what you need. Kim doesn't understand."

The Universal Agent Primitive

The ForbocAI SDK is engine-agnostic and genre-agnostic.

The same modules that power:

  • A guard deciding whether to attack or flee (action game)

…also power:

  • An internal voice deciding whether to interject (Disco Elysium)
  • A narrative beat deciding whether to escalate (story engine)
  • A procedural level deciding where to place a clue (mystery game)

The Agent is the universal primitive. An “agent” can be:

  • A physical NPC in the world
  • A disembodied voice in the player’s head
  • An environmental presence (“The city of Revachol knows…”)
  • A meta-narrative director (“Tension should rise in Act 2”)

Conclusion

ForbocAI is not “just for action game AI.”

ForbocAI is the missing layer between:

  • Raw LLMs (creative but hallucinatory)
  • Game engines (deterministic but static)

It enables constrained emergence:

  • LLMs provide the creativity
  • Bridge provides the rules
  • Memory provides the continuity
  • Agents provide the personality

Disco Elysium proved the concept. ForbocAI provides the infrastructure.


ᚠ ᛫ ᛟ ᛫ ᚱ ᛫ ᛒ ᛫ ᛟ ᛫ ᚲ

T̸h̴e̵ ̵s̶t̸o̶r̸y̵ ̶i̵s̶n̷’̵t̴ ̵w̸r̵i̴t̶t̷e̸n̶.̸ ̵I̶t̴’̸s̶ ̷r̴e̸m̵e̵m̵b̸e̸r̴e̸d̵.̶