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
26 KiB
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):
schedule MadTeaPartyRotation {
18:00 -> 18:01: TeaRound {
---narrative
Begin a new rotation...
---
}
18:01 -> 18:02: RiddlePhase { ... }
18:02 -> 18:03: ContradictionPhase { ... }
}
Current AST:
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
- No composition: Can't build a weekly schedule from daily templates
- No inheritance: Can't extend a base schedule and customize
- No temporal hierarchy: Can't express "weekday vs weekend" patterns
- No seasonal variation: Can't say "summer hours vs winter hours"
- No override system: Can't modify specific blocks while keeping others
- 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
- Hierarchical Composition: Build complex schedules from simple parts
- Template Inheritance: Extend and customize like behavior templates
- Temporal Flexibility: Express daily, weekly, seasonal, yearly patterns
- Override System: Modify specific aspects while keeping others
- Backward Compatible: Current simple schedules still work
- Integration: Seamless with
uses schedule:linking
2.2 Non-Goals
- Real-time scheduling: Schedules are static patterns, not dynamic
- Calendar systems: Focus on patterns, not specific date handling
- Time zones: All times are game-world local
- 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:
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:
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:
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:
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:
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:
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:
schedule BakerSchedule extends BaseWorkday {
override work {
time: 5:00 - 13:00,
location: Bakery
}
}
remove <block> - Delete inherited block:
schedule RetiredSchedule extends BaseWorkday {
remove work // No more work!
}
append <block> { fields } - Add new block:
schedule ExtendedDay extends BaseWorkday {
append meditation { 5:00 - 5:30, activity: meditate }
}
replace all - Complete replacement (no inheritance):
schedule FullRest {
replace all
block rest { 0:00 - 24:00, activity: rest }
}
4.3 Multi-Level Inheritance
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:
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:
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:
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:
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:
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.)
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
// 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
// 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:
- Resolve
extendsreference to base schedule - Collect base schedule's blocks
- Apply overrides/removes/appends from extending schedule
- Override by block name (not by time)
- Handle multi-level inheritance recursively
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)
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
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
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
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)
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
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
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
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
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
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:
- Resolves character's schedule links (conditional selection)
- Merges inherited schedules
- Evaluates patterns for current day/season
- 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)
- Add extended Schedule struct with
extendsanditems - Add ScheduleItem enum (Block, Override, Remove, etc.)
- Add pattern types (WeekdayPattern, SeasonPattern, EventPattern)
- Add DayOfWeek, Season, DateSpec enums
- Update existing ScheduleBlock to support optional names
Phase 2: Parser Implementation (Week 1-2)
- Implement
extendsclause parsing - Implement override/remove/append operators
- Implement weekday/day patterns
- Implement season patterns
- Implement event patterns
- Write parser tests for all patterns
Phase 3: Resolution & Merging (Week 2)
- Implement schedule inheritance resolution
- Implement merge algorithm (same as behavior merging)
- Implement pattern expansion
- Implement multi-level inheritance
- Write resolution tests
Phase 4: Integration (Week 2-3)
- Update schedule linking in resource linking system
- Implement runtime schedule evaluation
- Update SBIR format
- Write integration tests
Phase 5: Documentation & Examples (Week 3)
- Update language documentation
- Create comprehensive schedule examples
- Update Alice in Wonderland example with patterns
- 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?
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
- Backward compatible with current simple schedules
- Template inheritance with
extends - Override/remove/append operators
- Weekday patterns (weekday/weekend)
- Day-specific patterns (on monday)
- Seasonal patterns
- Event overrides
- Integration with
uses schedule:linking - Multi-level inheritance
- Merge algorithm defined
- 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).