# 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: ```storybook 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: ```storybook 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: ```storybook // 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: ```storybook 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: ```storybook // 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: ```storybook 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: ```storybook 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: ```storybook 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: ```storybook 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: ```storybook // 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 ```storybook 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 ```storybook 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 ```storybook 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 ```storybook 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 - [Behavior Trees](../reference/11-behavior-trees.md) - Complete behavior syntax - [Characters](../reference/10-characters.md) - Character architecture - [Relationships](../reference/15-relationships.md) - Relationship modeling - [Schedules](../reference/14-schedules.md) - Schedule composition - [Life Arcs](../reference/13-life-arcs.md) - State machine patterns