Files
storybook/docs/examples/27-multi-character.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

14 KiB

Multi-Character Interactions

This example models a complex social scene: a busy Saturday morning at Martha's bakery. Multiple characters interact simultaneously with interlocking behaviors, relationships, and a shared location buzzing with activity.

The Setting

enum RushLevel { calm, busy, hectic, overwhelming }
enum ServiceMode { normal, rush, emergency }

location BakeryStorefront {
    rush_level: busy
    current_time: 07:30
    customers_waiting: 8
    display_items_remaining: 45
    oven_batches_in_progress: 3
    coffee_machine_running: true

    ---description
    Saturday morning at Martha's bakery. The line stretches out
    the door. The display case gleams with fresh bread, pastries,
    and Elena's famous rosemary olive rolls. The air is warm with
    the smell of baking and the hum of conversation.
    ---

    ---atmosphere
    This is the bakery at its best and most stressful. Every
    Saturday brings the regulars, the farmers' market overflow,
    and tourists who heard about Martha's sourdough. The whole
    team works in concert to keep up.
    ---
}

institution SaturdayMorningCrew {
    type: work_team
    purpose: serve_customers_and_bake
    members: 4
    coordination_level: 0.9

    ---description
    The Saturday crew operates like a well-oiled machine. Martha
    runs the kitchen, Jane handles pastries, Elena manages the
    front counter, and Gregory -- the loyal regular -- unofficially
    helps direct the line.
    ---
}

The Characters

use schema::core_enums::{SkillLevel, Confidence, Specialty};
use schema::templates::{Baker, BusinessOwner, Apprentice};
use schema::beings::Human;

character Martha: Human from Baker, BusinessOwner {
    age: 34
    specialty: sourdough
    skill_level: master
    confidence: commanding
    energy: 0.8
    stress_level: 0.4
    loaves_baked_today: 24
    orders_pending: 6

    ---personality
    Calm under pressure. Martha thrives on Saturday mornings --
    the rush brings out her best. She coordinates the team with
    quiet efficiency, stepping in wherever needed while keeping
    the ovens running on schedule.
    ---
}

character Jane: Human from Baker {
    age: 36
    specialty: pastries
    skill_level: expert
    confidence: confident
    energy: 0.9
    creative_mode: true
    pastries_decorated_today: 18

    ---personality
    Jane works in focused silence during the rush. Her hands
    move with precision, piping decorations and assembling
    layered pastries. She communicates with Martha through
    glances and nods -- years of partnership have made words
    unnecessary.
    ---
}

character Elena: Human from Apprentice {
    age: 17
    skill_level: intermediate
    confidence: growing
    energy: 1.0
    customers_served_today: 32
    mistakes_today: 1

    ---personality
    Elena has grown into the front-counter role. She remembers
    regulars' names and orders, handles complaints with grace,
    and only calls Martha when truly stuck. The nervous girl
    who started a year ago is barely recognizable.
    ---
}

character Gregory: Human {
    age: 68
    role: "regular_customer"
    visits_today: 1
    helping_with_line: true
    knows_everyone: true

    ---personality
    Gregory arrives at exactly 7:15 every Saturday. He buys
    his sourdough loaf, then lingers near the door, chatting
    with other customers and unofficially managing the line.
    He considers this his contribution to the bakery.
    ---
}

Interlocking Behaviors

Martha's Behavior

behavior Martha_SaturdayMorning {
    ---description
    Martha's Saturday morning routine: managing the kitchen,
    coordinating the team, and keeping the ovens running.
    ---

    repeat {
        choose saturday_priority {
            // Check ovens first (highest priority)
            then oven_management {
                if(oven_timer_near_done)
                CheckOvenTemperature
                RemoveFinishedBatch
                LoadNextBatch
                SetTimer
            }

            // Handle special orders
            then special_orders {
                if(has_special_orders)
                choose order_type {
                    PrepareWeddingCake
                    BoxCustomOrder
                    DecorateSpecialLoaf
                }
            }

            // Support Elena at counter
            then help_counter {
                if(elena_needs_help)
                choose counter_support {
                    AnswerCustomerQuestion
                    HandleComplaint
                    ProcessLargeOrder
                }
            }

            // Coordinate with Jane
            then coordinate_pastries {
                if(display_items_remaining < 10)
                SignalJaneToRestockPastries
                RearrangeDisplay
            }

            // Default: knead next batch
            then prep_dough {
                MixNextBatch
                KneadDough
                ShapeLoaves
            }
        }
    }
}

Jane's Behavior

behavior Jane_SaturdayMorning {
    repeat {
        choose jane_priority {
            // Restock display when signaled
            then restock_pastries {
                if(martha_signaled_restock)
                PlateFinishedPastries
                CarryToDisplay
                ArrangeAttractively
            }

            // Decorate current batch
            then decorating {
                if(has_undecorated_pastries)
                PipeIcing
                AddGarnish
                InspectQuality
            }

            // Start new pastry batch
            then new_batch {
                if(pastry_dough_ready)
                RollPastryDough
                CutShapes
                AddFilling
                PlaceOnBakingSheet
            }

            // Prepare specialty items
            then specialty_items {
                if(specialty_order_pending)
                ReviewOrderNotes
                SelectPremiumIngredients
                CraftSpecialtyItem
            }
        }
    }
}

Elena's Behavior

behavior Elena_SaturdayCounter {
    choose counter_state {
        // Serve waiting customers
        then serve_customer {
            if(customer_waiting)
            then service_sequence {
                GreetCustomer
                if(customer_is_regular) {
                    RecallPreferences
                }

                choose order_handling {
                    then quick_order {
                        if(customer_knows_what_they_want)
                        AcceptOrder
                        PackageItem
                    }

                    then help_decide {
                        if(not customer_knows_what_they_want)
                        OfferRecommendation
                        OfferSample
                        AcceptOrder
                        PackageItem
                    }
                }

                CollectPayment
                ThankCustomer
            }
        }

        // Handle problems
        then handle_issue {
            if(customer_has_complaint)
            choose resolution {
                then resolve_alone {
                    if(confidence > 0.5)
                    ListenCarefully
                    OfferSolution
                    ApplyResolution
                }

                then escalate {
                    if(confidence <= 0.5)
                    AcknowledgeProblem
                    CallMarthaForHelp
                }
            }
        }

        // Manage the line
        then manage_queue {
            if(line_length > 5)
            AnnounceWaitTime
            SuggestPopularItems
        }
    }
}

Gregory's Behavior

behavior Gregory_SaturdayVisit {
    then saturday_routine {
        // Arrive and order
        then arrival {
            EnterBakery
            GreetElena
            OrderSourdoughLoaf
            PayExactChange
        }

        // Linger and help
        choose lingering_activity {
            then manage_line {
                if(line_is_long)
                DirectNewCustomersToEndOfLine
                ChatWithWaitingCustomers
                RecommendPopularItems
            }

            then catch_up {
                if(sees_familiar_face)
                GreetNeighbor
                ExchangeLocalNews
                DiscussWeather
            }

            then observe_elena {
                if(elena_handling_difficult_customer)
                StandNearbyForMoralSupport
                NodEncouragingly
            }
        }

        // Eventually leave
        then departure {
            WaveToMartha
            SayGoodbyeToElena
            ExitWithBread
        }
    }
}

Relationships

relationship BakeryPartnership {
    Martha {
        role: co_owner
        coordination: 1.0
        handles_bread: true

        ---perspective
        Martha and Jane communicate without words during the rush.
        A glance toward the display case means "we're running low."
        A nod means "I'll handle it." Years of working side by side
        have created an effortless rhythm.
        ---
    }

    Jane {
        role: co_owner
        coordination: 1.0
        handles_pastries: true

        ---perspective
        Jane trusts Martha's judgment completely during the Saturday
        rush. If Martha signals, Jane reprioritizes. If Jane needs
        oven time, Martha adjusts. They are two halves of a single
        well-run kitchen.
        ---
    }

    bond: 0.95
}

relationship TeamAndApprentice {
    Martha as mentor
    Jane as senior_colleague
    Elena as apprentice

    bond: 0.8

    ---dynamics
    Elena looks up to both Martha and Jane, but in different ways.
    Martha teaches her the fundamentals -- technique, discipline,
    consistency. Jane shows her the creative side -- decoration,
    presentation, flavor combinations. Together they are shaping
    Elena into a complete baker.
    ---
}

relationship GregoryAtTheBakery {
    Gregory {
        role: loyal_customer
        attachment: 0.9
        unofficial_helper: true

        ---perspective
        The bakery is Gregory's third place -- not home, not the
        library where he used to teach, but the warm space where
        he belongs. He has watched Elena grow from a nervous girl
        to a confident young woman. He is proud, though he would
        never say so directly.
        ---
    }

    Elena {
        role: counter_staff
        fondness: 0.8
        sees_as: "grandfather_figure"

        ---perspective
        Elena looks forward to Gregory's arrival every morning.
        His exact-change payment and dry humor are a reliable
        anchor in the chaos of the morning rush.
        ---
    }

    bond: 0.7
}

The Saturday Schedule

schedule SaturdayRush {
    block early_prep {
        03:00 - 06:00
        action: baking::saturday_batch
    }

    block opening {
        06:00 - 06:15
        action: shop::open_doors
    }

    block morning_rush {
        06:15 - 11:00
        action: shop::saturday_rush_service
    }

    block midday_restock {
        11:00 - 12:00
        action: baking::midday_supplemental
    }

    block afternoon_wind_down {
        12:00 - 14:00
        action: shop::afternoon_sales
    }

    block close_and_clean {
        14:00 - 15:00
        action: shop::saturday_cleanup
    }
}

Life Arc: Elena's Saturday Confidence

life_arc ElenaSaturdayGrowth {
    state nervous_start {
        on enter {
            Elena.confidence: uncertain
            Elena.energy: 1.0
        }
        on customers_served_today > 5 -> finding_rhythm

        ---narrative
        The first few customers are always the hardest. Elena
        fumbles with the register, second-guesses prices, and
        looks to Martha for confirmation. But each successful
        transaction builds her up.
        ---
    }

    state finding_rhythm {
        on enter {
            Elena.confidence: growing
        }
        on customers_served_today > 15 -> in_the_zone

        ---narrative
        Something clicks. Elena stops thinking about each step
        and starts flowing. She remembers Mrs. Patterson's usual
        order before she says it. She bags the croissants without
        looking.
        ---
    }

    state in_the_zone {
        on enter {
            Elena.confidence: confident
        }
        on handled_complaint_alone -> proud_moment
        on energy < 0.3 -> running_on_fumes

        ---narrative
        Elena is running the counter like she was born to it.
        Gregory gives her a quiet nod of approval from his spot
        by the door. She barely notices -- she is too busy being
        competent.
        ---
    }

    state proud_moment {
        on enter {
            Elena.confidence: confident
            Elena.self_respect: 0.9
        }

        ---narrative
        A customer complained about a stale roll. Elena apologized,
        replaced it with a fresh one, and offered a free cookie.
        The customer left smiling. Elena handled it alone, without
        calling Martha. She stands a little taller afterward.
        ---
    }

    state running_on_fumes {
        on enter {
            Elena.energy: 0.2
            Elena.confidence: uncertain
        }
        on break_taken -> finding_rhythm

        ---narrative
        The rush has been going for four hours. Elena's smile
        is getting harder to maintain. Martha notices and sends
        her to the back for a five-minute break and a pastry.
        ---
    }
}

Key Takeaways

This example demonstrates:

  1. Multiple characters with interlocking behaviors: Martha, Jane, Elena, and Gregory react to each other
  2. Character coordination: Martha and Jane operate as a seamless team
  3. Asymmetric group dynamics: Gregory is an unofficial helper, Elena is growing into her role
  4. Location as context: The busy bakery storefront defines the scene
  5. Institution modeling: The Saturday crew as a coordinated work team
  6. Visitor arc: Elena's confidence through the Saturday rush modeled as a life arc
  7. Rich prose: Every character and relationship includes narrative perspective

Cross-References