430 lines
12 KiB
Markdown
430 lines
12 KiB
Markdown
|
|
# 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
|
||
|
|
|
||
|
|
```bnf
|
||
|
|
<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 `species` declaration
|
||
|
|
- **Single inheritance**: A character can only have one species
|
||
|
|
- **Default behavior**: Species fields are inherited automatically
|
||
|
|
|
||
|
|
Example:
|
||
|
|
```storybook
|
||
|
|
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:
|
||
|
|
```storybook
|
||
|
|
character Martha: Human from Baker, BusinessOwner {
|
||
|
|
specialty: "sourdough"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Fields
|
||
|
|
Fields define the character's attributes using the standard field syntax. All [value types](./18-value-types.md) 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](./14-behavior-trees.md) using the `uses behaviors` clause.
|
||
|
|
|
||
|
|
```storybook
|
||
|
|
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](./11-behavior-trees.md) for details on behavior tree syntax and semantics.
|
||
|
|
|
||
|
|
### Schedule Integration
|
||
|
|
Characters can follow [schedules](./16-schedules.md) using the `uses schedule` or `uses schedules` clause.
|
||
|
|
|
||
|
|
```storybook
|
||
|
|
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](./14-schedules.md) 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:
|
||
|
|
```storybook
|
||
|
|
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):
|
||
|
|
|
||
|
|
1. **Species fields** (base ontology)
|
||
|
|
2. **Template fields** (left to right in `from` clause)
|
||
|
|
3. **Character fields** (highest priority)
|
||
|
|
|
||
|
|
Example:
|
||
|
|
```storybook
|
||
|
|
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:
|
||
|
|
|
||
|
|
1. **Unique names**: Character names must be unique within their module
|
||
|
|
2. **Species exists**: If specified, the species must reference a defined `species` declaration
|
||
|
|
3. **Templates exist**: All templates in the `from` clause must reference defined `template` declarations
|
||
|
|
4. **No circular inheritance**: Templates cannot form circular dependency chains
|
||
|
|
5. **Field type consistency**: Field values must match expected types from species/templates
|
||
|
|
6. **Reserved fields**: Cannot use reserved keywords as field names
|
||
|
|
7. **Behavior trees exist**: All behavior tree references must resolve to defined `behavior` declarations
|
||
|
|
8. **Schedules exist**: All schedule references must resolve to defined `schedule` declarations
|
||
|
|
9. **Prose tag uniqueness**: Each prose tag can appear at most once per character
|
||
|
|
|
||
|
|
## Examples
|
||
|
|
|
||
|
|
### Basic Character
|
||
|
|
```storybook
|
||
|
|
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
|
||
|
|
```storybook
|
||
|
|
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
|
||
|
|
```storybook
|
||
|
|
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
|
||
|
|
```storybook
|
||
|
|
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
|
||
|
|
```storybook
|
||
|
|
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:
|
||
|
|
```storybook
|
||
|
|
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:
|
||
|
|
```storybook
|
||
|
|
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:
|
||
|
|
```storybook
|
||
|
|
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](./16-other-declarations.md#species) - Species declarations
|
||
|
|
- [Templates](./16-other-declarations.md#templates) - Template definitions and strict mode
|
||
|
|
- [Value Types](./18-value-types.md) - All supported value types
|
||
|
|
- [Behavior Trees](./11-behavior-trees.md) - Character behavior integration
|
||
|
|
- [Schedules](./14-schedules.md) - Character schedule integration
|
||
|
|
- [Relationships](./15-relationships.md) - Relationships between characters
|
||
|
|
- [Life Arcs](./13-life-arcs.md) - 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
|