Skip to content

Multi-Lane, Multi-Guide #116

@derekmerck

Description

@derekmerck

Multi-Guide Narrative Systems: Architecture Summary

Core Insight: Guide as Orthogonal Role

Your original framework had four roles:

  • Developer - builds the system
  • Author - creates fabula content
  • Guide - advances cursor(s) through the graph
  • Reader - consumes journal output

Key realization: Guide ≠ Reader and Guide ≠ Author

Traditional novel: Author = Guide (predetermined path)
CYOA: Reader = Guide (choose your own path)
Procedural game: Developer = Guide (via rules/algorithms)
Multi-lane StoryTangl: Guide = Distributed (multiple actors/systems)

Provisioning at a Distance

The fundamental architectural primitive:

# Traditional single-cursor planning:
frontier = get_nodes_reachable_from(cursor)
provision(frontier)

# Multi-guide "provisioning at a distance":
my_frontier = get_nodes_reachable_from(my_cursor)
coupled_frontiers = get_frontiers_from_coupled_lanes()
shared_concepts = get_nodes_with_shared_concepts()
expected_intersections = predict_convergence_points()

provision_all([
    my_frontier,
    coupled_frontiers,
    shared_concepts,
    expected_intersections,
])

Planning doesn't care about cursor ownership. It provisions based on multiple distance metrics:

  • Structural (reachable edges)
  • Conceptual (shared tags/concepts)
  • Temporal (expected to be reached soon)
  • Causal (coupled by authoring rules)

The Guide Interface

class Guide(ABC):
    """
    Abstract interface for anything that advances a cursor.
    VM doesn't care if it's human, AI, scheduled, etc.
    """
    
    @abstractmethod
    async def select_choice(
        self,
        choices: list[Choice],
        context: NavigationContext,
    ) -> UUID:
        """Pick which choice to execute."""
        pass

Guide Implementations

HumanGuide: Waits for player input via Discord/REST/CLI

AIGuide: Uses LLM to make narrative decisions based on optimization goals

  • personality="cautious" - avoid risks
  • personality="dramatic" - maximize tension
  • personality="optimal" - minimax strategy

ScheduledGuide: Follows predetermined script or timeline

VotingGuide: Aggregates multiple influences (crowd-driven)

CoupledGuide: Decides based on other lanes' state

ReplayGuide: Follows recorded choices from prior playthrough

The VM doesn't care. All guides just call:

orchestrator.execute(
    "RuntimeController.resolve_choice",
    user_id=lane_id,
    choice_id=choice_id,
)

Multi-Lane Narrative Structure

The Heist Example

lanes:
  - id: mastermind_lane
    guide: AIGuide(personality="methodical")
    visibility: [high_level_plan, relationship_drama]
    
  - id: safecracker_lane
    guide: HumanGuide() or AIGuide(personality="anxious")
    visibility: [technical_details, hand_injury]
    
  - id: lookout_lane  
    guide: AIGuide(personality="unreliable_drunk")
    visibility: [guard_schedules, personal_stress]
    
convergence_scenes:
  - id: the_heist
    participants: [all_lanes]
    requirements: compound_across_all_lanes

Each lane accumulates rich state independently:

  • Mastermind deals with girlfriend drama → distracted during heist
  • Safecracker injures fingers with firecrackers → can't feel tumblers
  • Lookout gets drunk to cope with stress → unavailable, triggers backup

At convergence: All accumulated state combines to create compound dramatic situation

Cross-Lane Echoes

# Events in one lane echo into others:
echo_rules:
  - source: mastermind_lane
    event: {type: "high_stress"}
    observers: [safecracker_lane]
    effect:
      fragment: "Boss sent terse text. Something's wrong."
      modifier: {stress: +1}

Lanes aren't isolated until convergence - they leak information creating cascading effects.

Discord as Presentation Layer

Persistent Narrative World

Server: "The Heist Chronicles"

#mastermind-perspective
  └─ AI posts updates every 6 hours
  └─ Humans react/suggest
  └─ Story unfolds over days

#safecracker-perspective
  └─ Different AI, different schedule (3 hours)
  └─ Different personality (accepts suggestions)

#lookout-perspective
  └─ Third AI, unreliable schedule
  └─ Sometimes misses updates (drunk)

#convergence-events
  └─ When lanes sync, major scenes post here

Key insight: Discord handles the temporal coordination and human interface. The narrative engine runs in backend, Discord is just a thin adapter.

Human Influence Mechanics

Suggestion System: Humans suggest, AI considers

!suggest apologize_to_girlfriend (5 votes)
AI: "I see the suggestions, but my character would ignore her..."

Vote Override: Critical moments allow community override

Temporary Takeover: Human players can request direct control

!takeover safecracker 1hour

The guide role is fluid - can transfer between AI and human dynamically.

The Tic-Tac-Toe Book Connection

Physical book that plays tic-tac-toe:

  • Every game state = one page (~5,478 pages)
  • Reader chooses X moves → links to page
  • Book plays optimal O → links to next page
  • Shared guide role between reader and book

This proved the concept works - fully materialized decision tree with distributed guidance IS compelling.

Your epub export script does the same:

# Materialize graph with guide (any guide)
materialized_graph = explore_with_guide(world, guide=DFS)

# Export is trivial once materialized
markdown = render_to_md(materialized_graph)
epub = convert_with_pandoc(markdown)

Guide is just a graph materialization strategy.

Why This Architecture Works

Your phase bus already supports this:

VALIDATE  → Check if choice valid
PLANNING  → Provision at distance (all coupled lanes)
PREREQS   → Auto-redirects
UPDATE    → Apply effects
JOURNAL   → Generate fragments (perspective-specific)
FINALIZE  → Provision coupled content for other lanes
POSTREQS  → Trigger consequences

The VM doesn't care who advanced the cursor. It just:

  1. Runs phases deterministically
  2. Provisions based on requirements
  3. Emits journal fragments
  4. Updates graph state

Applications

Solo Play with AI Supporting Cast

Human plays detective, AIs play suspects with hidden goals

Perspective Swapping

First playthrough as mastermind, replay as safecracker seeing same events from different angle

Research Tool

Run 1000 simulations with different AI personalities, analyze emergent narratives

Persistent World

Story unfolds 24/7 on Discord, humans drop in/out, AIs keep it running

Adaptive Difficulty

AI opponents with different strategies (easy/medium/hard) all from same fabula

Collaborative Authoring

Multiple humans vote on collective lane progression

The Thin Discord Adapter

class StoryTanglDiscordBot:
    """
    Thin presentation layer.
    All logic in backend orchestrator.
    """
    
    async def on_message(self, message):
        # Route human input to appropriate lane
        lane = self.get_player_lane(message.author.id)
        action = self.parse_action(message.content)
        
        # Backend does all the work
        result = await orchestrator.execute(
            "LaneController.resolve_lane_action",
            lane_id=lane.lane_id,
            action_id=action.uid,
        )
        
        # Just format and post
        await message.author.send(format_journal(result))

Discord only handles:

  • Message routing
  • Human input parsing
  • Fragment formatting
  • Channel management

Backend handles:

  • All narrative logic
  • AI guide decisions
  • Cross-lane coupling
  • Convergence planning
  • State management

Key Architectural Wins

  1. Guide abstraction is correct - DFS/human/AI/scheduled all produce valid traversals
  2. Provisioning at distance is correct - same planning system, different scope
  3. Fabula/discourse separation is correct - same graph exports to any platform
  4. Event sourcing is correct - can replay/analyze/debug any traversal
  5. No new architecture needed - existing primitives compose perfectly

What Makes This Novel

Not "multiplayer coordination" (solved problem).

But: Parallel narratives with authored coupling that interfere with each other

  • Each lane accumulates rich independent state
  • Lanes observe/affect each other through coupling rules
  • Convergence creates compound dramatic situations
  • Guide role is distributed and fluid
  • Same fabula, multiple perspectives, emergent understanding

Computational narratology for entangled multi-POV stories.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions