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
12 KiB
Characters
Characters are the primary entities in Storybook—the people, creatures, and beings that inhabit your world. Each character has a set of attributes that define who they are, what they can do, and how they relate to the world around them.
Syntax
<character-decl> ::= "character" <identifier> <species-clause>? <template-clause>? <body>
<species-clause> ::= ":" <qualified-path>
<template-clause> ::= "from" <qualified-path> ("," <qualified-path>)*
<body> ::= "{" <body-item>* "}"
<body-item> ::= <field>
| <uses-behaviors>
| <uses-schedule>
<uses-behaviors> ::= "uses" "behaviors" ":" <behavior-link-list>
<uses-schedule> ::= "uses" ("schedule" | "schedules") ":" (<qualified-path> | <schedule-list>)
<behavior-link-list> ::= "[" <behavior-link> ("," <behavior-link>)* "]"
<behavior-link> ::= "{" <behavior-link-field>* "}"
<behavior-link-field> ::= "tree" ":" <qualified-path>
| "when" ":" <expression>
| "priority" ":" ("low" | "normal" | "high" | "critical")
<schedule-list> ::= "[" <qualified-path> ("," <qualified-path>)* "]"
<field> ::= <identifier> ":" <value>
<value> ::= <literal>
| <qualified-path>
| <list>
| <object>
| <prose-block>
| <override>
<prose-block> ::= "---" <identifier> <content> "---"
Components
Name
The character's identifier. Must be unique within its scope and follow standard identifier rules (alphanumeric + underscore, cannot start with digit).
Species (Optional)
The species clause (: SpeciesName) defines what the character fundamentally is. This is distinct from templates, which define what attributes they have.
- Purpose: Ontological typing—what kind of being this is
- Validation: Must reference a defined
speciesdeclaration - Single inheritance: A character can only have one species
- Default behavior: Species fields are inherited automatically
Example:
character Martha: Human {
age: 34
}
Template Inheritance (Optional)
The template clause (from Template1, Template2) specifies templates from which the character inherits fields. Templates provide reusable attribute sets.
- Purpose: Compositional inheritance—mix-and-match capabilities and traits
- Multiple inheritance: Characters can inherit from multiple templates
- Merge semantics: Fields from later templates override earlier ones
- Override allowed: Character fields override all inherited fields
Example:
character Martha: Human from Baker, BusinessOwner {
specialty: "sourdough"
}
Fields
Fields define the character's attributes using the standard field syntax. All value types are supported.
Common field categories:
- Physical traits:
height,weight,age,eye_color - Personality:
confidence,patience,dedication - Professional:
skill_level,specialty,recipes_mastered - State tracking:
energy,mood,orders_today - Capabilities:
can_teach,can_work_independently
Prose Blocks
Characters can contain multiple prose blocks for narrative content. Common tags:
---backstory: Character history and origin---appearance: Physical description---personality: Behavioral traits and quirks---motivation: Goals and desires---secrets: Hidden information
Prose blocks are narrative-only and do not affect simulation logic.
Behavior Integration
Characters can link to behavior trees using the uses behaviors clause.
character Guard {
uses behaviors: [
{
tree: combat::patrol_route
priority: normal
},
{
tree: combat::engage_intruder
when: threat_detected
priority: high
}
]
}
Each behavior link includes:
tree: Qualified path to the behavior tree (required)when: Condition expression for activation (optional)priority: Execution priority (optional, default:normal)
See Behavior Trees for details on behavior tree syntax and semantics.
Schedule Integration
Characters can follow schedules using the uses schedule or uses schedules clause.
character Baker {
uses schedule: BakerySchedule
}
character Innkeeper {
uses schedules: [WeekdaySchedule, WeekendSchedule]
}
- Single schedule:
uses schedule: ScheduleName - Multiple schedules:
uses schedules: [Schedule1, Schedule2]
The runtime selects the appropriate schedule based on temporal constraints. See Schedules for composition and selection semantics.
Species vs. Templates
The distinction between species (:) and templates (from) reflects ontological vs. compositional typing:
| Feature | Species (:) |
Templates (from) |
|---|---|---|
| Semantics | What the character is | What the character has |
| Cardinality | Exactly one | Zero or more |
| Example | : Human, : Dragon |
from Warrior, Mage |
| Purpose | Fundamental nature | Reusable trait sets |
| Override | Can override species fields | Can override template fields |
Example showing both:
species Dragon {
max_lifespan: 1000
can_fly: true
}
template Hoarder {
treasure_value: 0..1000000
greed_level: 0.0..1.0
}
template Ancient {
age: 500..1000
wisdom: 0.8..1.0
}
character Smaug: Dragon from Hoarder, Ancient {
age: 850
treasure_value: 500000
greed_level: 0.95
}
Field Resolution Order
When a character inherits from species and templates, fields are resolved in this order (later overrides earlier):
- Species fields (base ontology)
- Template fields (left to right in
fromclause) - Character fields (highest priority)
Example:
species Human {
lifespan: 80
speed: 1.0
}
template Warrior {
speed: 1.5
strength: 10
}
template Berserker {
speed: 2.0
strength: 15
}
character Conan: Human from Warrior, Berserker {
strength: 20
}
// Resolved fields:
// lifespan: 80 (from Human)
// speed: 2.0 (Berserker overrides Warrior overrides Human)
// strength: 20 (character overrides Berserker)
Validation Rules
The Storybook compiler enforces these validation rules:
- Unique names: Character names must be unique within their module
- Species exists: If specified, the species must reference a defined
speciesdeclaration - Templates exist: All templates in the
fromclause must reference definedtemplatedeclarations - No circular inheritance: Templates cannot form circular dependency chains
- Field type consistency: Field values must match expected types from species/templates
- Reserved fields: Cannot use reserved keywords as field names
- Behavior trees exist: All behavior tree references must resolve to defined
behaviordeclarations - Schedules exist: All schedule references must resolve to defined
scheduledeclarations - Prose tag uniqueness: Each prose tag can appear at most once per character
Examples
Basic Character
character SimpleMerchant {
name: "Gregor"
occupation: "Fish Merchant"
wealth: 50
---personality
A straightforward fish seller at the market. Honest, hardworking,
and always smells faintly of mackerel.
---
}
Character with Species
character Martha: Human {
age: 34
skill_level: 0.95
specialty: "sourdough"
---backstory
Martha learned to bake from her grandmother, starting at age
twelve. She now runs the most popular bakery in town.
---
}
Character with Template Inheritance
character Jane: Human from Baker, PastrySpecialist {
age: 36
specialty: "pastries"
recipes_mastered: 120
years_experience: 18
can_teach: true
---appearance
A focused woman with flour-dusted apron and steady hands.
Known for her intricate pastry decorations and precise
temperature control.
---
}
Character with All Features
character CityGuard: Human from CombatTraining, LawEnforcement {
age: 30
rank: "Sergeant"
// Physical traits
height: 175
strength: 12
// Equipment
has_weapon: true
armor_level: 2
// Behavior integration
uses behaviors: [
{
tree: guards::patrol_route
priority: normal
},
{
tree: guards::engage_hostile
when: threat_detected
priority: high
},
{
tree: guards::sound_alarm
when: emergency
priority: critical
}
]
// Schedule integration
uses schedules: [guards::day_shift, guards::night_shift]
---backstory
A veteran of the city watch, now responsible for training new recruits
while maintaining order in the merchant district.
---
---personality
Gruff exterior with a hidden soft spot for street children. Follows
the rules but knows when to look the other way.
---
}
Character with Overrides
template WeaponUser {
damage: 5..15
accuracy: 0.7
}
character MasterSwordsman: Human from WeaponUser {
// Override template range with specific value
damage: 15
accuracy: 0.95
// Add character-specific fields
signature_move: "Whirlwind Strike"
}
Use Cases
Protagonist Definition
Define rich, dynamic protagonists with complex attributes:
character Elena: Human from Scholar, Diplomat {
age: 28
intelligence: 18
charisma: 16
languages_known: ["Common", "Elvish", "Draconic"]
books_read: 347
current_quest: "Broker peace between warring kingdoms"
---backstory
Raised in the Grand Library, Elena discovered ancient texts that
hinted at a forgotten alliance between humans and dragons. She now
seeks to revive that alliance to end the current war.
---
}
NPC Templates
Create diverse NPCs from templates:
template Villager {
occupation: "Farmer"
wealth: 10..50
disposition: 0.0..1.0 // 0=hostile, 1=friendly
}
character Oswald: Human from Villager {
occupation: "Blacksmith"
wealth: 45
disposition: 0.8
}
character Mildred: Human from Villager {
occupation: "Baker"
wealth: 35
disposition: 0.95
}
Ensemble Casts
Define multiple related characters:
template BakeryStaff {
punctuality: 0.5..1.0
teamwork: 0.5..1.0
}
template Apprentice {
skill_level: 0.0..0.5
dedication: 0.5..1.0
}
character Elena: Human from BakeryStaff, Apprentice {
age: 16
natural_talent: 0.8
dedication: 0.9
---backstory
Elena comes from a family of farmers who could never afford to
buy bread from the bakery. When Martha offered her an apprenticeship,
she jumped at the chance to learn a trade.
---
}
Cross-References
- Species - Species declarations
- Templates - Template definitions and strict mode
- Value Types - All supported value types
- Behavior Trees - Character behavior integration
- Schedules - Character schedule integration
- Relationships - Relationships between characters
- Life Arcs - Character state machines over time
Related Concepts
- Instantiation: Characters are concrete instances; they cannot be instantiated further
- Composition: Prefer template composition over deep species hierarchies
- Modularity: Characters can reference behaviors and schedules from other modules
- Narrative-driven: Use prose blocks to embed storytelling directly with data