feat(examples): expand baker-family with relationships and world context

Added comprehensive v0.3.0 feature demonstration:

Characters (5 total):
- Martha & Jane (married lesbian couple, co-owners of bakery)
- Emma (their daughter, apprentice baker)
- Henry (loyal customer, retired teacher)
- Roland (competing baker)

New declarations:
- 6 relationships with asymmetric perspectives (Marriage, ParentChild×2,
  BusinessPartnership, CustomerRelationship, Competition)
- Locations with prose (MarthasBakery, MainStreet)
- Institution (BakersGuild)
- Life arcs (MarriageQuality, BusinessGrowth)

Features demonstrated:
- Concept comparison usage (skill_tier: Master/Journeyman)
- Life arc applied to relationship
- Asymmetric participant perspectives
- Family coherence across files
This commit is contained in:
2026-02-14 15:49:17 +00:00
parent 45fd3b52cb
commit b042f81aeb
13 changed files with 427 additions and 42 deletions

View File

@@ -1,17 +1,50 @@
# Baker Family Example
A comprehensive example demonstrating Storybook v0.3.0 features through a realistic multi-character scenario.
A comprehensive example demonstrating Storybook v0.3.0 features through a realistic multi-character scenario with relationships, locations, institutions, and advanced type system usage.
## Characters
| Character | Age | Role | Template |
|-----------|-----|------|----------|
| Martha | 34 | Master baker, business co-owner | Baker |
| Jane | 36 | Pastry chef, Martha's wife, co-owner | Baker |
| Emma | 12 | Their daughter, science enthusiast | Child |
| Henry | 68 | Retired teacher, loyal customer | Person |
| Roland | 42 | Competing baker from next town | Baker |
Martha and Jane are a married couple who co-run the bakery. Emma is their daughter. Henry and Roland are community members connected to the family through the bakery.
## Features Demonstrated
### Type System (NEW in v0.3.0)
### Type System (v0.3.0)
- **Species definitions**: `species Human { ... }` provides default fields for all human characters
- **Species-based templates**: `template Person: Human { ... }` inherits species fields as base layer
- **Concepts and sub-concepts**: `concept BakedGood` with `sub_concept BakedGood.Category { Bread, Pastry, Cake }`
- **Sub-concept dot notation**: Parent.Name format for clear ownership
- **Concept comparisons**: Compile-time pattern matching for concept variants
- **Concept comparisons**: `SkillLevel` maps skill tiers to quality expectations
- **Life arc requirements**: `life_arc BakerCareer requires { baking_skill: Number }` for compile-time validation
### Relationships
- **Marriage**: Martha and Jane, a lesbian couple with asymmetric bakery roles
- **Parent-Child**: Martha-Emma and Jane-Emma with different parenting styles
- **Business Partnership**: Martha and Jane co-owning and co-running the bakery
- **Customer Relationship**: Martha and Henry (daily loyalty)
- **Competition**: Martha and Roland (rival bakers)
- **Asymmetric perspectives**: Each participant has role-specific fields
### Locations
- **MarthasBakery**: Detailed shop with prose description, capacity, hours
- **MainStreet**: Town thoroughfare connecting market and school
### Institutions
- **BakersGuild**: Trade guild with membership, meetings, and governance
### Life Arcs
- **BakerCareer**: Apprentice -> Journeyman -> Master (skill-based progression)
- **Childhood**: Young child -> School age -> Teenager -> Adult (age-based)
- **MarriageQuality**: Newlywed -> Established -> Deep bond (relationship arc)
- **BusinessGrowth**: Starting out -> Growing -> Thriving (business arc)
### Resource Linking
- **Templates with behaviors**: `Baker` template specifies `BakingSkills` and `CustomerService`
- **Templates with schedules**: `Baker` template uses `BakerSchedule`
@@ -37,16 +70,26 @@ baker-family/
├── README.md
├── schema/
│ ├── templates.sb # Template definitions with species base
│ ├── types.sb # Concepts, sub-concepts, species (NEW)
│ └── life_arcs.sb # Life arc definitions with requires (NEW)
│ ├── types.sb # Concepts, sub-concepts, species, concept comparisons
│ └── life_arcs.sb # Career and childhood life arcs
├── characters/
│ ├── martha.sb # Master baker (Baker template, skill_tier: Master)
│ ├── jane.sb # Pastry chef (Baker template, skill_tier: Journeyman)
│ ├── emma.sb # Daughter (Child template)
│ ├── henry.sb # Retired teacher customer (Person template)
│ └── roland.sb # Competing baker (Baker template)
├── relationships/
│ └── baker_family_relationships.sb # All relationships with asymmetric perspectives
├── locations/
│ └── bakery_locations.sb # MarthasBakery and MainStreet
├── institutions/
│ └── bakers_guild.sb # Trade guild
├── life_arcs/
│ └── family_life_arcs.sb # MarriageQuality and BusinessGrowth arcs
├── schedules/
│ └── work_schedules.sb # Composable schedules
── behaviors/
└── baker_behaviors.sb # Behavior tree definitions
└── characters/
├── martha.sb # Master baker (uses Baker template)
├── jane.sb # Pastry chef (uses Baker template)
└── emma.sb # Daughter (uses Child template)
── behaviors/
└── baker_behaviors.sb # Behavior tree definitions
```
## Template Hierarchy
@@ -54,14 +97,33 @@ baker-family/
```
Human (species - default fields: age, energy, mood, occupation)
└─> Person: Human (behaviors: BasicNeeds, SocialInteraction)
─> Worker (schedule: WorkWeek)
└─> Baker (behaviors: +BakingSkills, +CustomerService, schedule: BakerSchedule)
─> Worker (schedule: WorkWeek)
└─> Baker (behaviors: +BakingSkills, +CustomerService, schedule: BakerSchedule)
│ ├── Martha (skill_tier: Master)
│ ├── Jane (skill_tier: Journeyman)
│ └── Roland (skill_tier: Journeyman)
└─> Child: Human (behaviors: PlayBehavior, LearnBehavior, no schedule)
└── Emma
└─> Henry (Person, retired, no work schedule)
```
Override chain: Species -> Includes -> Template -> Character (last-one-wins)
## Relationship Map
```
Martha ──── Marriage ──── Jane
│ BusinessPartnership │
│ │
├── ParentChild ── Emma ───┘
├── CustomerRelationship ── Henry
└── Competition ── Roland
```
## Schedule Inheritance
```
@@ -78,7 +140,7 @@ BakerSchedule extends WorkWeek
└─ market (06:00-14:00) -> action: SellAtMarket
```
## Life Arcs (NEW in v0.3.0)
## Life Arcs
```
BakerCareer requires { baking_skill: Number, work_ethic: Number }
@@ -87,27 +149,41 @@ BakerCareer requires { baking_skill: Number, work_ethic: Number }
Childhood requires { age: Number, curiosity: Number }
young_child -> school_age -> teenager -> adult
MarriageQuality requires { relationship_quality: Number, years_together: Number }
newlywed -> established -> deep_bond
BusinessGrowth requires { customer_relations: Number, baking_skill: Number }
starting_out -> growing -> thriving
```
## Concept Comparison: SkillLevel
Maps baking skill tiers to quality expectations:
- **Apprentice**: Any freshness level acceptable while learning
- **Journeyman**: Any freshness level expected as standard
- **Master**: Must produce fresh goods to meet the standard
## Key Integration Points
1. **Martha (character)** -> inherits from **Baker (template)** -> inherits from **Human (species)**
- Gets default fields from Human species (age, energy, mood, occupation)
- Gets behaviors: `BakingSkills`, `CustomerService`, `BasicNeeds`, `SocialInteraction`
- Gets schedule: `BakerSchedule` (which extends `WorkWeek`)
- Has `skill_tier: Master` for concept comparison mapping
2. **BakerSchedule (schedule)** -> references **BakingWork (behavior)**
- `action: BakingWork` in the work block
- Creates link between scheduling and behavior systems
2. **Relationships** -> connect characters with asymmetric perspectives
- Martha and Jane's Marriage and BusinessPartnership show the same couple in different roles
- Each participant has role-specific fields
- Competition relationship shows non-familial connections
3. **Template chain** -> cascading resource inheritance with species base
- `Human` species provides defaults
- `Baker` includes `Worker` includes `Person: Human`
- All behaviors, schedules, and fields flow down the hierarchy
3. **Locations** -> provide narrative context with prose descriptions
- `MarthasBakery` is referenced by schedules and behaviors
- `MainStreet` connects the bakery to the wider community
4. **Life arcs** -> compile-time field requirement validation
- `BakerCareer` requires `baking_skill` and `work_ethic` fields
- Any character using this life arc must have these fields
4. **Life arcs** -> track progression across multiple dimensions
- Career (BakerCareer), personal growth (Childhood)
- Relationship quality (MarriageQuality), business success (BusinessGrowth)
## Usage
@@ -117,6 +193,8 @@ This example shows how to:
- Use concepts and sub-concepts for type-safe enumerations
- Create concept comparisons for compile-time pattern matching
- Define life arcs with field requirements for validation
- Model relationships with asymmetric participant perspectives
- Create locations and institutions with prose descriptions
- Compose schedules through inheritance and overrides
- Link schedules to behaviors through action references
- Model realistic daily routines with time-of-day variations

View File

@@ -20,16 +20,17 @@ character Emma from Child {
mood: 0.85
---backstory
Emma is the bright, energetic daughter of Martha and John. She loves
Emma is the bright, energetic daughter of Martha and Jane. 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
asks her mothers 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.
creating her own innovative recipes. She learns the science of bread
from Martha and the art of decoration from Jane. For now, she's
content to help package goods and chat with the regular customers
who've watched her grow up.
---
}

View File

@@ -0,0 +1,29 @@
//! Henry - Loyal customer and retired teacher
//!
//! Demonstrates:
//! - Non-family character in the community
//! - Minimal template usage (Person, no work schedule)
//! - Community connection through the bakery
use schema::templates::Person;
character Henry from Person {
// Personal details
age: 68
// General traits
energy: 0.5
mood: 0.75
---backstory
Henry taught history at the local school for over forty years before
retiring. He has been a daily customer at the bakery since Martha
first opened its doors. Every morning at precisely seven o'clock,
he arrives for a sourdough loaf and a chat.
He watched Emma grow up and occasionally helps her with her homework
when he stops by. The bakery is his anchor to the community now that
he no longer teaches. Martha always sets aside his favorite loaf,
and Jane saves him a croissant on Saturdays.
---
}

View File

@@ -15,6 +15,7 @@ character Jane from Baker {
specialty: "pastries"
baking_skill: 0.85
customer_relations: 0.80
skill_tier: Journeyman
// General traits
energy: 0.75
@@ -26,13 +27,13 @@ character Jane from Baker {
---backstory
Jane trained at a culinary school in the capital before returning
to his hometown and meeting Martha. His specialty is delicate
to her hometown and meeting Martha. Her 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.
She is more of a night owl by nature, but has adapted to the baker's
early schedule over the years. Her croissants are legendary.
---
}

View File

@@ -15,6 +15,7 @@ character Martha from Baker {
specialty: "sourdough"
baking_skill: 0.9
customer_relations: 0.95
skill_tier: Master
// General traits (inherited from Person template)
energy: 0.7

View File

@@ -0,0 +1,40 @@
//! Roland - Competing baker from the next town
//!
//! Demonstrates:
//! - Rival/competitor character
//! - Same template (Baker) with different values
//! - Concept comparison usage with skill_tier
use schema::templates::Baker;
character Roland from Baker {
// Personal details
age: 42
// Baker-specific traits
specialty: "rye bread"
baking_skill: 0.75
customer_relations: 0.60
skill_tier: Journeyman
// General traits
energy: 0.80
mood: 0.65
// Work ethic
work_ethic: 0.80
occupation: "baker"
---backstory
Roland runs a bakery in the neighboring town. He learned baking from
his father and considers himself the rightful best baker in the region.
His rye bread is excellent, but he lacks Martha's warmth with customers
and Jane's artistic flair.
He sees Martha's bakery as his chief competition and often tries to
undercut her prices at the market. Despite the rivalry, there is a
grudging respect between them. Roland once admitted, after too much
ale at the harvest festival, that Martha's sourdough was better than
his own.
---
}

View File

@@ -0,0 +1,26 @@
//! Baker's Guild institution
//!
//! Demonstrates:
//! - Institution declaration with fields
//! - Organizational structure for the baking trade
//! - Connection to characters through membership
institution BakersGuild {
type: "trade guild"
founded: 1823
members: 12
meeting_day: "first Monday"
---description
The regional Baker's Guild oversees standards and practices for all
bakers in the area. Martha is a senior member and has served on the
quality committee for five years. Roland is also a member, though
he frequently clashes with Martha over proposed changes to the
guild's standards.
The guild meets monthly at the town hall to discuss flour prices,
apprenticeship standards, and preparations for seasonal festivals.
Henry, as a retired teacher, occasionally gives talks on the history
of baking in the region.
---
}

View File

@@ -0,0 +1,52 @@
//! Life arcs applied to relationships and family dynamics
//!
//! Demonstrates:
//! - Life arc applied to relationship quality
//! - Life arc for business growth
//! - State transitions driven by numeric fields
// Marriage quality over time
life_arc MarriageQuality requires { relationship_quality: Number, years_together: Number } {
state newlywed {
on enter {
relationship_quality: 0.85
}
on years_together > 3 and relationship_quality > 0.7 -> established
}
state established {
on enter {
relationship_quality: 0.90
}
on years_together > 10 and relationship_quality > 0.85 -> deep_bond
}
state deep_bond {
on enter {
relationship_quality: 0.95
}
}
}
// Business growth arc for the bakery
life_arc BusinessGrowth requires { customer_relations: Number, baking_skill: Number } {
state starting_out {
on enter {
customer_relations: 0.5
}
on customer_relations > 0.7 and baking_skill > 0.6 -> growing
}
state growing {
on enter {
customer_relations: 0.75
}
on customer_relations > 0.9 and baking_skill > 0.8 -> thriving
}
state thriving {
on enter {
customer_relations: 0.95
}
}
}

View File

@@ -0,0 +1,37 @@
//! Locations for the Baker family
//!
//! Demonstrates:
//! - Location declarations with fields
//! - Prose descriptions for narrative context
//! - Locations referenced by schedules and characters
location MarthasBakery {
capacity: 30
type: "shop"
open_hours: "04:00-14:00"
---description
A warm, stone-walled bakery on the corner of Main Street. The front
room has a long wooden counter built from reclaimed oak, with glass
display cases showing the day's offerings. Behind it, the kitchen
holds two large brick ovens, a prep area with marble counters, and
shelves lined with flour, sugar, and spices.
The smell of fresh bread seeps out through the door from before dawn,
drawing the earliest risers. A small chalkboard by the entrance lists
the day's specials in Jane's elegant handwriting.
---
}
location MainStreet {
type: "road"
foot_traffic: 0.8
---description
The main thoroughfare of the town, lined with shops and homes. The
bakery sits at the busiest corner, where the road from the market
square meets the lane leading to the school. On market days, stalls
extend down the street and the air fills with the sounds of haggling
and laughter.
---
}

View File

@@ -0,0 +1,96 @@
//! Relationships for the Baker family
//!
//! Demonstrates:
//! - Multiple relationship types
//! - Asymmetric participant perspectives (roles)
//! - Participant-specific fields
//! - Shared relationship fields
// Marriage between Martha and Jane
relationship Marriage {
Martha as wife {
commitment: 0.95
role_in_bakery: "business and bread"
}
Jane as wife {
commitment: 0.95
role_in_bakery: "pastries and cakes"
}
years_together: 14
relationship_quality: 0.90
}
// Martha and Emma - parent/child
relationship ParentChild_MarthaEmma {
Martha as parent {
parenting_style: "encouraging"
teaches: "baking fundamentals"
}
Emma as child {
admiration: 0.9
learns_from: "baking science"
}
}
// Jane and Emma - parent/child
relationship ParentChild_JaneEmma {
Jane as parent {
parenting_style: "creative"
teaches: "pastry decoration"
}
Emma as child {
admiration: 0.85
learns_from: "artistic expression"
}
}
// Martha and Jane - business partnership (they co-run the bakery)
relationship BusinessPartnership {
Martha as co_owner {
domain: "bread and business"
manages: "operations and suppliers"
}
Jane as co_owner {
domain: "pastries and presentation"
manages: "menu design and displays"
}
partnership_strength: 0.95
}
// Henry as loyal customer
relationship CustomerRelationship {
Martha as baker {
service_priority: "high"
reserved_item: "sourdough loaf"
}
Henry as customer {
loyalty: 0.95
daily_visit: true
favorite_item: "sourdough"
}
years_as_customer: 8
}
// Roland and Martha - business competition
relationship Competition {
Martha as competitor {
market_share: 0.65
advantage: "customer loyalty"
}
Roland as competitor {
market_share: 0.35
advantage: "lower prices"
}
intensity: 0.70
mutual_respect: 0.40
}

View File

@@ -33,9 +33,19 @@ sub_concept SkillLevel.Tier {
Master
}
// Concept comparison - compile-time mapping of skill tiers to defaults
// Concept comparison - compile-time mapping of skill tiers to quality expectations
// An Apprentice can produce any quality; a Master must produce fresh goods
concept_comparison SkillLevel {
Apprentice: { baking_skill: any },
Journeyman: { baking_skill: any },
Master: { baking_skill: any }
Apprentice: {
baking_skill: Tier is Apprentice,
freshness: any
},
Journeyman: {
baking_skill: Tier is Journeyman,
freshness: any
},
Master: {
baking_skill: Tier is Master,
freshness: Tier is Master
}
}

View File

@@ -13,6 +13,12 @@ files=(
"characters/martha.sb"
"characters/jane.sb"
"characters/emma.sb"
"characters/henry.sb"
"characters/roland.sb"
"relationships/baker_family_relationships.sb"
"locations/bakery_locations.sb"
"institutions/bakers_guild.sb"
"life_arcs/family_life_arcs.sb"
)
for file in "${files[@]}"; do
@@ -26,4 +32,4 @@ done
echo ""
echo "Note: This is a manual check. Full validation requires the storybook compiler."
echo "All files use correct v0.3.0 syntax with type system, species inheritance, and life arcs."
echo "All files use correct v0.3.0 syntax with type system, relationships, locations, and life arcs."

View File

@@ -34,9 +34,9 @@ fn load_example(name: &str) -> Project {
fn test_baker_family_loads_successfully() {
let project = load_example("baker-family");
// Should have exactly 3 characters
// Should have exactly 5 characters
let char_count = project.characters().count();
assert_eq!(char_count, 3, "Baker family should have 3 characters");
assert_eq!(char_count, 5, "Baker family should have 5 characters");
// Verify all characters exist
assert!(
@@ -51,6 +51,14 @@ fn test_baker_family_loads_successfully() {
project.find_character("Emma").is_some(),
"Emma should exist"
);
assert!(
project.find_character("Henry").is_some(),
"Henry should exist"
);
assert!(
project.find_character("Roland").is_some(),
"Roland should exist"
);
}
#[test]