Files
storybook/docs/advanced/20-patterns.md
Sienna Meridian Satterwhite 16deb5d237 release: Storybook v0.2.0 - Major syntax and features update
BREAKING CHANGES:
- Relationship syntax now requires blocks for all participants
- Removed self/other perspective blocks from relationships
- Replaced 'guard' keyword with 'if' for behavior tree decorators

Language Features:
- Add tree-sitter grammar with improved if/condition disambiguation
- Add comprehensive tutorial and reference documentation
- Add SBIR v0.2.0 binary format specification
- Add resource linking system for behaviors and schedules
- Add year-long schedule patterns (day, season, recurrence)
- Add behavior tree enhancements (named nodes, decorators)

Documentation:
- Complete tutorial series (9 chapters) with baker family examples
- Complete reference documentation for all language features
- SBIR v0.2.0 specification with binary format details
- Added locations and institutions documentation

Examples:
- Convert all examples to baker family scenario
- Add comprehensive working examples

Tooling:
- Zed extension with LSP integration
- Tree-sitter grammar for syntax highlighting
- Build scripts and development tools

Version Updates:
- Main package: 0.1.0 → 0.2.0
- Tree-sitter grammar: 0.1.0 → 0.2.0
- Zed extension: 0.1.0 → 0.2.0
- Storybook editor: 0.1.0 → 0.2.0
2026-02-13 21:52:03 +00:00

9.2 KiB

Design Patterns

This chapter presents proven patterns for structuring Storybook projects. These patterns have emerged from building complex narrative simulations and represent best practices for maintainability, reuse, and clarity.

Behavior Tree Patterns

Priority Fallback Chain

Use a selector to try increasingly desperate options:

behavior Survival {
    choose survival_priority {
        then optimal {
            if(health > 70 and has_supplies)
            ProceedNormally
        }

        then cautious {
            if(health > 30)
            ProceedCarefully
        }

        then desperate {
            if(health > 10)
            SeekHelp
        }

        LastResortPanic
    }
}

The tree naturally degrades: first tries the best option, then falls back through progressively worse alternatives.

Conditional Behavior Switching

Use guards at the top level to switch between behavioral modes:

behavior ModeSwitcher {
    choose mode {
        if(is_combat_mode) {
            include CombatBehavior
        }

        if(is_exploration_mode) {
            include ExplorationBehavior
        }

        if(is_social_mode) {
            include SocialBehavior
        }

        include IdleBehavior
    }
}

Composite Subtree Pattern

Break complex behaviors into focused, reusable subtrees:

// Atomic subtrees
behavior Navigate { then nav { PlanPath, FollowPath } }
behavior Interact { then talk { Approach, Greet, Converse } }
behavior Trade { then exchange { ShowGoods, Negotiate, Exchange } }

// Composed behavior
behavior Merchant_AI {
    choose activity {
        then serve_customer {
            if(customer_present)
            include Interact
            include Trade
        }

        then travel_to_market {
            if(is_market_day)
            include Navigate
        }

        Idle
    }
}

Repeating Patrol with Interrupts

Use a repeating patrol that can be interrupted by higher-priority events:

character Guard {
    uses behaviors: [
        {
            tree: GuardCombat
            when: threat_detected
            priority: high
        },
        {
            tree: GuardPatrol
            priority: normal
        }
    ]
}

behavior GuardPatrol {
    repeat {
        then patrol_loop {
            MoveTo(destination: "Waypoint1")
            WaitAndScan(duration: 5s)
            MoveTo(destination: "Waypoint2")
            WaitAndScan(duration: 5s)
        }
    }
}

The combat behavior preempts patrol when threats appear, then patrol resumes.

Character Architecture Patterns

Species + Templates Composition

Use species for identity and templates for capabilities:

// Species: What they ARE
species Human { lifespan: 70 }
species Elf { lifespan: 1000 }

// Templates: What they HAVE
template Warrior { strength: 10..20, weapon_skill: 0.5..1.0 }
template Scholar { intelligence: 15..20, books_read: 50..500 }
template Leader { charisma: 12..18, followers: 5..50 }

// Characters: Combine both
character Aragorn: Human from Warrior, Leader {
    strength: 18
    charisma: 17
}

character Elrond: Elf from Scholar, Leader {
    intelligence: 20
    charisma: 18
}

Strict Templates for Schema Enforcement

Use strict templates when you need controlled, uniform entities:

template RecipeCard strict {
    recipe_name: string
    difficulty: Difficulty
    prep_time_minutes: 10..180
}

// This works:
character SourdoughRecipe from RecipeCard {
    recipe_name: "Classic Sourdough"
    difficulty: intermediate
    prep_time_minutes: 120
}

// This would error (extra field not allowed):
// character BadRecipe from RecipeCard {
//     recipe_name: "Mystery Bread"
//     difficulty: easy
//     favorite_color: "blue"  // Error!
// }

Template Inheritance Chains

Build template hierarchies for progressive specialization:

template Worker {
    skill_level: 0.0..1.0
    wage: 10..50
}

template SkilledWorker {
    include Worker
    specialization: "general"
    tool_proficiency: 0.5..1.0
}

template MasterCraftsman {
    include SkilledWorker
    can_teach: true
    reputation: 0.7..1.0
}

Relationship Patterns

Bidirectional Perspective

Model relationships where each side sees things differently:

relationship MentorApprentice {
    Master as mentor self {
        patience: 0.7
        investment_in_student: 0.9
    } other {
        sees_potential: 0.8
        frustration_level: 0.3
    }

    Student as apprentice self {
        dedication: 0.8
        overwhelmed: 0.4
    } other {
        respect: 0.95
        desire_to_impress: 0.9
    }

    bond: 0.75
    years_together: 3
}

Power Dynamic Pattern

Model unequal power relationships explicitly:

relationship Vassalage {
    King as lord self {
        authority: 1.0
        grants: "protection"
    } other {
        trusts_vassal: 0.6
    }

    Knight as vassal self {
        loyalty: 0.9
        ambition: 0.4
    } other {
        respects_lord: 0.8
        fears_lord: 0.3
    }

    bond: 0.7
}

Relationship Network

Build social graphs with multiple overlapping relationships:

// Family
relationship BakerMarriage { Martha as spouse, David as spouse, bond: 0.9 }
relationship BakerParenting { Martha as parent, Tommy as child, bond: 0.95 }

// Professional
relationship BakerEmployment { Martha as employer, Elena as employee, bond: 0.8 }
relationship GuildMembership { Martha as member, BakersGuild as org }

// Social
relationship BakerFriendship { Martha, Neighbor, bond: 0.6 }

Schedule Patterns

Base Schedule with Specializations

schedule BaseWorker {
    block work { 09:00 - 17:00, action: work::standard }
    block lunch { 12:00 - 13:00, action: social::lunch }
}

schedule EarlyBird extends BaseWorker {
    block work { 05:00 - 13:00, action: work::early_shift }
    block lunch { 11:00 - 12:00, action: social::lunch }
}

schedule NightOwl extends BaseWorker {
    block work { 14:00 - 22:00, action: work::late_shift }
    block lunch { 18:00 - 19:00, action: social::dinner }
}

Seasonal Variation

schedule FarmSchedule {
    block spring_work {
        06:00 - 18:00
        action: farming::plant
        on season spring
    }

    block summer_work {
        05:00 - 20:00
        action: farming::tend
        on season summer
    }

    block fall_work {
        06:00 - 20:00
        action: farming::harvest
        on season fall
    }

    block winter_work {
        08:00 - 16:00
        action: farming::maintain
        on season winter
    }
}

Life Arc Patterns

Progressive Development

life_arc CareerProgression {
    state novice {
        on enter { Character.title: "Apprentice" }
        on experience > 100 -> intermediate
    }

    state intermediate {
        on enter { Character.title: "Journeyman" }
        on experience > 500 -> expert
    }

    state expert {
        on enter { Character.title: "Master", Character.can_teach: true }
    }
}

Emotional State Machine

life_arc MoodSystem {
    state neutral {
        on provoked -> angry
        on complimented -> happy
        on tired -> sleepy
    }

    state angry {
        on enter { Character.aggression: 0.9 }
        on calmed_down -> neutral
        on escalated -> furious
    }

    state furious {
        on enter { Character.aggression: 1.0 }
        on timeout_elapsed -> angry
    }

    state happy {
        on enter { Character.gives_discounts: true }
        on insulted -> neutral
    }

    state sleepy {
        on enter { Character.responsiveness: 0.2 }
        on woke_up -> neutral
    }
}

Project Organization Patterns

Schema / World Separation

Keep type definitions separate from instance data:

my-project/
  schema/           # Types and templates (reusable)
    core_enums.sb
    templates.sb
    beings.sb
  world/            # Instances (specific to this story)
    characters/
    behaviors/
    relationships/
    locations/

Module per Domain

Group related declarations together:

world/
  characters/
    heroes.sb       # All hero characters
    villains.sb     # All villain characters
    npcs.sb         # Background characters
  behaviors/
    combat.sb       # Combat behaviors
    social.sb       # Social behaviors
    exploration.sb  # Exploration behaviors

Anti-Patterns to Avoid

Deep nesting: More than 4-5 levels of behavior tree nesting is hard to read. Use include to flatten.

God behaviors: One massive behavior tree doing everything. Break it into focused subtrees.

Deep species hierarchies: More than 2-3 levels of species includes is rarely needed. Use templates for variation.

Duplicated logic: If two behaviors share logic, extract it into a shared subtree.

Unnamed nodes: Always label composite nodes in behavior trees for readability.

Cross-References