# 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.
