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
This commit is contained in:
344
docs/advanced/23-best-practices.md
Normal file
344
docs/advanced/23-best-practices.md
Normal file
@@ -0,0 +1,344 @@
|
||||
# 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:
|
||||
|
||||
```storybook
|
||||
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:
|
||||
|
||||
```storybook
|
||||
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:
|
||||
|
||||
```storybook
|
||||
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:
|
||||
|
||||
```storybook
|
||||
// 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:
|
||||
|
||||
```storybook
|
||||
// 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:
|
||||
|
||||
```storybook
|
||||
// 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
|
||||
|
||||
```storybook
|
||||
// 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
|
||||
|
||||
```storybook
|
||||
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:
|
||||
|
||||
```storybook
|
||||
// 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
|
||||
|
||||
```storybook
|
||||
// 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:
|
||||
|
||||
```storybook
|
||||
// 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
|
||||
|
||||
```storybook
|
||||
// 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
|
||||
|
||||
```storybook
|
||||
// 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
|
||||
|
||||
```storybook
|
||||
// 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
|
||||
|
||||
```storybook
|
||||
// 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
|
||||
|
||||
```storybook
|
||||
// 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
|
||||
|
||||
```storybook
|
||||
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
|
||||
|
||||
```storybook
|
||||
// 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
|
||||
|
||||
```storybook
|
||||
// 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](./20-patterns.md) - Common structural patterns
|
||||
- [Validation Rules](../reference/19-validation.md) - What the compiler checks
|
||||
- [Language Overview](../reference/09-overview.md) - Language philosophy
|
||||
Reference in New Issue
Block a user