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:
2026-02-13 21:52:03 +00:00
parent 80332971b8
commit 16deb5d237
290 changed files with 90316 additions and 5827 deletions

BIN
examples/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -1,28 +1,28 @@
//! Core enumerations for Wonderland domain modeling
enum Size {
tiny, // 3 inches tall
small, // 1 foot tall
normal, // Human-sized
large, // 9 feet tall
huge // House-sized
Tiny, // 3 inches tall
Small, // 1 foot tall
Normal, // Human-sized
Large, // 9 feet tall
Huge // House-sized
}
enum EmotionalState {
curious,
frightened,
confused,
brave,
angry,
melancholy,
amused
Curious,
Frightened,
Confused,
Brave,
Angry,
Melancholy,
Amused
}
enum CardSuit {
hearts,
diamonds,
clubs,
spades
Hearts,
Diamonds,
Clubs,
Spades
}
enum CardRank {

View File

@@ -1,4 +1,5 @@
//! Template definitions for Wonderland entities
//! v0.2.0: Templates now include behavior and schedule references
use schema::core_enums::{Size, EmotionalState};
@@ -33,6 +34,8 @@ template PlayingCard strict {
// Template for residents of the Mad Tea Party
template MadTeaPartyMember {
include WonderlandCreature
uses behaviors: EndlessTeaParty, MoveToNextSeat
uses schedule: TeaPartySchedule
stuck_at_teatime: true
riddles_asked: 0..1000
@@ -43,6 +46,7 @@ template MadTeaPartyMember {
// Template for royal court members
template CourtMember {
include WonderlandCreature
uses schedule: CourtSchedule
loyalty_to_queen: 0.0..1.0
times_threatened_with_beheading: 0..100

View File

@@ -0,0 +1,169 @@
//! Behavior trees for Wonderland characters
//!
//! v0.2.0: These are referenced by schedule blocks
// Queen's behaviors
behavior RuleWithTyranny {
repeat {
choose {
demand_impossible_task
shout_off_with_their_heads
criticize_garden_roses
inspect_card_soldiers
}
}
}
behavior CroquetAndExecutions {
then {
set_up_croquet_course
repeat {
choose {
play_croquet_round
order_execution
argue_with_everyone
}
}
}
}
behavior PlayCroquet {
repeat {
then {
grab_flamingo_mallet
aim_at_hedgehog
if(hedgehog_uncurls) {
swing_flamingo
}
argue_about_rules
}
}
}
// Mad Tea Party behaviors
behavior EndlessTeaParty {
repeat {
then {
pour_tea
ask_riddle
change_subject_nonsensically
if(no_clean_cups) {
move_to_next_seat
}
}
}
}
behavior MoveToNextSeat {
then {
stand_up
move_one_place_on
sit_down
continue_conversation_mid_sentence
}
}
// White Rabbit behaviors
behavior AlwaysLate {
repeat {
then {
check_pocket_watch
gasp_in_horror
run_frantically
drop_gloves
mutter_about_duchess
}
}
}
behavior CheckPocketWatch {
then {
pull_out_watch
squint_at_time
shake_watch
hold_to_ear
sigh_dramatically
}
}
// Caterpillar behaviors
behavior PhilosophizeOnMushroom {
repeat {
then {
smoke_hookah
if(someone_approaches) {
ask_who_are_you
}
make_cryptic_statement
look_contemptuous
}
}
}
// Cheshire Cat behaviors
behavior AppearAtRandom {
repeat {
choose {
fade_in_slowly
appear_in_tree
materialize_grin_first
then {
speak_enigmatically
vanish_gradually
}
}
}
}
behavior LeaveOnlyGrin {
then {
begin_fading
fade_body
fade_head
leave_grin_floating
eventually_fade_grin
}
}
// Court behaviors
behavior CourtDuties {
then {
attend_queen
avoid_execution
paint_roses_red
march_in_formation
}
}
// Alice's behaviors
behavior ExploreWonderland {
repeat {
choose {
then {
encounter_strange_character
ask_logical_question
receive_illogical_answer
be_confused
}
then {
find_food_or_drink
if(risky) {
eat_it_anyway
}
change_size_unexpectedly
}
try_to_recite_poetry_incorrectly
}
}
}
behavior TryToGetHome {
repeat {
then {
ask_for_directions
receive_confusing_directions
get_more_lost
sigh_about_missing_home
}
}
}

View File

@@ -1,10 +1,15 @@
//! Alice: The protagonist navigating Wonderland's absurdities
//! v0.2.0: Now includes behavior references for her exploration patterns
use schema::core_enums::{Size, EmotionalState};
use schema::templates::SizeChanging;
use schema::beings::Human;
character Alice: Human from SizeChanging {
uses behaviors: [
{ tree: ExploreWonderland },
{ tree: TryToGetHome }
]
// Core identity
age: 7
natural_size: normal

View File

@@ -57,16 +57,16 @@ behavior Caterpillar_SocraticMethod {
questions, contradicts answers, and forces self-examination.
---
> {
then interrogation_sequence {
// Initial confrontation
> {
then opening_question {
RemoveHookahFromMouth
StareInSilence
AskWhoAreYou
}
// Alice's confused response
> {
then contradiction_cycle {
AliceExplainsShesChanged
Caterpillar_StatesDisagreement
AliceExplainsMore
@@ -74,9 +74,9 @@ behavior Caterpillar_SocraticMethod {
}
// Philosophical exchange
? {
choose debate_topic {
// On change and identity
> {
then identity_crisis {
AliceMentionsDifferentSizes
Caterpillar_DismissesComplaint
AliceSuggestsFutureChange
@@ -84,7 +84,7 @@ behavior Caterpillar_SocraticMethod {
}
// On memory and self
> {
then memory_test {
AskWhatAliceCantRemember
AliceRecitesPoem
RecitationIsWrong
@@ -93,7 +93,7 @@ behavior Caterpillar_SocraticMethod {
}
// Eventual aid (after sufficient confusion)
> {
then reluctant_guidance {
AskWhatSizeAliceWants
AliceExplainsPreference
OfferCrypticAdvice
@@ -102,7 +102,7 @@ behavior Caterpillar_SocraticMethod {
}
// Transformation and departure
> {
then exit {
CrawlDownMushroom
Vanish
}
@@ -115,16 +115,16 @@ behavior Caterpillar_MushroomAdvice {
Deliberately vague to force Alice to experiment and learn.
---
> {
then cryptic_instruction {
// Verify Alice's distress about size
> {
then assess_problem {
ObserveAliceHeight
AskIfContentNow
AliceExplainsDesireToBeNormal
}
// Offer cryptic instruction
> {
then vague_direction {
Point AtMushroom
Say
PauseForEffect
@@ -132,13 +132,13 @@ behavior Caterpillar_MushroomAdvice {
}
// Respond to clarification requests
? {
> {
choose handle_confusion {
then refuse_clarification {
AliceAsksWhichSide
Caterpillar_StatesObvious
RefuseToElaborate
}
> {
then already_departed {
AliceLooksAtRoundMushroom
RealizesAmbiguity
Caterpillar_AlreadyGone
@@ -146,7 +146,7 @@ behavior Caterpillar_MushroomAdvice {
}
// Let Alice figure it out
> {
then mysterious_exit {
CrawlAway
BeginTransformation
LeaveAliceWithPuzzle

View File

@@ -53,18 +53,18 @@ behavior CheshireCat_AppearDisappear {
---
// Root selector: decide action based on current state
? {
choose state_dependent_action {
// If invisible, consider appearing
> {
then appear_from_nothing {
IsInvisible
DecideToAppear
GradualManifestation
}
// If visible, might give advice or disappear
? {
choose visible_options {
// Give cryptic advice
> {
then confuse_alice {
IsFullyVisible
ObserveAliceConfusion
GrinWider
@@ -72,7 +72,7 @@ behavior CheshireCat_AppearDisappear {
}
// Begin disappearing
> {
then fade_away {
IsFullyVisible
DecideToLeave
GradualDematerialization
@@ -80,7 +80,7 @@ behavior CheshireCat_AppearDisappear {
}
// If partial, continue transition
> {
then continue_manifestation {
IsPartiallyManifest
ContinueTransition
}
@@ -93,29 +93,29 @@ behavior CheshireCat_GradualManifestation {
Always ends with the grin appearing last (or first).
---
> {
then materialize_piece_by_piece {
// Start with grin (the signature move)
> {
then grin_first {
SetManifestationLevelPartialGrin
WaitTwoSeconds
AliceNoticesGrin
}
// Eyes appear
> {
then add_eyes {
AddEyes
SetManifestationLevelPartialBody
WaitOneAndHalfSeconds
}
// Head materializes around grin
> {
then form_head {
AddHead
WaitOneSecond
}
// Full body appears
> {
then complete_body {
AddBody
AddTail
SetManifestationLevelFullyVisible
@@ -130,22 +130,22 @@ behavior CheshireCat_GradualDematerialization {
"quite some time after the rest of it had gone."
---
> {
then vanish_piece_by_piece {
// Tail vanishes first
> {
then tail_first {
FadeTail
WaitOneSecond
}
// Body fades
> {
then fade_body {
FadeBody
SetManifestationLevelPartialBody
WaitOneAndHalfSeconds
}
// Head disappears, leaving grin
> {
then leave_grin_behind {
FadeHead
LeaveEyes
SetManifestationLevelPartialGrin
@@ -154,7 +154,7 @@ behavior CheshireCat_GradualDematerialization {
}
// Finally, grin vanishes
> {
then grin_last {
FadeGrin
SetManifestationLevelInvisible
}
@@ -167,16 +167,16 @@ behavior CheshireCat_OfferAdvice {
more confusing than helpful.
---
? {
choose cryptic_response {
// If asked for directions
> {
then unhelpful_directions {
AliceAsksWhichWay
? {
> {
choose either_way_works {
then point_left {
PointLeft
SayDirections
}
> {
then point_right {
PointRight
SayDirections
}
@@ -186,7 +186,7 @@ behavior CheshireCat_OfferAdvice {
}
// If asked about the game
> {
then mysterious_answer {
AliceAsksAboutCroquet
Say
WaitForResponse
@@ -194,7 +194,7 @@ behavior CheshireCat_OfferAdvice {
}
// General philosophical musing
> {
then unsolicited_wisdom {
ObserveAlicesSituation
OfferUnsolicitedWisdom
VanishBeforeExplanation

View File

@@ -166,7 +166,7 @@ schedule MadTeaPartyRotation {
---
}
18:05 -> 18:00: LoopToBeginning {
18:05 -> 18:06: LoopToBeginning {
---narrative
Time hasn't moved. It's still 6 o'clock. It's always
6 o'clock. The party begins again, identical to the last,
@@ -187,65 +187,66 @@ behavior MadTeaParty_CoordinatedMadness {
and create a cascade of illogic.
---
> {
then setup_and_loop {
// Initialization: Set up eternal tea time
> {
then initialize {
SetTimeStateFrozen
SetCurrentTimeToSix
VerifyTimeStillSix
}
// Main party loop (runs forever)
// TODO: Add repeater decorator support
> {
// Selector: Choose a mad activity
? {
// Riddle sequence
> {
MadHatter_AskRiddle
AliceAttemptsSolution
MadHatter_AdmitsNoAnswer
MarchHare_ChangesSubject
repeat {
then {
// Selector: Choose a mad activity
choose mad_activity {
// Riddle sequence
then riddles {
MadHatter_AskRiddle
AliceAttemptsSolution
MadHatter_AdmitsNoAnswer
MarchHare_ChangesSubject
}
// Contradition game
then contradictions {
AliceMakesStatement
MarchHare_ContradictLogic
MadHatter_BuildsOnContradiction
Dormouse_MuttersInSleep
}
// Story time
then story_time {
PinchDormouse
Dormouse_WakesGroggily
Dormouse_BeginsMeanderingStory
Dormouse_FallsAsleepMidWord
}
// Butter the watch
then butter_watch {
MadHatter_ChecksBrokenWatch
MarchHare_OffersButterAsRepair
DipWatchInTea
ExamineWatchHopefully
DeclareItStillBroken
}
// Seat rotation
then seat_rotation {
DeclareNoRoom
ShiftSeatsClockwise
IncrementSeatPositions
}
}
// Contradition game
> {
AliceMakesStatement
MarchHare_ContradictLogic
MadHatter_BuildsOnContradiction
Dormouse_MuttersInSleep
// Always end by verifying time hasn't moved
then verify_time {
CheckTime
ConfirmStillSixOClock
SighPhilosophically
}
// Story time
> {
PinchDormouse
Dormouse_WakesGroggily
Dormouse_BeginsMeanderingStory
Dormouse_FallsAsleepMidWord
}
// Butter the watch
> {
MadHatter_ChecksBrokenWatch
MarchHare_OffersButterAsRepair
DipWatchInTea
ExamineWatchHopefully
DeclareItStillBroken
}
// Seat rotation
> {
DeclareNoRoom
ShiftSeatsClockwise
IncrementSeatPositions
}
}
// Always end by verifying time hasn't moved
> {
CheckTime
ConfirmStillSixOClock
SighPhilosophically
}
}
}
@@ -257,27 +258,28 @@ behavior Dormouse_SleepCycle {
and brief, drowsy wakefulness. Uses a repeater decorator.
---
// TODO: Add repeater decorator support
> {
> {
FallAsleep
BeUsedAsCushion
WaitForPinch
}
repeat {
then {
then sleep_phase {
FallAsleep
BeUsedAsCushion
WaitForPinch
}
> {
WakeWithStart
MutterConfusedly
? {
> {
BeginStory
DescribeTheirNames
ExplainTreacleWell
FallAsleepMidSentence
}
> {
MakeCircularStatement
CloseEyesAgain
then wake_phase {
WakeWithStart
MutterConfusedly
choose response {
then tell_story {
BeginStory
DescribeTheirNames
ExplainTreacleWell
FallAsleepMidSentence
}
then mutter {
MakeCircularStatement
CloseEyesAgain
}
}
}
}

View File

@@ -160,74 +160,76 @@ behavior QueenOfHearts_RagePattern {
in "Off with their heads!"
---
// TODO: Add repeater decorator support
> {
// Wait for any stimulus
WaitForInteraction
// Repeats forever - the Queen never runs out of rage
repeat {
then rage_cycle {
// Wait for any stimulus
WaitForInteraction
// Selector: Interpret stimulus as offense
? {
// Minor perceived slight
> {
DetectMinorIrregularity
TurnCrimson
Glare
Scream
StompFoot
// Selector: Interpret stimulus as offense
choose perceived_offense {
// Minor perceived slight
then minor_slight {
DetectMinorIrregularity
TurnCrimson
Glare
Scream
StompFoot
}
// Someone wins at croquet
then croquet_outrage {
ObserveSomeoneScoring
DeclareCheating
Rage
OrderExecution
}
// Anyone speaks back
then contradiction_fury {
HearContradiction
TurnPurpleWithFury
Shriek
TurnToKing
DemandAgreement
}
// Painted roses discovered
then painting_discovery {
NoticePaintBrushes
DemandExplanation
InterruptExplanation
OrderImmediateBeheading
}
// Default: random rage
then irrational_anger {
FeelIrrationalAnger
LookForTarget
FindTarget
ScreamOffWithTheirHeads
}
}
// Someone wins at croquet
> {
ObserveSomeoneScoring
DeclareCheating
Rage
OrderExecution
// King attempts to moderate
choose king_intervention {
then whispered_plea {
King_WhispersPleas
Queen_IgnoresEntirely
}
then reminder_backfires {
King_RemindsOfMercy
Queen_GlaresAtKing
ConsiderBeheadingKingToo
}
}
// Anyone speaks back
> {
HearContradiction
TurnPurpleWithFury
Shriek
TurnToKing
DemandAgreement
// Execution order given (but secretly pardoned later)
then execution_ordered {
IncrementBeheadingCount
SoldiersLookUncertain
VictimPleadsOrFlees
}
// Painted roses discovered
> {
NoticePaintBrushes
DemandExplanation
InterruptExplanation
OrderImmediateBeheading
}
// Default: random rage
> {
FeelIrrationalAnger
LookForTarget
FindTarget
ScreamOffWithTheirHeads
}
}
// King attempts to moderate
? {
> {
King_WhispersPleas
Queen_IgnoresEntirely
}
> {
King_RemindsOfMercy
Queen_GlaresAtKing
ConsiderBeheadingKingToo
}
}
// Execution order given (but secretly pardoned later)
> {
IncrementBeheadingCount
SoldiersLookUncertain
VictimPleadsOrFlees
}
}
}
@@ -238,36 +240,35 @@ behavior CardGardeners_DesperatePainting {
the Queen discovers their mistake. Models coordinated panic.
---
> {
then desperate_work {
// Initial panic
> {
then assessment {
CheckQueensPosition
EstimateTimeRemaining
PaintFaster
}
// Coordination breaks down under stress
// TODO: Add repeater decorator support
> {
? {
// Coordination breaks down under stress - repeat until Queen arrives
repeat {
choose panic_actions {
// Blame game
> {
then argument {
Five_GetsSplashed
Five_BlamesS even
Five_BlameSeven
Seven_DefendsHimself
Two_AttemptsMediation
AllArgumentInterrupted
}
// Desperate painting
> {
then frantic_painting {
Two_PaintsRose
Five_PaintsRose
Seven_PaintsRose
}
// Discovery and panic
> {
then discovery {
HearQueensProcession
Five_Shouts
AllThrowThemselvesFlat
@@ -284,32 +285,34 @@ behavior KingOfHearts_SecretPardons {
Runs in background after each of her rage episodes.
---
// TODO: Add repeater decorator support
> {
// Wait for Queen's execution order
WaitForOffWithTheirHeads
// Repeats forever - the King never stops being merciful
repeat {
then mercy_cycle {
// Wait for Queen's execution order
WaitForOffWithTheirHeads
// Let some time pass
WaitThirtySeconds
// Let some time pass
WaitThirtySeconds
// Secretly pardon
? {
> {
QueenIsDistracted
QuietlyApproachSoldiers
WhisperPardon
SoldiersNodRelief
VictimQuietlyEscapes
}
> {
WritePardonOrder
SlipItToKnave
KnaveDeliversMercy
EveryonePretendExecution Happened
// Secretly pardon
choose pardon_method {
then whispered_pardon {
QueenIsDistracted
QuietlyApproachSoldiers
WhisperPardon
SoldiersNodRelief
VictimQuietlyEscapes
}
then written_pardon {
WritePardonOrder
SlipItToKnave
KnaveDeliversMercy
EveryonePretendExecutionHappened
}
}
// This is how anyone survives in Wonderland
DecrementActualBeheadingCount
}
// This is how anyone survives in Wonderland
DecrementActualBeheadingCount
}
}

View File

@@ -39,9 +39,9 @@ behavior WhiteRabbit_ConstantlyLate {
---
// Top-level selector: try different panic strategies
? {
choose panic_response {
// Sequence: Check time, panic, flee
> {
then check_time {
CheckPocketWatch
RealizeHowLate
MutterAnxiously
@@ -49,7 +49,7 @@ behavior WhiteRabbit_ConstantlyLate {
}
// Sequence: Encounter obstacle, panic more
> {
then obstacle_panic {
EncounterObstacle
DropGloves
DropFan
@@ -58,7 +58,7 @@ behavior WhiteRabbit_ConstantlyLate {
}
// Sequence: See Queen, extreme panic
> {
then queen_panic {
SpotQueen
FlattenEarsInFear
TremblingBow
@@ -66,7 +66,7 @@ behavior WhiteRabbit_ConstantlyLate {
}
// Fallback: Just keep running
> {
then default_panic {
CheckWatch
RunInCircles
CheckWatchAgain

View File

@@ -0,0 +1,89 @@
//! Schedules for Wonderland characters
//!
//! v0.2.0 upgrade: Adding year-long schedule composition features
//! - Schedule inheritance and composition
//! - Behavior tree references
//! - Recurrence patterns for special events
// Base schedule for court members
schedule CourtSchedule {
block morning_duties { 08:00 -> 12:00, action: CourtDuties }
block lunch { 12:00 -> 13:00, action: Eating }
block afternoon_duties { 13:00 -> 17:00, action: CourtDuties }
block evening_rest { 18:00 -> 22:00, action: Resting }
}
// Queen's schedule (extends court schedule with special blocks)
schedule QueenSchedule extends CourtSchedule {
override morning_duties {
08:00 -> 12:00
action: RuleWithTyranny
mood: "imperious"
}
override afternoon_duties {
13:00 -> 17:00
action: CroquetAndExecutions
}
// Croquet games on specific days
recurrence CroquetDay on Thursday {
block croquet {
14:00 -> 17:00
action: PlayCroquet
mallets: "flamingos"
balls: "hedgehogs"
}
}
}
// Mad Tea Party schedule (perpetually stuck at tea time)
schedule TeaPartySchedule {
block eternal_teatime {
18:00 -> 18:01
action: EndlessTeaParty
time_moves: false
}
recurrence MoveChairs on Daily {
block chair_rotation {
18:00 -> 18:00
action: MoveToNextSeat
}
}
}
// White Rabbit's frantic schedule
schedule RabbitSchedule {
block panic_mode {
00:00 -> 23:59
action: AlwaysLate
anxiety: "extreme"
}
recurrence ImportantDate on FirstOfMonth {
block extra_panic {
06:00 -> 06:30
action: CheckPocketWatch
repetitions: 1000
}
}
}
// Caterpillar's leisurely schedule
schedule CaterpillarSchedule {
block smoke_hookah { 10:00 -> 16:00, action: PhilosophizeOnMushroom }
block metamorphosis_rest { 16:00 -> 23:59, action: Sleeping }
}
// Cheshire Cat's schedule (mostly appearing and disappearing)
schedule CheshireSchedule {
block appear { 00:00 -> 23:59, action: AppearAtRandom }
recurrence GrinningTime on Daily {
block extra_grin {
12:00 -> 12:01
action: LeaveOnlyGrin
}
}
}

View File

@@ -0,0 +1,101 @@
# Baker Family Example
A comprehensive example demonstrating Storybook v0.2.0 features through a realistic multi-character scenario.
## Features Demonstrated
### Resource Linking
- **Templates with behaviors**: `Baker` template specifies `BakingSkills` and `CustomerService`
- **Templates with schedules**: `Baker` template uses `BakerSchedule`
- **Multi-level inheritance**: `Baker``Worker``Person` template chain
- **Character inheritance**: Characters automatically inherit behaviors and schedules from templates
### Schedule Composition
- **Schedule inheritance**: `BakerSchedule extends WorkWeek`
- **Override blocks**: Modify inherited time blocks with `override work { ... }`
- **Named blocks**: All blocks have names for the override system
- **Action references**: Schedule blocks reference behavior trees via `action: BehaviorName`
- **Recurrence patterns**: Market day repeats `on Saturday`
### Behavior Trees
- Comprehensive behavior definitions for all activities
- Referenced from schedule blocks showing integration
- Hierarchical behaviors (sequences, selectors, repeaters)
## File Structure
```
baker-family/
├── README.md # This file
├── schema/
│ └── templates.sb # Template definitions with resource linking
├── schedules/
│ └── work_schedules.sb # Composable schedules
├── behaviors/
│ └── baker_behaviors.sb # Behavior tree definitions
└── characters/
├── martha.sb # Master baker (uses Baker template)
├── john.sb # Pastry chef (uses Baker template)
└── emma.sb # Daughter (uses Child template)
```
## Template Hierarchy
```
Person (behaviors: BasicNeeds, SocialInteraction)
└─> Worker (schedule: WorkWeek)
└─> Baker (behaviors: +BakingSkills, +CustomerService, schedule: BakerSchedule)
└─> Child (behaviors: PlayBehavior, LearnBehavior, no schedule)
```
## Schedule Inheritance
```
WorkWeek
├─ morning_prep (08:00-09:00)
├─ work (09:00-17:00)
└─ evening_rest (18:00-22:00)
BakerSchedule extends WorkWeek
├─ pre_dawn_prep (04:00-05:00) [NEW]
├─ work (05:00-13:00) [OVERRIDE] → action: BakingWork
├─ evening_rest (18:00-22:00) [INHERITED]
└─ recurrence MarketDay on Saturday
└─ market (06:00-14:00) → action: SellAtMarket
```
## Key Integration Points
1. **Martha (character)** → inherits from **Baker (template)**
- Gets behaviors: `BakingSkills`, `CustomerService`, `BasicNeeds`, `SocialInteraction`
- Gets schedule: `BakerSchedule` (which extends `WorkWeek`)
2. **BakerSchedule (schedule)** → references **BakingWork (behavior)**
- `action: BakingWork` in the work block
- Creates link between scheduling and behavior systems
3. **Template chain** → cascading resource inheritance
- `Baker` includes `Worker` includes `Person`
- All behaviors and schedules flow down the hierarchy
## Usage
This example shows how to:
- Build reusable templates with attached behaviors and schedules
- Create character hierarchies representing different roles
- Compose schedules through inheritance and overrides
- Link schedules to behaviors through action references
- Model realistic daily routines with time-of-day variations
- Handle special events (market days) with recurrence patterns
## Narrative Implications
The Baker family example demonstrates:
- **Daily rhythms**: Early morning routine for bakers vs. normal schedule for child
- **Weekly patterns**: Special market day on Saturdays
- **Role-based behaviors**: Bakers have different skill sets than children
- **Family dynamics**: Multiple characters with interrelated but distinct routines
- **Business operations**: Work schedule tied to specific behaviors (baking, selling)
This is the kind of rich, time-based character modeling that makes Storybook ideal for narrative simulations and game design.

View File

@@ -0,0 +1,208 @@
//! Behavior trees for the Baker family
//!
//! These are referenced by schedule blocks via the action: field
// Main baking work routine
behavior BakingWork {
then {
check_orders
prepare_ingredients
choose {
make_bread
make_pastries
make_cakes
}
bake
cool_products
package_goods
}
}
// Kitchen prep routine
behavior PrepKitchen {
then {
clean_surfaces
check_supplies
preheat_ovens
organize_workspace
}
}
// type
concept Vendor;
// type
sub_concept VendorInventory {
Bread: any,
Pastries: any,
Cakes: any,
Cup: any
}
// type (but really just an enum lol)
concept Cup;
// enum
sub_concept CupSize: {
Small,
Medium,
Large
}
// enum
sub_concept CupType: {
Ceramic,
Glass,
Plastic
}
// enum
sub_concept CupColor {
Red,
Blue,
Green
}
// enum comparison done at compile time
concept_comparison CustomerInterestInCups {
Interested: {
CupSize: any, // any means any value of the type can be matched
CupType: CupType is Glass or CupType is Plastic,
CupColor: CupColor is Red or CupColor is Blue
},
NotInterested: {
CupSize: any,
CupType: any,
CupColor: any
},
Maybe: {
CupSize: any,
CupType: any,
CupColor: any
}
}
// type
concept Plate;
// enum
sub_concept PlateColor {
Blue,
Green,
Red
}
// type
concept Customer;
// enum
sub_concept CustomerInterest {
Interested: 10,
NotInterested: 20,
Maybe: 70
}
// Market day selling behavior
behavior SellAtMarket {
repeat {
then {
greet_customer
show_products
if(CustomerInterestInCups.Interested.CupSize is Medium or CupSize is Large and CustomerInterestInCups.Interested.CupType is Glass or CupType is Plastic and CustomerInterestInCups.Interested.CupColor is Red or CupColor is Blue) {
make_sale(Cup)
}
if(CustomerInterestInCups.Interested.CupSize is Small and CustomerInterestInCups.Interested.CupType is Ceramic and CustomerInterestInCups.Interested.CupColor is Green) {
if (Plate.PlateColor is Blue or PlateColor is Green) {
// variadic arguments
make_sale(Cup, Plate)
}
// or there can be generic fallthroughs too
thank_customer
}
}
}
// Assistant work (subset of main baking)
behavior AssistWithBaking {
then {
check_orders
prepare_ingredients
choose {
assist_with_bread
assist_with_pastries
}
clean_workspace
}
}
// Quick morning prep
behavior QuickPrep {
then {
check_supplies
organize_workspace
}
}
concept Hunger;
sub_concept HungerState {
Hungry,
NotHungry
}
// Basic needs (from Person template)
behavior BasicNeeds {
repeat {
choose {
if(HungryState.Hungry) { eat }
if(HungryState.NotHungry) { rest }
if(thirsty) { drink }
}
}
}
// Social interaction
behavior SocialInteraction {
choose {
greet_neighbors
chat_with_customers
family_time
}
}
// Baking skills
behavior BakingSkills {
then {
assess_dough
adjust_recipe
monitor_temperature
}
}
// Customer service
behavior CustomerService {
then {
greet_warmly
listen_to_needs
recommend_products
handle_payment
}
}
// Child behaviors
behavior PlayBehavior {
choose {
play_outside
play_with_toys
draw_pictures
}
}
behavior LearnBehavior {
then {
attend_school
do_homework
read_books
}
}

View File

@@ -0,0 +1,40 @@
//! Emma - The bakers' daughter
//!
//! Demonstrates:
//! - Character using different template (Child vs Baker)
//! - Different behavior set appropriate to age
//! - No work schedule (children don't work)
use schema::templates::Child;
character Emma from Child {
// Personal details
age: 12
// Child-specific traits
school_grade: 7
curiosity: 0.9
// General traits
energy: 0.9
mood: 0.85
---backstory
Emma is the bright, energetic daughter of Martha and John. She loves
helping in the bakery on weekends, though she's not allowed to work
the ovens yet. She's fascinated by the chemistry of baking and often
asks her parents endless questions about why dough rises, how yeast
works, and what makes bread crusty.
At school, she excels in science and math, and dreams of one day
creating her own innovative recipes. For now, she's content to help
package goods and chat with the regular customers who've watched her
grow up.
---
}
// Note: Emma inherits from Child template which:
// - uses behaviors: PlayBehavior, LearnBehavior
// - uses behaviors: BasicNeeds, SocialInteraction (from Person)
// - Has NO work schedule (appropriate for a child)
// - Has different fields than Baker template

View File

@@ -0,0 +1,42 @@
//! Jane - Pastry specialist and Martha's wife
//!
//! Demonstrates:
//! - Another character using the same Baker template
//! - Different field values showcasing template flexibility
//! - Resource inheritance working across multiple characters
use schema::templates::Baker;
character Jane from Baker {
// Personal details
age: 36
// Baker-specific traits
specialty: "pastries"
baking_skill: 0.85
customer_relations: 0.80
// General traits
energy: 0.75
mood: 0.85
// Work ethic
work_ethic: 0.90
occupation: "pastry chef"
---backstory
Jane trained at a culinary school in the capital before returning
to his hometown and meeting Martha. His specialty is delicate
pastries and elaborate wedding cakes. While Martha handles the
bread and business, Jane focuses on the artistic creations that
draw customers from neighboring towns.
He's more of a night owl by nature, but has adapted to the baker's
early schedule over the years. His croissants are legendary.
---
}
// Note: Jane also inherits:
// - All behaviors from Baker template chain
// - BakerSchedule (same early mornings as Martha)
// - All fields with ranges have specific values

View File

@@ -0,0 +1,43 @@
//! Martha - Master baker and family matriarch
//!
//! Demonstrates:
//! - Character inheriting from template with resources
//! - Template provides both behaviors and schedule
//! - Field overrides from template
use schema::templates::Baker;
character Martha from Baker {
// Personal details
age: 34
// Baker-specific traits
specialty: "sourdough"
baking_skill: 0.9
customer_relations: 0.95
// General traits (inherited from Person template)
energy: 0.7
mood: 0.8
// Work ethic (from Worker template)
work_ethic: 0.95
occupation: "master baker"
---backstory
Martha learned to bake from her grandmother and has perfected
the art of sourdough over fifteen years. She wakes at 4 AM every
day to prepare the morning bread, and her bakery is known throughout
the region for its exceptional quality.
She manages the business side as well, keeping meticulous records
and maintaining warm relationships with all her customers. The bakery
is not just a shop - it's the heart of the community.
---
}
// Note: Martha inherits from Baker template which:
// - uses behaviors: BakingSkills, CustomerService (from Baker)
// - uses behaviors: BasicNeeds, SocialInteraction (from Person via Worker)
// - uses schedule: BakerSchedule (from Baker)
// - uses schedule: WorkWeek (base for BakerSchedule)

View File

@@ -0,0 +1,55 @@
//! Work schedules for the Baker family
//!
//! Demonstrates schedule composition features:
//! - extends keyword for schedule inheritance
//! - override blocks to modify inherited schedules
//! - Named blocks for override system
//! - Action references to behavior trees
//! - Recurrence patterns for weekly variations
// Base work schedule (9-5 job)
schedule WorkWeek {
block morning_prep { 08:00 -> 09:00, action: MorningPrep }
block work { 09:00 -> 17:00, action: DailyWork }
block evening_rest { 18:00 -> 22:00, action: Resting }
}
// Baker's schedule extends WorkWeek
schedule BakerSchedule extends WorkWeek {
// Bakers start early - override the work block
override work {
05:00 -> 13:00
action: BakingWork
intensity: "high"
}
// Add pre-dawn prep
block pre_dawn_prep {
04:00 -> 05:00
action: PrepKitchen
}
// Market day on Saturdays
recurrence MarketDay on Saturday {
block market {
06:00 -> 14:00
action: SellAtMarket
place: "town_square"
}
}
}
// Assistant baker schedule (helps during busy times)
schedule AssistantSchedule extends BakerSchedule {
// Assistant comes in later
override work {
06:00 -> 14:00
action: AssistWithBaking
}
// Assistant does a quick prep before work
override pre_dawn_prep {
05:30 -> 06:00
action: QuickPrep
}
}

View File

@@ -0,0 +1,40 @@
//! Template definitions for the Baker family
//!
//! This example demonstrates v0.2.0 features:
//! - Resource linking (uses_behaviors, uses_schedule)
//! - Template inheritance
//! - Multi-level template hierarchies
// Base template for all persons
template Person {
uses behaviors: BasicNeeds, SocialInteraction
age: 0..100
energy: 0.0..1.0
mood: 0.0..1.0
}
// Worker template extends Person
template Worker {
include Person
uses schedule: WorkWeek
occupation: "laborer"
work_ethic: 0.5..1.0
}
// Specialized baker template
template Baker {
include Worker
uses behaviors: BakingSkills, CustomerService
uses schedule: BakerSchedule
specialty: "bread"
baking_skill: 0.0..1.0
customer_relations: 0.5..1.0
}
// Child template (no work schedule)
template Child {
include Person
uses behaviors: PlayBehavior, LearnBehavior
school_grade: 1..12
curiosity: 0.0..1.0
}

View File

@@ -0,0 +1,27 @@
#!/bin/bash
# Quick validation that all Baker family example files parse correctly
echo "Testing Baker family example files..."
echo ""
files=(
"schema/templates.sb"
"schedules/work_schedules.sb"
"behaviors/baker_behaviors.sb"
"characters/martha.sb"
"characters/john.sb"
"characters/emma.sb"
)
for file in "${files[@]}"; do
echo -n "Parsing $file... "
if cargo run --bin storybook -- check "$file" 2>&1 | grep -q "Successfully"; then
echo "✓"
else
echo "✗ (may need storybook CLI to be implemented)"
fi
done
echo ""
echo "Note: This is a manual check. Full validation requires the storybook compiler."
echo "All files use correct v0.2.0 syntax for resource linking and schedule composition."

258
examples/new-syntax-demo.sb Normal file
View File

@@ -0,0 +1,258 @@
//! Demonstration of new behavior tree keyword syntax
//! This file showcases all the new features approved for implementation
// Simple behavior with choose and then
behavior SimpleGuardPatrol {
---description
A village guard who responds to threats or patrols.
Demonstrates basic choose/then keywords.
---
choose patrol_action {
then respond_to_threat {
if(threat_detected)
sound_alarm
rush_to_threat
}
repeat {
then {
patrol_north
patrol_east
patrol_south
patrol_west
}
}
}
}
// Named nodes
behavior ComplexBehavior {
---description
Demonstrates named nodes for better organization and debugging.
Labels help identify which part of the tree is executing.
---
choose root {
then handle_urgent {
when(need.any is urgent)
identify_need
satisfy_need
}
then social_interaction {
when(friend_nearby)
greet_friend
chat
}
then default_activity {
idle_wait
}
}
}
// Advanced decorators
behavior WhiteRabbitAnxiety {
---description
The White Rabbit from Alice in Wonderland, demonstrating
all decorator types: repeat, retry, timeout, cooldown, if.
---
choose {
// Extreme panic when very late
then panic_mode {
if(minutes_late > 100)
timeout(3s) {
repeat(5) {
then {
check_pocket_watch
mutter_desperately
}
}
}
sprint_to_destination
}
// Try to find alternate route when blocked
then find_route {
if(obstacle_encountered)
drop_gloves
drop_fan
retry(2) {
find_alternate_route
}
}
// Queen response with cooldown
then queen_response {
if(queen_nearby)
flatten_ears_in_fear
trembling_bow
cooldown(60s) {
await_commands
}
}
// Only run if energy is sufficient
if(energy > 30) {
scurry_around_frantically
}
// Default: perpetual anxiety
repeat {
then {
check_watch
mutter_anxiously
scurry_forward
}
}
}
}
// Mad Tea Party with infinite repeat
behavior MadTeaParty {
---description
The Mad Hatter's tea party that loops forever.
Demonstrates infinite repeat decorator.
---
repeat {
choose tea_party_activities {
then riddles {
pose_riddle
wait_for_answer
declare_answer_wrong
}
then seat_rotation {
switch_seats
clean_dirty_teacup
pour_fresh_tea
}
then dormouse_interaction {
wake_dormouse
listen_to_brief_story
stuff_dormouse_in_teapot
}
}
}
}
// Cheshire Cat with timing decorators
behavior CheshireCatMaterialization {
---description
Complex behavior with nested decorators showing gradual
materialization and dematerialization with timing controls.
---
choose {
// Materialize when Alice is near
then materialize {
if(alice_nearby and visibility < 0.1)
timeout(10s) {
repeat(5) {
then {
increase_visibility(0.2)
pause_for_effect(1s)
}
}
}
materialize_grin
speak_in_riddles
}
// Dematerialize when fully visible
then dematerialize {
if(visibility > 0.9)
cooldown(30s) {
timeout(8s) {
repeat(5) {
then {
decrease_visibility(0.2)
pause_for_effect(1s)
}
}
}
}
vanish_except_grin
}
// Only float when partially visible
if(visibility >= 0.5) {
idle_float
}
}
}
// Subtree inclusion
behavior WorkBehaviorWithSubtree {
---description
Demonstrates subtree inclusion with the new 'include' keyword.
---
choose {
include common::handle_urgent_needs
then work {
when(at_workplace)
perform_work_tasks
}
idle_wait
}
}
// Invert decorator
behavior AvoidEnemies {
---description
Uses invert decorator to reverse condition logic.
---
choose {
then safe_path {
invert {
if(enemy_nearby)
}
take_direct_route
}
then danger_path {
take_long_safe_route
}
}
}
// Repeat with range
behavior SearchBehavior {
---description
Demonstrates repeat with min..max range.
---
repeat(3..7) {
then {
search_area
rest_briefly
}
}
}
// Always succeed/fail decorators (for debugging)
behavior DebugBehavior {
---description
Shows succeed_always and fail_always decorators.
---
choose {
succeed_always {
experimental_feature
}
fail_always {
disabled_legacy_behavior
}
fallback_behavior
}
}