# Best Practices - Storybook Language Guide
Comprehensive documentation for the Storybook narrative simulation language

# Best Practices

This chapter compiles best practices for writing clear, maintainable, and effective Storybook code. These guidelines apply across all declaration types and project sizes.

## Naming Conventions

### Declarations

Use PascalCase for all declaration names:

    character MasterBaker { }          // Good
    species DomesticCat { }            // Good
    behavior GuardPatrol { }           // Good

    character master_baker { }         // Avoid
    behavior guard-patrol { }         // Invalid (no hyphens)

### Fields

Use snake_case for field names:

    character Martha {
        skill_level: 0.95            // Good
        emotional_state: focused     // Good
        years_experience: 22         // Good

        skillLevel: 0.95             // Avoid (camelCase)
    }

### Behavior Tree Labels

Use snake_case for node labels, with descriptive names:

    choose survival_instinct {       // Good
        then fight_response { }      // Good
        then flight_response { }     // Good
    }

    choose s1 {                      // Avoid (meaningless)
        then a { }                   // Avoid
    }

### Enum Variants

Use PascalCase or snake_case consistently within an enum:

    // PascalCase (good for short names)
    enum Size { Tiny, Small, Normal, Large, Huge }

    // snake_case (good for compound names)
    enum GovernmentStyle {
        absolute_tyranny,
        constitutional_monarchy,
        direct_democracy
    }

## File Organization

### Separate Schema from World

Keep reusable type definitions separate from instance data:

    project/
      schema/           # Reusable across stories
        core_enums.sb   # Enum definitions
        templates.sb    # Template definitions
        beings.sb       # Species definitions
      world/            # Specific to this story
        characters/     # Character instances
        behaviors/      # Behavior trees
        relationships/  # Relationship instances
        locations/      # Location instances

### One Concern per File

Group related declarations, but avoid putting unrelated things together:

    // characters/bakery_staff.sb - Good: related characters together
    character Martha { }
    character Jane { }
    character Elena { }

    // everything.sb - Avoid: everything in one file
    character Martha { }
    behavior BakeRoutine { }
    schedule DailyRoutine { }
    relationship Partnership { }

### Explicit Imports

Prefer explicit imports over wildcards:

    // Good: clear what is being used
    use schema::core_enums::{SkillLevel, Specialty};
    use schema::beings::Human;

    // Avoid: unclear dependencies
    use schema::core_enums::*;
    use schema::beings::*;

## Character Design

### Use Species for Identity, Templates for Traits

    // Species: ontological identity
    species Human { lifespan: 70 }

    // Templates: compositional traits
    template Warrior { strength: 10..20 }
    template Scholar { intelligence: 15..20 }

    // Character: combines identity and traits
    character Aragorn: Human from Warrior {
        strength: 18
    }

### Document with Prose Blocks

    character Martha: Human {
        age: 34

        ---backstory
        Martha learned to bake from her grandmother, starting at
        age twelve. She now runs the most popular bakery in town.
        ---

        ---personality
        Meticulous and patient, with an unwavering commitment to
        quality. Tough but fair with her staff.
        ---
    }

### Prefer Flat Inheritance

Avoid deep species hierarchies. Two or three levels is usually enough:

    // Good: shallow
    species Mammal { warm_blooded: true }
    species Human includes Mammal { sapient: true }

    // Avoid: too deep
    species Being { }
    species LivingBeing includes Being { }
    species Animal includes LivingBeing { }
    species Vertebrate includes Animal { }
    species Mammal includes Vertebrate { }
    species Human includes Mammal { }

## Behavior Tree Design

### Name Every Composite Node

    // Good: self-documenting
    choose daily_priority {
        then handle_emergency { }
        then do_work { }
        then relax { }
    }

    // Avoid: anonymous nodes
    choose {
        then { }
        then { }
    }

### Keep Trees Shallow

Extract deep subtrees into separate behaviors:

    // Good: flat with includes
    behavior Main {
        choose mode {
            include CombatBehavior
            include ExplorationBehavior
            include SocialBehavior
        }
    }

    // Avoid: deeply nested
    behavior Main {
        choose {
            then { choose { then { choose { then { Action } } } } }
        }
    }

### Use Decorators for Control Flow

    // Good: decorator handles timing
    cooldown(30s) { CastSpell }
    timeout(10s) { SolvePuzzle }
    retry(3) { PickLock }

    // Avoid: manual timing in actions
    CheckCooldownTimer
    IfCooldownReady { CastSpell }

## Expression Writing

### Use Parentheses for Clarity

    // Good: explicit grouping
    on (health < 50 or is_poisoned) and has_antidote -> healing

    // Risky: relies on precedence knowledge
    on health < 50 or is_poisoned and has_antidote -> healing

### Break Complex Conditions into Multiple Transitions

    // Good: separate transitions, easy to read
    state combat {
        on health < 20 and not has_potion -> desperate
        on surrounded and not has_escape -> desperate
        on enemy_count > 10 -> desperate
    }

    // Avoid: one massive condition
    state combat {
        on (health < 20 and not has_potion) or (surrounded and not has_escape) or enemy_count > 10 -> desperate
    }

### Use `is` for Enum Comparisons

    // Good: reads naturally
    on status is active -> active_state
    on skill_level is master -> teach_others

    // Works but less readable
    on status == active -> active_state

## Schedule Design

### Use Named Blocks for Override Support

    // Good: named blocks can be overridden
    schedule Base {
        block work { 09:00 - 17:00, action: standard_work }
    }

    schedule Variant extends Base {
        block work { 05:00 - 13:00, action: early_work }
    }

### Group Related Blocks

    schedule DailyRoutine {
        // Morning
        block wake { 06:00 - 07:00, action: morning_routine }
        block breakfast { 07:00 - 08:00, action: eat }

        // Work
        block commute { 08:00 - 09:00, action: travel }
        block work { 09:00 - 17:00, action: work }

        // Evening
        block leisure { 18:00 - 22:00, action: relax }
        block sleep { 22:00 - 06:00, action: sleep }
    }

## Relationship Design

### Use Roles for Clarity

    // Good: roles clarify the relationship
    relationship Marriage {
        Martha as spouse
        David as spouse
        bond: 0.9
    }

    // Less clear without roles
    relationship Marriage {
        Martha
        David
        bond: 0.9
    }

### Use Perspectives for Asymmetry

    // Good: captures different viewpoints
    relationship TeacherStudent {
        Gandalf as teacher self { patience: 0.8 } other { potential: 0.9 }
        Frodo as student self { motivation: 0.7 } other { admiration: 0.95 }
        bond: 0.85
    }

## General Principles

1. Readability over brevity: Storybook code should read like a narrative, not a puzzle.

2. Explicit over implicit: Say what you mean. Use named nodes, explicit imports, and clear field names.

3. Flat over deep: Shallow hierarchies, short behavior trees, and focused files are easier to maintain.

4. Composition over inheritance: Prefer combining templates over building deep species hierarchies.

5. Document with prose: Prose blocks are a feature, not clutter. Use them to explain intent alongside data.

6. One concept per declaration: Each behavior tree, life arc, or schedule should have a single clear purpose.

## Cross-References

- Design Patterns - Common structural patterns
- Validation Rules - What the compiler checks
- Language Overview - Language philosophy