# Behavior Trees - Storybook Language Guide
Comprehensive documentation for the Storybook narrative simulation language

# Behavior Trees

Behavior trees define the decision-making logic for characters, institutions, and other entities. They model how an entity chooses actions, responds to conditions, and adapts to its environment. Storybook uses behavior trees for character AI, NPC routines, and complex reactive behavior.

## What is a Behavior Tree?

A behavior tree is a hierarchical structure that executes from root to leaves, making decisions based on success/failure of child nodes:

- Composite nodes (choose, then) have multiple children and control flow
- Condition nodes (if, when) test predicates
- Action nodes execute concrete behaviors
- Decorator nodes (repeat, invert, timeout, etc.) modify child behavior
- Subtree nodes (include) reference other behavior trees

Behavior trees are evaluated every tick (frame), flowing through the tree from root to leaves until a node returns success or failure.

## Syntax

    <behavior-decl> ::= "behavior" <identifier> <body>

    <body> ::= "{" <prose-blocks>* <behavior-node> "}"

    <behavior-node> ::= <selector>
                      | <sequence>
                      | <condition>
                      | <action>
                      | <decorator>
                      | <subtree>

    <selector> ::= "choose" <label>? "{" <behavior-node>+ "}"

    <sequence> ::= "then" <label>? "{" <behavior-node>+ "}"

    <condition> ::= ("if" | "when") "(" <expression> ")"

    <action> ::= <identifier> ( "(" <param-list> ")" )?

    <param-list> ::= <field> ("," <field>)*

    <decorator> ::= <decorator-type> ("(" <params> ")")? "{" <behavior-node> "}"

    <subtree> ::= "include" <qualified-path>

    <label> ::= <identifier>

## Composite Nodes

### Selector: `choose`

A selector tries its children in order until one succeeds. Returns success if any child succeeds, failure if all fail.

Execution:

1. Try first child
2. If succeeds -> return success
3. If fails -> try next child
4. If all fail -> return failure

Use case: “Try A, if that fails try B, if that fails try C…”

    behavior GuardBehavior {
        choose guard_actions {
            AttackIntruder      // Try first
            SoundAlarm          // If attack fails, sound alarm
            FleeInPanic         // If alarm fails, flee
        }
    }

Named selectors:

    choose service_options {
        then serve_regular {
            CustomerIsWaiting
            TakeOrder
        }

        then restock_display {
            DisplayIsLow
            FetchFromKitchen
        }
    }

Labels are optional but recommended for complex trees–they improve readability and debugging.

### Sequence: `then`

A sequence runs its children in order until one fails. Returns success only if all children succeed, failure if any fails.

Execution:

1. Run first child
2. If fails -> return failure
3. If succeeds -> run next child
4. If all succeed -> return success

Use case: “Do A, then B, then C… all must succeed”

    behavior BrewingSequence {
        then brew_potion {
            GatherIngredients   // Must succeed
            MixIngredients      // Then this must succeed
            Boil                // Then this must succeed
            BottlePotion        // Finally this
        }
    }

Named sequences:

    then prepare_sourdough {
        MixDough
        KneadDough
        ShapeLoaves
    }

### Nesting Composites

Composite nodes can nest arbitrarily deep:

    behavior ComplexAI {
        choose root_decision {
            // Combat branch
            then engage_combat {
                if(enemy_nearby)
                choose combat_tactics {
                    AttackWithSword
                    AttackWithMagic
                    DefendAndWait
                }
            }

            // Exploration branch
            then explore_area {
                if(safe)
                choose exploration_mode {
                    SearchForTreasure
                    MapTerritory
                    Rest
                }
            }

            // Default: Idle
            Idle
        }
    }

## Condition Nodes

Conditions test expressions and return success/failure based on the result.

### `if` vs. `when`

Both are semantically identical–use whichever reads better in context:

    behavior Example {
        choose options {
            // "if" for state checks
            then branch_a {
                if(player_nearby)
                Attack
            }

            // "when" for event-like conditions
            then branch_b {
                when(alarm_triggered)
                Flee
            }
        }
    }

### Condition Syntax

    if(health < 20)                          // Comparison
    when(is_hostile)                         // Boolean field
    if(distance > 10 and has_weapon)         // Logical AND
    when(not is_stunned or is_enraged)       // Logical OR with NOT

See Expression Language for complete expression syntax.

## Action Nodes

Actions are leaf nodes that execute concrete behaviors. They reference action implementations in the runtime.

### Basic Actions

    behavior SimpleActions {
        then do_things {
            MoveForward
            TurnLeft
            Attack
        }
    }

### Actions with Parameters

Actions can have named parameters using parenthesis syntax:

    behavior ParameterizedActions {
        then patrol {
            MoveTo(destination: "Waypoint1", speed: 1.5)
            WaitFor(duration: 5s)
            MoveTo(destination: "Waypoint2", speed: 1.5)
        }
    }

Parameter passing:

- Parameters are passed as fields (name: value)
- All value types supported
- Runtime validates parameter types

    behavior RichParameters {
        then complex_action {
            CastSpell(spell: "Fireball", target: enemy_position, power: 75, multicast: false)
            Heal(amount: 50, target: self)
        }
    }

## Decorator Nodes

Decorators wrap a single child node and modify its behavior. See Decorators for complete reference.

### Common Decorators

    behavior DecoratorExamples {
        choose {
            // Repeat infinitely
            repeat {
                PatrolRoute
            }

            // Repeat exactly 3 times
            repeat(3) {
                CheckDoor
            }

            // Repeat 2 to 5 times
            repeat(2..5) {
                SearchArea
            }

            // Invert success/failure
            invert {
                IsEnemyNearby  // Returns success if enemy NOT nearby
            }

            // Retry up to 5 times on failure
            retry(5) {
                OpenLockedDoor
            }

            // Timeout after 10 seconds
            timeout(10s) {
                SolveComplexPuzzle
            }

            // Cooldown: only run once per 30 seconds
            cooldown(30s) {
                FireCannon
            }

            // If: only run if condition true
            if(health > 50) {
                AggressiveAttack
            }

            // Always succeed regardless of child result
            succeed_always {
                AttemptOptionalTask
            }

            // Always fail regardless of child result
            fail_always {
                ImpossipleTask
            }
        }
    }

## Subtree References

The `include` keyword references another behavior tree, enabling modularity and reuse.

### Basic Subtree

    behavior PatrolRoute {
        then patrol {
            MoveTo(destination: "Waypoint1")
            MoveTo(destination: "Waypoint2")
            MoveTo(destination: "Waypoint3")
        }
    }

    behavior GuardBehavior {
        choose guard_ai {
            then combat {
                if(enemy_nearby)
                include combat::engage
            }

            include PatrolRoute  // Reuse patrol behavior
        }
    }

### Qualified Subtree References

    behavior ComplexAI {
        choose ai_modes {
            include behaviors::combat::melee
            include behaviors::combat::ranged
            include behaviors::exploration::search
            include behaviors::social::greet
        }
    }

## Named Nodes

Both composite nodes (`choose`, `then`) can have optional labels:

    behavior NamedNodeExample {
        choose daily_priority {                  // Named selector
            then handle_special_orders {         // Named sequence
                CheckOrderQueue
                PrepareSpecialIngredients
                BakeSpecialItem
            }

            choose regular_work {               // Named selector
                then morning_bread {             // Named sequence
                    MixSourdough
                    BakeLoaves
                }
            }
        }
    }

Benefits:

- Readability: Tree structure is self-documenting
- Debugging: Named nodes appear in execution traces
- Narrative: Labels can be narrative (“handle_special_orders” vs. anonymous node)

Guidelines:

- Use labels for important structural nodes
- Use descriptive, narrative names
- Omit labels for trivial nodes

## Complete Examples

### Simple Guard AI

    behavior GuardPatrol {
        choose guard_logic {
            // Combat if enemy nearby
            then combat_mode {
                if(enemy_nearby and has_weapon)
                Attack
            }

            // Sound alarm if see intruder
            then alarm_mode {
                if(intruder_detected)
                SoundAlarm
            }

            // Default: Patrol
            then patrol_mode {
                include PatrolRoute
            }
        }
    }

### Complex NPC Behavior

    behavior Innkeeper_DailyRoutine {
        ---description
        The innkeeper's behavior throughout the day. Uses selectors for
        decision-making and sequences for multi-step actions.
        ---

        choose daily_activity {
            // Morning: Prepare for opening
            then morning_prep {
                when(time_is_morning)
                then prep_sequence {
                    UnlockDoor
                    LightFireplace
                    PrepareBreakfast
                    WaitForGuests
                }
            }

            // Day: Serve customers
            then day_service {
                when(time_is_daytime)
                choose service_mode {
                    // Serve customer if present
                    then serve {
                        if(customer_waiting)
                        GreetCustomer
                        TakeOrder
                        ServeMeal
                        CollectPayment
                    }

                    // Restock if needed
                    then restock {
                        if(inventory_low)
                        ReplenishInventory
                    }

                    // Default: Clean
                    CleanTables
                }
            }

            // Night: Close up
            then evening_close {
                when(time_is_evening)
                then close_sequence {
                    DismissRemainingGuests
                    LockDoor
                    CountMoney
                    GoToBed
                }
            }
        }
    }

### Morning Baking Routine

    behavior Baker_MorningRoutine {
        ---description
        Martha's morning routine: prepare dough step by step,
        from mixing to shaping to baking.
        ---

        then morning_baking {
            // Start with sourdough
            then prepare_starter {
                CheckStarter
                FeedStarter
                WaitForActivity
            }

            // Mix the dough
            then mix_dough {
                MeasureFlour
                AddWater
                IncorporateStarter
            }

            // Knead and shape
            then shape_loaves {
                KneadDough
                FirstRise
                ShapeLoaves
            }

            // Bake
            then bake {
                PreHeatOven
                LoadLoaves
                MonitorBaking
            }
        }
    }

### Repeating Behavior

    behavior Bakery_CustomerServiceLoop {
        ---description
        The bakery's continuous customer service loop. Uses infinite
        repeat decorator to serve customers throughout the day.
        ---

        repeat {
            then service_cycle {
                // Check for customers
                choose service_mode {
                    then serve_waiting {
                        if(customer_waiting)
                        GreetCustomer
                        TakeOrder
                    }

                    then restock_display {
                        if(display_low)
                        FetchFromKitchen
                        ArrangeOnShelves
                    }
                }

                // Process payment
                CollectPayment
                ThankCustomer

                // Brief pause between customers
                timeout(5s) {
                    CleanCounter
                }

                PrepareForNextCustomer
            }
        }
    }

### Retry Logic for Delicate Recipes

    behavior Baker_DelicatePastry {
        ---description
        Elena attempting a delicate pastry recipe that requires
        precise technique. Uses retry decorator for persistence.
        ---

        choose baking_strategy {
            // Try when conditions are right
            then attempt_pastry {
                if(oven_at_temperature)
                // Try up to 3 times
                retry(3) {
                    then make_pastry {
                        RollDoughThin
                        ApplyFilling
                        FoldAndSeal
                        CheckForLeaks
                    }
                }
            }

            // If oven not ready, prepare meanwhile
            then prepare_meanwhile {
                if(not oven_at_temperature)
                then prep_sequence {
                    PrepareIngredients
                    MixFilling
                    ChillDough
                }
            }
        }
    }

## Integration with Characters

Characters link to behaviors using the `uses behaviors` clause:

    character Guard {
        uses behaviors: [
            {
                tree: guards::patrol_route
                priority: normal
            },
            {
                tree: guards::engage_hostile
                when: threat_detected
                priority: high
            },
            {
                tree: guards::sound_alarm
                when: emergency
                priority: critical
            }
        ]
    }

Behavior selection:

- Multiple behaviors evaluated by priority (critical > high > normal > low)
- Conditions (`when` clause) gate behavior activation
- Higher-priority behaviors preempt lower-priority ones

See Characters for complete behavior linking syntax.

## Execution Semantics

### Tick-Based Evaluation

Behavior trees execute every “tick” (typically once per frame):

1. Start at root node
2. Traverse down to leaves based on composite logic
3. Execute leaf nodes (conditions, actions)
4. Return success/failure up the tree
5. Repeat next tick

### Node Return Values

Every node returns one of:

- Success: Node completed successfully
- Failure: Node failed
- Running: Node still executing (async action)

### Stateful vs. Stateless

- Stateless nodes: Evaluate fresh every tick (conditions, simple actions)
- Stateful nodes: Maintain state across ticks (decorators, long actions)

Example of stateful behavior:

    behavior LongAction {
        timeout(30s) {           // Stateful: tracks elapsed time
            ComplexCalculation   // May take multiple ticks
        }
    }

## Validation Rules

1. At least one node: Behavior body must contain at least one node
2. Composite children: `choose` and `then` require at least one child
3. Decorator child: Decorators require exactly one child
4. Action exists: Action names must reference registered actions in runtime
5. Subtree exists: `include` must reference a defined `behavior` declaration
6. Expression validity: Condition expressions must be well-formed
7. Duration format: Decorator durations must be valid (e.g., `5s`, `10m`)
8. Unique labels: Node labels (if used) should be unique within their parent
9. Parameter types: Action parameters must match expected types

## Best Practices

### 1. Prefer Shallow Trees

Avoid:

    choose {
        then { then { then { then { Action } } } }  // Too deep!
    }

Prefer:

    choose root {
        include combat_tree
        include exploration_tree
        include social_tree
    }

### 2. Use Named Nodes for Clarity

Avoid:

    choose {
        then {
            IsHungry
            FindFood
            Eat
        }
        Wander
    }

Prefer:

    choose survival {
        then eat_if_hungry {
            IsHungry
            FindFood
            Eat
        }
        Wander
    }

### 3. Subtrees for Reusability

Avoid: Duplicating logic across behaviors

Prefer:

    behavior Combat_Common {
        then attack_sequence {
            DrawWeapon
            Approach
            Strike
        }
    }

    behavior Warrior {
        include Combat_Common
    }

    behavior Guard {
        include Combat_Common
    }

### 4. Decorators for Timing

Avoid: Manual timing in actions

Prefer:

    timeout(10s) {
        ComplexTask
    }

    cooldown(30s) {
        SpecialAbility
    }

### 5. Guard for Preconditions

Avoid:

    then problematic {
        ExpensiveAction  // Always runs even if inappropriate
    }

Prefer:

    if(can_afford_action) {
        ExpensiveAction  // Only runs when condition passes
    }

## Cross-References

- Decorators - Complete decorator reference
- Characters - Linking behaviors to characters
- Expression Language - Condition expression syntax
- Value Types - Parameter value types
- Design Patterns - Common behavior tree patterns

## Related Concepts

- Reactive AI: Behavior trees continuously react to changing conditions
- Hierarchical decision-making: Composite nodes create decision hierarchies
- Modularity: Subtrees enable behavior reuse and composition
- Narrative-driven design: Named nodes make behavior trees readable as stories