# Making Characters Act In the previous chapter, you created behavior trees with selectors and sequences. Now you will add conditions, action parameters, and decorators to create dynamic, responsive behaviors. ## Conditions: if and when Conditions let behavior trees react to the world. Use `if` or `when` to test a condition before proceeding: ```storybook behavior Martha_React { choose response { then bake_path { if(inventory_sufficient) StartBaking } then restock_path { if(inventory_low) OrderSupplies } CleanWorkstation } } ``` `if(inventory_sufficient)` succeeds when inventory is sufficient, and fails otherwise. If it fails, the entire `bake_path` sequence fails, and the tree moves on to the next option. `if` and `when` are interchangeable -- use whichever reads more naturally: ```storybook // "if" for state checks if(health < 20) // "when" for event-like conditions when(alarm_triggered) ``` ### Condition Expressions Conditions support comparisons and logical operators: ```storybook // Comparisons if(health < 20) if(distance > 100) if(name == "Martha") if(status is Curious) // 'is' is syntactic sugar for == // Logical operators if(hungry and tired) if(rich or lucky) if(not is_dangerous) // Combined if(health < 50 and not has_potion) if((age > 18 and age < 65) or is_veteran) ``` ## Action Parameters Actions can take named parameters using parenthesis syntax: ```storybook behavior Martha_BakeSpecial { then baking { MixDough(recipe: "sourdough", quantity: 10) KneadDough(duration: 15m) BakeLoaves(temperature: 230, duration: 35m) } } ``` Parameters are fields inside `( )` after the action name. They let you customize behavior without defining separate actions for each variation. ## Decorators Decorators wrap a single child node and modify its behavior. They are your tools for timing, repetition, and conditional execution. ### repeat -- Looping ```storybook // Infinite repeat (checks oven forever) repeat { CheckOvenTemperature } // Repeat exactly 3 times repeat(3) { KneadDough } // Repeat between 2 and 5 times (random) repeat(2..5) { FoldDough } ``` ### invert -- Flip Results Inverts success/failure. Useful for "if NOT" conditions: ```storybook behavior SafeBake { choose options { then bake_safely { invert { OvenOverheating } // Succeeds if oven is NOT overheating ContinueBaking } StopAndInspect } } ``` ### retry -- Try Again on Failure Retries the child up to N times if it fails: ```storybook retry(3) { LightOven // Try up to 3 times before giving up } ``` ### timeout -- Time Limits Fails the child if it does not complete within the duration: ```storybook timeout(10s) { WaitForDoughToRise // Must finish within 10 seconds } ``` ### cooldown -- Rate Limiting Prevents the child from running again within the cooldown period: ```storybook cooldown(30s) { CheckOvenTemperature // Can only check once every 30 seconds } ``` ### if as Decorator (Guard) The `if` decorator only runs the child when a condition is true: ```storybook if(has_special_orders) { PrepareSpecialBatch // Only prepare when there are orders } ``` This is different from `if` as a condition node. As a decorator, `if` wraps a child and gates its execution. As a condition node, `if` is a simple pass/fail check inline in a sequence. ### succeed_always and fail_always Force a result regardless of the child: ```storybook // Try bonus task, but don't fail the routine if it fails succeed_always { ExperimentWithNewRecipe } // Temporarily disable a feature fail_always { UntestedBakingMethod } ``` ## Combining Decorators Decorators can nest for complex control: ```storybook behavior ResilientAction { // Only run if oven is ready, with 20s timeout, retrying up to 3 times if(oven_ready) { timeout(20s) { retry(3) { BakeDelicateItem } } } } ``` Execution flows outside-in: first the `if` checks the oven, then the timeout starts, then the retry begins. ## Subtree References The `include` keyword references another behavior tree, enabling reuse: ```storybook behavior SourdoughRecipe { then sourdough { MixDough(recipe: "sourdough", quantity: 10) KneadDough(duration: 15m) FirstRise(duration: 2h) ShapeLoaves } } behavior Martha_DailyRoutine { choose daily_priority { then special_orders { if(has_special_orders) include SpecialOrderBehavior } include SourdoughRecipe // Reuse sourdough behavior } } ``` Subtrees help you avoid duplicating behavior logic. You can also reference behaviors from other modules using qualified paths: ```storybook include behaviors::baking::sourdough include behaviors::service::greet_customer ``` ## Behavior Linking with Priorities Characters can link to multiple behaviors with priorities and conditions: ```storybook character Martha: Human { uses behaviors: [ { tree: BakerRoutine priority: normal }, { tree: HandleEmergency when: emergency_detected priority: high }, { tree: HandleHealthInspection when: inspector_present priority: critical } ] } ``` The runtime evaluates behaviors by priority (critical > high > normal > low). Higher-priority behaviors preempt lower-priority ones when their conditions are met. ## A Complete Example Here is a complete behavior tree for handling the morning rush: ```storybook behavior MorningRush_Routine { ---description The bakery's morning rush routine: serve customers, restock, and keep the ovens running. --- repeat { then rush_cycle { // Serve any waiting customers choose service_mode { then serve_regular { if(customer_waiting) GreetCustomer TakeOrder PackageItems CollectPayment } then restock { if(display_low) FetchFromKitchen ArrangeOnShelves } } // Check ovens between customers timeout(5s) { CheckAllOvens } PrepareNextBatch } } } ``` This tree repeats forever: serve a customer or restock the display, check the ovens, and prepare the next batch. ## Next Steps You now know the full toolkit for behavior trees. In [Advanced Behaviors](./05-advanced-behaviors.md), you will learn patterns for building complex AI systems with nested trees, state-based switching, and modular design. --- **Reference**: See [Decorators Reference](../reference/12-decorators.md) for all decorator types and [Expression Language](../reference/17-expressions.md) for complete condition syntax.