Files
storybook/design/year-long-schedule-system.md
Sienna Meridian Satterwhite 16deb5d237 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
2026-02-13 21:52:03 +00:00

1017 lines
26 KiB
Markdown

# Year-Long Composable Schedule System Design
**Author:** Resource Linking Architect (Schedule System Designer)
**Date:** 2026-02-12
**Status:** Draft for Review
**Version:** 0.1
**Related:** Resource Linking System Design (Task #8)
---
## Executive Summary
This document proposes a **year-long, composable schedule system** for the Storybook DSL that extends the current simple daily schedules to support:
- **Temporal composition**: Days → Weeks → Months → Seasons → Year
- **Template inheritance**: Schedules extend and override like behavior templates
- **Seasonal variations**: Winter/summer hours, holiday schedules
- **Event overrides**: Special occasions, one-off modifications
- **Integration with resource linking**: Works seamlessly with `uses schedule:` syntax
The design enables both simple daily routines and complex year-long patterns while maintaining readability and composability.
---
## 1. Current State & Limitations
### 1.1 Existing Schedule Syntax
**Current (Simple Daily Schedule):**
```storybook
schedule MadTeaPartyRotation {
18:00 -> 18:01: TeaRound {
---narrative
Begin a new rotation...
---
}
18:01 -> 18:02: RiddlePhase { ... }
18:02 -> 18:03: ContradictionPhase { ... }
}
```
**Current AST:**
```rust
pub struct Schedule {
pub name: String,
pub blocks: Vec<ScheduleBlock>, // Flat list
pub span: Span,
}
pub struct ScheduleBlock {
pub start: Time, // HH:MM
pub end: Time, // HH:MM
pub activity: String,
pub fields: Vec<Field>,
pub span: Span,
}
```
### 1.2 Limitations
1. **No composition**: Can't build a weekly schedule from daily templates
2. **No inheritance**: Can't extend a base schedule and customize
3. **No temporal hierarchy**: Can't express "weekday vs weekend" patterns
4. **No seasonal variation**: Can't say "summer hours vs winter hours"
5. **No override system**: Can't modify specific blocks while keeping others
6. **No year-long support**: Limited to repeating daily patterns
### 1.3 Use Cases Not Supported
**Use Case 1: Seasonal Business Hours**
```
Bakery is open 6:00-20:00 in summer, 7:00-18:00 in winter
```
**Use Case 2: Weekday vs Weekend**
```
Martha works Monday-Friday, rests Saturday-Sunday
```
**Use Case 3: Holiday Override**
```
Martha follows BakerSchedule normally, but FullRest on Christmas
```
**Use Case 4: Life Arc Changes**
```
Martha's schedule changes when she becomes Elder (retires)
```
---
## 2. Design Goals
### 2.1 Primary Goals
1. **Hierarchical Composition**: Build complex schedules from simple parts
2. **Template Inheritance**: Extend and customize like behavior templates
3. **Temporal Flexibility**: Express daily, weekly, seasonal, yearly patterns
4. **Override System**: Modify specific aspects while keeping others
5. **Backward Compatible**: Current simple schedules still work
6. **Integration**: Seamless with `uses schedule:` linking
### 2.2 Non-Goals
1. **Real-time scheduling**: Schedules are static patterns, not dynamic
2. **Calendar systems**: Focus on patterns, not specific date handling
3. **Time zones**: All times are game-world local
4. **Procedural generation**: Schedules are authored, not generated
---
## 3. Proposed Architecture
### 3.1 Time Hierarchy (yes, but i want to make this user-composable so they're not locked into gregorian, euro-centric calendars. idk how we would do that, but like Lonni wants 8 seasons... maybe the schedule constants (years/months/days/weeks/seasons/etc) can be configured in the storybook.toml? idk how to handle this)
```
Year (365 days)
├─ Season (Winter, Spring, Summer, Fall)
│ └─ Month (Jan, Feb, ..., Dec)
│ └─ Week (7-day cycle)
│ └─ Day (24-hour period)
│ └─ Block (time range + activity)
```
### 3.2 Schedule Types
**Daily Schedule** - Single 24-hour pattern:
```storybook
schedule SimpleDay {
block sleep { 0:00 - 6:00, activity: sleep }
block work { 9:00 - 17:00, activity: work }
block leisure { 17:00 - 22:00, activity: leisure }
block sleep { 22:00 - 24:00, activity: sleep }
}
```
**Weekly Schedule** - 7-day pattern with day variations:
```storybook
schedule WorkWeek {
weekday (mon, tue, wed, thu, fri) {
block work { 9:00 - 17:00, activity: work }
block leisure { 17:00 - 22:00, activity: leisure }
}
weekend (sat, sun) {
block leisure { 10:00 - 22:00, activity: leisure }
}
}
```
**Seasonal Schedule** - Patterns that change by season:
```storybook
schedule BakeryHours {
season summer {
block open { 6:00 - 20:00, activity: work }
}
season winter {
block open { 7:00 - 18:00, activity: work }
}
}
```
**Yearly Schedule** - Full year with events and overrides:
```storybook
schedule AnnualPattern extends WorkWeek {
event Christmas on Dec 25 {
block rest { 0:00 - 24:00, activity: rest }
}
event NewYear on Jan 1 {
block celebration { 0:00 - 24:00, activity: celebrate }
}
}
```
---
## 4. Composition System (i just want `override` support, we can yank `remove` and `append` and `remove all`, but `extends` is good)
### 4.1 Template Inheritance with `extends`
**Base Schedule:**
```storybook
schedule BaseWorkday {
block sleep { 0:00 - 6:00, activity: sleep }
block work { 9:00 - 17:00, activity: work }
block leisure { 17:00 - 22:00, activity: leisure }
block sleep { 22:00 - 24:00, activity: sleep }
}
```
**Extended Schedule:**
```storybook
schedule BakerSchedule extends BaseWorkday {
override work { 5:00 - 13:00 } // Earlier hours
append baking { 3:00 - 5:00, activity: prepare }
}
```
**Result:**
```
Block baking: 3:00 - 5:00 (prepare)
Block work: 5:00 - 13:00 (work) ← overridden
Block leisure: 17:00 - 22:00 (leisure) ← inherited
Block sleep: 22:00 - 24:00 + 0:00 - 6:00 (sleep) ← inherited
```
### 4.2 Override Operators
**`override <block> { fields }`** - Replace specific block properties:
```storybook
schedule BakerSchedule extends BaseWorkday {
override work {
time: 5:00 - 13:00,
location: Bakery
}
}
```
**`remove <block>`** - Delete inherited block:
```storybook
schedule RetiredSchedule extends BaseWorkday {
remove work // No more work!
}
```
**`append <block> { fields }`** - Add new block:
```storybook
schedule ExtendedDay extends BaseWorkday {
append meditation { 5:00 - 5:30, activity: meditate }
}
```
**`replace all`** - Complete replacement (no inheritance):
```storybook
schedule FullRest {
replace all
block rest { 0:00 - 24:00, activity: rest }
}
```
### 4.3 Multi-Level Inheritance
```storybook
schedule Base {
block work { 9:00 - 17:00, activity: work }
}
schedule WorkerSchedule extends Base {
override work { 8:00 - 16:00 }
}
schedule SeniorWorkerSchedule extends WorkerSchedule {
override work { 9:00 - 15:00 } // Shorter hours
}
// Result: work is 9:00 - 15:00 (SeniorWorker's version wins)
```
**Merge Rules (Same as Behavior Linking):**
- Character schedules override template schedules by block name
- Most specific schedule wins
- Concatenation + override-by-name
---
## 5. Temporal Patterns
### 5.1 Day-of-Week Patterns (not `activity` but `action` or `behavior` references)
**Simple Weekday/Weekend Split:**
```storybook
schedule WorkWeek {
weekday (mon, tue, wed, thu, fri) extends BaseWorkday {
// Monday-Friday use BaseWorkday
}
weekend (sat, sun) {
block leisure { 8:00 - 22:00, activity: leisure }
block sleep { 22:00 - 8:00, activity: sleep }
}
}
```
**Day-Specific Customization:**
```storybook
schedule DetailedWeek {
on monday extends WorkdaySchedule {
append meeting { 9:00 - 10:00, activity: meeting }
}
on friday extends WorkdaySchedule {
override work { 9:00 - 15:00 } // Early finish!
}
on saturday {
block market { 8:00 - 12:00, activity: shopping }
block leisure { 12:00 - 22:00, activity: leisure }
}
on sunday {
block church { 10:00 - 11:00, activity: worship }
block family { 11:00 - 18:00, activity: social }
}
}
```
### 5.2 Seasonal Patterns
**Basic Seasonal Split:**
```storybook
schedule SeasonalWork {
season (spring, summer) {
block work { 6:00 - 14:00, activity: outdoor_work }
}
season (fall, winter) {
block work { 8:00 - 16:00, activity: indoor_work }
}
}
```
**Season-Specific Schedules:**
```storybook
schedule FarmerSchedule {
season spring {
on weekday { block planting { 5:00 - 18:00, activity: plant } }
}
season summer {
on weekday { block tending { 6:00 - 16:00, activity: tend } }
}
season fall {
on weekday { block harvest { 5:00 - 19:00, activity: harvest } }
}
season winter {
on weekday { block planning { 9:00 - 15:00, activity: plan } }
}
}
```
### 5.3 Event Overrides (`event` is interesting)
**Holiday Definitions:**
```storybook
schedule AnnualSchedule extends WorkWeek {
event Christmas on Dec 25 {
block family { 0:00 - 24:00, activity: family_time }
}
event NewYear on Jan 1 {
block celebration { 0:00 - 24:00, activity: celebrate }
}
event Birthday on Jun 15 {
block party { 18:00 - 22:00, activity: celebrate }
}
}
```
**Recurring Events:** (hmmmmmmmmmm sell me on this one.)
```storybook
schedule MarketSchedule extends BaseSchedule {
every saturday {
block market { 8:00 - 13:00, activity: sell_at_market }
}
every first_monday_of_month {
block guild_meeting { 19:00 - 21:00, activity: meeting }
}
}
```
---
## 6. AST Design
### 6.1 Extended Schedule Structure
```rust
// In src/syntax/ast.rs
#[derive(Debug, Clone, PartialEq)]
pub struct Schedule {
pub name: String,
pub extends: Option<Vec<String>>, // NEW: extends BaseSchedule
pub items: Vec<ScheduleItem>, // NEW: blocks, patterns, events
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub enum ScheduleItem {
Block(ScheduleBlock), // Direct block definition
Override(ScheduleOverride), // override block_name { ... }
Remove(String), // remove block_name
Append(ScheduleBlock), // append new_block { ... }
ReplaceAll, // replace all
WeekdayPattern(WeekdayPattern), // weekday (...) { ... }
DayPattern(DayPattern), // on monday { ... }
SeasonPattern(SeasonPattern), // season summer { ... }
EventPattern(EventPattern), // event Name on Date { ... }
}
#[derive(Debug, Clone, PartialEq)]
pub struct ScheduleBlock {
pub name: Option<String>, // Optional block name
pub start: Time,
pub end: Time,
pub activity: String,
pub fields: Vec<Field>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ScheduleOverride {
pub block_name: String,
pub fields: Vec<OverrideField>, // time, activity, location, etc.
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct WeekdayPattern {
pub days: Vec<DayOfWeek>, // [mon, tue, wed]
pub extends: Option<Vec<String>>, // Optional base schedule
pub blocks: Vec<ScheduleBlock>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct DayPattern {
pub day: DayOfWeek, // monday
pub extends: Option<Vec<String>>,
pub blocks: Vec<ScheduleBlock>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct SeasonPattern {
pub seasons: Vec<Season>, // [spring, summer]
pub blocks: Vec<ScheduleBlock>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct EventPattern {
pub name: String, // "Christmas"
pub date: DateSpec, // Dec 25 or every saturday
pub blocks: Vec<ScheduleBlock>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub enum DayOfWeek {
Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Season {
Spring, Summer, Fall, Winter,
}
#[derive(Debug, Clone, PartialEq)]
pub enum DateSpec {
SpecificDate { month: u8, day: u8 }, // Dec 25
Recurring(RecurringPattern), // every saturday
}
#[derive(Debug, Clone, PartialEq)]
pub enum RecurringPattern {
EveryWeekday(DayOfWeek), // every saturday
FirstDayOfMonth(DayOfWeek), // first monday of month
LastDayOfMonth(DayOfWeek), // last friday of month
}
```
---
## 7. Grammar Design (LALRPOP)
### 7.1 Schedule Productions
```lalrpop
// In parser.lalrpop
pub Schedule: Schedule = {
"schedule" <name:Ident> <extends:ExtendsClause?> "{"
<items:ScheduleItem*>
"}" => Schedule { name, extends, items, span }
};
ExtendsClause: Vec<String> = {
"extends" <QualifiedPath>
};
ScheduleItem: ScheduleItem = {
<ScheduleBlock> => ScheduleItem::Block(<>),
<ScheduleOverride> => ScheduleItem::Override(<>),
<RemoveStmt> => ScheduleItem::Remove(<>),
<AppendStmt> => ScheduleItem::Append(<>),
<ReplaceAllStmt> => ScheduleItem::ReplaceAll,
<WeekdayPattern> => ScheduleItem::WeekdayPattern(<>),
<DayPattern> => ScheduleItem::DayPattern(<>),
<SeasonPattern> => ScheduleItem::SeasonPattern(<>),
<EventPattern> => ScheduleItem::EventPattern(<>),
};
// Basic block: 9:00 - 17:00: Work { activity: work }
ScheduleBlock: ScheduleBlock = {
<start:Time> "-" <end:Time> ":" <name:Ident?> "{"
<fields:Field*>
"}" => ScheduleBlock { name, start, end, fields, span }
};
// Override: override work { time: 5:00 - 13:00 }
ScheduleOverride: ScheduleOverride = {
"override" <block_name:Ident> "{"
<fields:OverrideField*>
"}" => ScheduleOverride { block_name, fields, span }
};
// Remove: remove block_name
RemoveStmt: String = {
"remove" <Ident>
};
// Append: append new_block { 5:00 - 6:00, activity: meditate }
AppendStmt: ScheduleBlock = {
"append" <ScheduleBlock>
};
// Replace all blocks
ReplaceAllStmt = {
"replace" "all"
};
// Weekday pattern: weekday (mon, tue, wed) { blocks }
WeekdayPattern: WeekdayPattern = {
"weekday" "(" <days:Comma<DayOfWeek>> ")" <extends:ExtendsClause?> "{"
<blocks:ScheduleBlock*>
"}" => WeekdayPattern { days, extends, blocks, span }
};
// Day pattern: on monday { blocks }
DayPattern: DayPattern = {
"on" <day:DayOfWeek> <extends:ExtendsClause?> "{"
<blocks:ScheduleBlock*>
"}" => DayPattern { day, extends, blocks, span }
};
// Season pattern: season summer { blocks }
SeasonPattern: SeasonPattern = {
"season" "(" <seasons:Comma<Season>> ")" "{"
<blocks:ScheduleBlock*>
"}" => SeasonPattern { seasons, blocks, span }
};
// Event pattern: event Christmas on Dec 25 { blocks }
EventPattern: EventPattern = {
"event" <name:Ident> "on" <date:DateSpec> "{"
<blocks:ScheduleBlock*>
"}" => EventPattern { name, date, blocks, span }
};
DayOfWeek: DayOfWeek = {
"monday" => DayOfWeek::Monday,
"tuesday" => DayOfWeek::Tuesday,
"wednesday" => DayOfWeek::Wednesday,
"thursday" => DayOfWeek::Thursday,
"friday" => DayOfWeek::Friday,
"saturday" => DayOfWeek::Saturday,
"sunday" => DayOfWeek::Sunday,
"mon" => DayOfWeek::Monday, // Short forms
"tue" => DayOfWeek::Tuesday,
"wed" => DayOfWeek::Wednesday,
"thu" => DayOfWeek::Thursday,
"fri" => DayOfWeek::Friday,
"sat" => DayOfWeek::Saturday,
"sun" => DayOfWeek::Sunday,
};
Season: Season = {
"spring" => Season::Spring,
"summer" => Season::Summer,
"fall" => Season::Fall,
"winter" => Season::Winter,
};
DateSpec: DateSpec = {
<month:Month> <day:Integer> => DateSpec::SpecificDate { month, day },
"every" <DayOfWeek> => DateSpec::Recurring(RecurringPattern::EveryWeekday(<>)),
"every" "first" <DayOfWeek> "of" "month" =>
DateSpec::Recurring(RecurringPattern::FirstDayOfMonth(<>)),
};
```
---
## 8. Resolution & Merging
### 8.1 Schedule Merge Algorithm
**Same as Behavior Merging:**
1. Resolve `extends` reference to base schedule
2. Collect base schedule's blocks
3. Apply overrides/removes/appends from extending schedule
4. Override by block name (not by time)
5. Handle multi-level inheritance recursively
```rust
fn merge_schedules(
child: &Schedule,
parent: &Schedule,
) -> ResolvedSchedule {
let mut blocks = HashMap::new();
// Step 1: Add parent blocks
for block in &parent.blocks {
if let Some(name) = &block.name {
blocks.insert(name.clone(), block.clone());
}
}
// Step 2: Apply child modifications
for item in &child.items {
match item {
ScheduleItem::Block(block) => {
if let Some(name) = &block.name {
blocks.insert(name.clone(), block.clone());
}
}
ScheduleItem::Override(ovr) => {
if let Some(block) = blocks.get_mut(&ovr.block_name) {
apply_override(block, ovr);
}
}
ScheduleItem::Remove(name) => {
blocks.remove(name);
}
ScheduleItem::ReplaceAll => {
blocks.clear();
}
// ... handle patterns
}
}
ResolvedSchedule { blocks: blocks.into_values().collect() }
}
```
### 8.2 Pattern Resolution
**Weekday Patterns** expand to 7 day-specific schedules: (we have to account for user-defined story constants)
```storybook
weekday (mon, tue, wed, thu, fri) {
block work { 9:00 - 17:00 }
}
// Expands to:
// monday: { work { 9:00 - 17:00 } }
// tuesday: { work { 9:00 - 17:00 } }
// ...
```
**Season Patterns** apply conditionally at runtime based on current season.
**Event Patterns** override specific days when event matches.
---
## 9. Integration with Resource Linking
### 9.1 Simple Case
```storybook
schedule BakerSchedule {
block work { 5:00 - 13:00, activity: work }
block lunch { 13:00 - 14:00, activity: eat }
block rest { 14:00 - 22:00, activity: rest }
}
character Martha: Human {
uses schedule: BakerSchedule
}
```
### 9.2 Conditional Schedule Linking
```storybook
schedule WorkdaySchedule {
block work { 9:00 - 17:00, activity: work }
}
schedule WeekendSchedule {
block leisure { 10:00 - 22:00, activity: leisure }
}
character Martha: Human {
uses schedules: [
{ schedule: WorkdaySchedule, when: day_of_week is weekday } (hmmmm i like this but we need to scope how we handle abstract constructs like `day_of_week` because that's arbitrary)
{ schedule: WeekendSchedule, when: day_of_week is weekend }
]
}
```
### 9.3 Seasonal Schedules
```storybook
schedule SummerHours {
block open { 6:00 - 20:00, activity: work }
}
schedule WinterHours {
block open { 7:00 - 18:00, activity: work }
}
institution Bakery {
uses schedules: [
{ schedule: SummerHours, when: season == summer } (we have to figure out how to define seasons)
{ schedule: WinterHours, when: season == winter }
]
}
```
---
## 10. Examples
### Example 1: Simple Daily Schedule (Backward Compatible)
```storybook
schedule SimpleDay {
block sleep { 0:00 - 6:00, activity: sleep }
block work { 9:00 - 17:00, activity: work }
block leisure { 17:00 - 22:00, activity: leisure }
block sleep { 22:00 - 24:00, activity: sleep }
}
```
### Example 2: Schedule with Override
```storybook
schedule BaseWorkday {
block sleep { 0:00 - 6:00, activity: sleep }
block work { 9:00 - 17:00, activity: work }
block leisure { 17:00 - 22:00, activity: leisure }
block sleep { 22:00 - 24:00, activity: sleep }
}
schedule BakerSchedule extends BaseWorkday {
override work { time: 5:00 - 13:00, location: Bakery }
append prep { time: 3:00 - 5:00, activity: bake_prep }
}
```
### Example 3: Weekly Pattern
```storybook
schedule WorkWeek {
weekday (mon, tue, wed, thu, fri) {
block work { 9:00 - 17:00, activity: work }
block leisure { 17:00 - 22:00, activity: leisure }
}
weekend (sat, sun) {
block leisure { 10:00 - 22:00, activity: leisure }
}
}
```
### Example 4: Seasonal Business Hours
```storybook
schedule BakeryHours {
season (spring, summer) {
block open { 6:00 - 20:00, activity: serve_customers }
block prep { 4:00 - 6:00, activity: bake_bread }
}
season (fall, winter) {
block open { 7:00 - 18:00, activity: serve_customers }
block prep { 5:00 - 7:00, activity: bake_bread }
}
}
```
### Example 5: Full Year with Events
```storybook
schedule AnnualSchedule extends WorkWeek {
event Christmas on Dec 25 {
block family { 0:00 - 24:00, activity: family_time }
}
event NewYear on Jan 1 {
block celebration { 0:00 - 24:00, activity: celebrate }
}
every saturday {
block market { 8:00 - 12:00, activity: sell_at_market }
}
}
```
### Example 6: Complex Multi-Level Inheritance
```storybook
schedule BaseHuman {
block sleep { 0:00 - 6:00, activity: sleep }
block breakfast { 6:00 - 7:00, activity: eat }
block dinner { 18:00 - 19:00, activity: eat }
block sleep { 22:00 - 24:00, activity: sleep }
}
schedule Worker extends BaseHuman {
block work { 9:00 - 17:00, activity: work }
}
schedule Baker extends Worker {
override work { time: 5:00 - 13:00, location: Bakery }
override breakfast { time: 13:30 - 14:00 } // Late breakfast
append prep { time: 3:00 - 5:00, activity: bake }
}
schedule RetiredBaker extends BaseHuman {
// No work, just keep eating/sleeping schedule
append hobby { time: 10:00 - 16:00, activity: hobby }
}
```
---
## 11. SBIR Representation
### 11.1 SCHEDULES Section Extension
```
SCHEDULES Section:
- count: u32
- schedules: [Schedule...]
Schedule:
- name: String
- parent_schedule_id: Option<u32> // extends reference
- blocks: [ScheduleBlock...]
- patterns: [SchedulePattern...] // weekday, season, event
ScheduleBlock:
- name: Option<String>
- start: Time (u16 minutes since midnight)
- end: Time (u16 minutes since midnight)
- activity: String
- fields: Map<String, Value>
SchedulePattern:
- kind: PatternKind (Weekday, Season, Event)
- specification: bytes (encoded pattern details)
- blocks: [ScheduleBlock...]
PatternKind:
- Weekday(days: [DayOfWeek])
- Season(seasons: [Season])
- Event(date: DateSpec)
```
### 11.2 Runtime Evaluation
**At runtime**, the engine:
1. Resolves character's schedule links (conditional selection)
2. Merges inherited schedules
3. Evaluates patterns for current day/season
4. Produces final 24-hour schedule for today
**Example Flow:**
```
Character Martha uses BakerSchedule
BakerSchedule extends BaseWorkday
Merge: BaseWorkday blocks + Baker overrides
Result: Martha's schedule for today
```
---
## 12. Implementation Plan
### Phase 1: AST Extension (Week 1)
1. Add extended Schedule struct with `extends` and `items`
2. Add ScheduleItem enum (Block, Override, Remove, etc.)
3. Add pattern types (WeekdayPattern, SeasonPattern, EventPattern)
4. Add DayOfWeek, Season, DateSpec enums
5. Update existing ScheduleBlock to support optional names
### Phase 2: Parser Implementation (Week 1-2)
1. Implement `extends` clause parsing
2. Implement override/remove/append operators
3. Implement weekday/day patterns
4. Implement season patterns
5. Implement event patterns
6. Write parser tests for all patterns
### Phase 3: Resolution & Merging (Week 2)
1. Implement schedule inheritance resolution
2. Implement merge algorithm (same as behavior merging)
3. Implement pattern expansion
4. Implement multi-level inheritance
5. Write resolution tests
### Phase 4: Integration (Week 2-3)
1. Update schedule linking in resource linking system
2. Implement runtime schedule evaluation
3. Update SBIR format
4. Write integration tests
### Phase 5: Documentation & Examples (Week 3)
1. Update language documentation
2. Create comprehensive schedule examples
3. Update Alice in Wonderland example with patterns
4. Create migration guide
**Total Estimate:** 3 weeks
---
## 13. Open Questions
### Question 1: Block Naming (yes)
Should all blocks require names?
**Current:** Blocks can be anonymous
**Proposed:** Blocks need names for override system
**Recommendation:** Require names for override-ability
### Question 2: Time Overlap Detection (ummmmmmm... yeah prolly.)
Should parser/validator detect time overlaps?
```storybook
schedule Broken {
block work { 9:00 - 17:00 }
block lunch { 12:00 - 13:00 } // Overlaps with work!
}
```
**Recommendation:** Warning (not error) for overlaps
### Question 3: Default Block Duration (must throw an error)
What if user writes just `block lunch`?
**Option A:** Error (must specify time)
**Option B:** Default duration (e.g., 1 hour)
**Recommendation:** Option A (explicit is better)
### Question 4: Seasonal Calendar (configurable per world)
Which calendar system?
**Option A:** Simple 4 seasons (Spring, Summer, Fall, Winter)
**Option B:** Month-specific (Jan is winter, etc.)
**Option C:** Configurable per world
**Recommendation:** Option A, with Option C as future extension
---
## 14. Success Criteria
### Must Have
- [x] Backward compatible with current simple schedules
- [x] Template inheritance with `extends`
- [x] Override/remove/append operators
- [x] Weekday patterns (weekday/weekend)
- [x] Day-specific patterns (on monday)
- [x] Seasonal patterns
- [x] Event overrides
- [x] Integration with `uses schedule:` linking
- [x] Multi-level inheritance
- [x] Merge algorithm defined
- [x] SBIR representation specified
### Should Have
- [ ] Recurring event patterns (every saturday)
- [ ] Time overlap warnings
- [ ] Pattern validation
- [ ] Comprehensive examples
- [ ] Runtime evaluation algorithm
### Nice to Have
- [ ] Calendar abstraction for different worlds
- [ ] Behavior references in schedule blocks
- [ ] Visual schedule editor design
- [ ] Performance optimization for large schedules
---
## 15. Comparison with Behavior Linking
| Aspect | Behavior Linking | Schedule Linking |
|--------|------------------|------------------|
| **Inheritance** | `from Template` | `extends Base` |
| **Merge Rule** | Concatenation + override by name | Same |
| **Override** | Character's behavior replaces template's | Child's block replaces parent's |
| **Selection** | Priority + conditions | Temporal + conditions |
| **Multi-level** | Supported | Supported |
| **Empty Array** | Inherit all | Inherit all |
**Design Principle:** Keep schedule composition consistent with behavior composition for user familiarity.
---
**End of Design Document**
**Next Step:** Review and approval before implementation (Task #12).