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
501 lines
12 KiB
Markdown
501 lines
12 KiB
Markdown
# Locations and Institutions
|
|
|
|
So far you have created characters, given them behaviors, connected them with relationships, scheduled their days, and guided them through life arcs. But characters need places to *be* and organizations to *belong to*. That is what locations and institutions provide.
|
|
|
|
---
|
|
|
|
## What Are Locations?
|
|
|
|
A **location** is a place in your world. It can be a building, a room, a park, a city -- any space where things happen. Locations hold fields that describe the place and optional prose blocks for narrative detail.
|
|
|
|
### Your First Location
|
|
|
|
Let's create the bakery where Martha works:
|
|
|
|
```storybook
|
|
location BakersBakery {
|
|
type: bakery
|
|
address: "14 Main Street"
|
|
capacity: 30
|
|
}
|
|
```
|
|
|
|
That is all it takes. The `location` keyword, a name, and a block of fields. Every field is a key-value pair, and you choose whatever fields make sense for your world.
|
|
|
|
### Adding Detail
|
|
|
|
A real location needs more than three fields. Let's flesh out the bakery:
|
|
|
|
```storybook
|
|
location BakersBakery {
|
|
type: bakery
|
|
address: "14 Main Street"
|
|
capacity: 30
|
|
employees: 4
|
|
specialty: "artisan sourdough"
|
|
daily_output_loaves: 80..120
|
|
open: true
|
|
established: "2011"
|
|
}
|
|
```
|
|
|
|
Notice `daily_output_loaves: 80..120` -- that is a range. Each simulation run can pick a different number of loaves, adding natural variation.
|
|
|
|
### Prose Blocks
|
|
|
|
Bare fields are good for data, but locations also need narrative flavor. Use prose blocks:
|
|
|
|
```storybook
|
|
location BakersBakery {
|
|
type: bakery
|
|
address: "14 Main Street"
|
|
capacity: 30
|
|
|
|
---description
|
|
A warm, inviting bakery on Main Street. The smell of fresh bread
|
|
wafts out the door every morning at dawn. Martha has run the shop
|
|
for fifteen years, and the locals consider it the heart of the
|
|
neighborhood.
|
|
---
|
|
}
|
|
```
|
|
|
|
Prose blocks start with `---tag_name` and end with `---`. The tag name (`description` here) becomes the key. You can have as many prose blocks as you want:
|
|
|
|
```storybook
|
|
location BakersBakery {
|
|
type: bakery
|
|
|
|
---description
|
|
The bakery on Main Street...
|
|
---
|
|
|
|
---history
|
|
Originally a hardware store, Martha converted the space in 2011...
|
|
---
|
|
|
|
---atmosphere
|
|
Flour dust catches the light from tall windows...
|
|
---
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Building a World with Locations
|
|
|
|
Locations work best when they form a coherent world. Here is the Baker family's neighborhood:
|
|
|
|
```storybook
|
|
location BakersBakery {
|
|
type: bakery
|
|
address: "14 Main Street"
|
|
capacity: 30
|
|
owner: Martha
|
|
|
|
---description
|
|
Martha's artisan bakery. The stone oven was imported from France.
|
|
---
|
|
}
|
|
|
|
location BakerHome {
|
|
type: residence
|
|
address: "22 Elm Lane"
|
|
bedrooms: 4
|
|
has_garden: true
|
|
|
|
---description
|
|
The Baker family home. Martha insisted on an oversized kitchen.
|
|
---
|
|
}
|
|
|
|
location BakersGuildHall {
|
|
type: guild_hall
|
|
address: "7 Guild Row"
|
|
capacity: 100
|
|
established: "1892"
|
|
|
|
---description
|
|
The historic headquarters of the Bakers Guild.
|
|
---
|
|
}
|
|
|
|
location TownSquare {
|
|
type: public_square
|
|
capacity: 500
|
|
has_fountain: true
|
|
has_market_stalls: true
|
|
|
|
---description
|
|
The central gathering place. On weekends, the farmers market
|
|
fills the square with produce stalls.
|
|
---
|
|
}
|
|
```
|
|
|
|
### Modeling Hierarchy
|
|
|
|
Storybook does not enforce a built-in parent-child relationship for locations. Instead, you use fields to express hierarchy:
|
|
|
|
```storybook
|
|
location MainStreet {
|
|
type: street
|
|
district: TownCenter
|
|
shops: 12
|
|
}
|
|
|
|
location BakersBakery {
|
|
type: bakery
|
|
street: MainStreet
|
|
district: TownCenter
|
|
}
|
|
```
|
|
|
|
This convention-based approach keeps the language simple while letting you model whatever spatial relationships your world needs.
|
|
|
|
---
|
|
|
|
## What Are Institutions?
|
|
|
|
An **institution** is an organization, group, or system. Think of it as a character that represents a collective: a guild, a government, a school, a business. Institutions have a key capability that locations lack -- they can **use behaviors and schedules**, just like characters.
|
|
|
|
### Your First Institution
|
|
|
|
```storybook
|
|
institution BakersGuild {
|
|
type: trade_guild
|
|
members: 50
|
|
founded: "1892"
|
|
reputation: 0.85
|
|
}
|
|
```
|
|
|
|
This looks just like a location so far. The difference comes when you add behaviors.
|
|
|
|
### Institutions with Behaviors
|
|
|
|
Institutions can act. The `uses behaviors` clause links behavior trees to the institution:
|
|
|
|
```storybook
|
|
institution BakersGuild {
|
|
type: trade_guild
|
|
members: 50
|
|
reputation: 0.85
|
|
|
|
uses behaviors: [
|
|
{ tree: ManageApprentices },
|
|
{ tree: NegotiateSuppliers },
|
|
{ tree: HostEvents }
|
|
]
|
|
}
|
|
```
|
|
|
|
Each entry in the list is a behavior link object with a `tree` field. This tells the simulation engine that the Bakers Guild can manage apprentices, negotiate with suppliers, and host events.
|
|
|
|
### Behavior Priorities
|
|
|
|
Not all behaviors are equally important. Use the `priority` field:
|
|
|
|
```storybook
|
|
institution BakersGuild {
|
|
type: trade_guild
|
|
|
|
uses behaviors: [
|
|
{ tree: ManageApprentices, priority: normal },
|
|
{ tree: NegotiateSuppliers, priority: high },
|
|
{ tree: HostEvents, priority: low }
|
|
]
|
|
}
|
|
```
|
|
|
|
Priority levels are `low`, `normal`, `high`, and `critical`. Higher-priority behaviors take precedence when the institution must choose between actions.
|
|
|
|
### Conditional Behaviors
|
|
|
|
Some behaviors only activate under certain conditions:
|
|
|
|
```storybook
|
|
institution BakersGuild {
|
|
type: trade_guild
|
|
reputation: 0.85
|
|
|
|
uses behaviors: [
|
|
{ tree: ManageApprentices },
|
|
{ tree: NegotiateSuppliers, priority: high },
|
|
{ tree: EmergencyMeeting, when: reputation < 0.3, priority: critical }
|
|
]
|
|
}
|
|
```
|
|
|
|
The `when` clause uses an [expression](../reference/17-expressions.md). Here, the emergency meeting behavior only activates when reputation drops below 0.3.
|
|
|
|
### Institutions with Schedules
|
|
|
|
Institutions can also follow schedules:
|
|
|
|
```storybook
|
|
institution BakersGuild {
|
|
type: trade_guild
|
|
uses schedule: GuildOperatingHours
|
|
}
|
|
```
|
|
|
|
For multiple schedules:
|
|
|
|
```storybook
|
|
institution BakersGuild {
|
|
type: trade_guild
|
|
uses schedules: [WeekdaySchedule, WeekendSchedule]
|
|
}
|
|
```
|
|
|
|
### Prose Blocks
|
|
|
|
Just like locations, institutions support prose blocks:
|
|
|
|
```storybook
|
|
institution BakersGuild {
|
|
type: trade_guild
|
|
members: 50
|
|
|
|
---description
|
|
The Bakers Guild has been the backbone of the town's bread trade
|
|
since 1892. Members share recipes, arrange apprenticeships, and
|
|
collectively negotiate flour prices.
|
|
---
|
|
|
|
---charter
|
|
Article I: All members shall maintain the highest standards.
|
|
Article II: Apprentices must complete a three-year program.
|
|
---
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Connecting Characters to Institutions
|
|
|
|
Institutions do not have a built-in membership list. You model membership through character fields or relationships.
|
|
|
|
### Through Character Fields
|
|
|
|
The simplest approach -- add fields to your characters:
|
|
|
|
```storybook
|
|
character Martha {
|
|
age: 45
|
|
occupation: baker
|
|
guild: BakersGuild
|
|
guild_role: guild_master
|
|
guild_member_since: "2005"
|
|
}
|
|
|
|
character Jane {
|
|
age: 19
|
|
occupation: apprentice_baker
|
|
guild: BakersGuild
|
|
guild_role: apprentice
|
|
guild_member_since: "2024"
|
|
}
|
|
```
|
|
|
|
### Through Relationships
|
|
|
|
For richer modeling, use relationships:
|
|
|
|
```storybook
|
|
relationship GuildMembership {
|
|
Martha as guild_master { years_active: 20 }
|
|
BakersGuild as organization { }
|
|
bond: 0.95
|
|
}
|
|
|
|
relationship Apprenticeship {
|
|
Jane as apprentice { skills_learned: 12 }
|
|
Martha as mentor { patience_remaining: 0.7 }
|
|
BakersGuild as guild { }
|
|
years_completed: 1
|
|
}
|
|
```
|
|
|
|
This approach captures richer information: roles, duration, and multi-party connections.
|
|
|
|
---
|
|
|
|
## Locations vs. Institutions
|
|
|
|
When should you use each?
|
|
|
|
| Question | Use... |
|
|
|----------|--------|
|
|
| Where does something happen? | Location |
|
|
| Who or what organizes things? | Institution |
|
|
| Does it need behaviors? | Institution |
|
|
| Does it need a schedule? | Institution |
|
|
| Is it purely a place? | Location |
|
|
| Is it a group or organization? | Institution |
|
|
|
|
Sometimes the same concept needs both:
|
|
|
|
```storybook
|
|
// The physical building
|
|
location BakersGuildHall {
|
|
type: guild_hall
|
|
address: "7 Guild Row"
|
|
capacity: 100
|
|
}
|
|
|
|
// The organization that meets there
|
|
institution BakersGuild {
|
|
type: trade_guild
|
|
members: 50
|
|
location: BakersGuildHall
|
|
|
|
uses behaviors: [
|
|
{ tree: ManageApprentices },
|
|
{ tree: NegotiateSuppliers }
|
|
]
|
|
|
|
uses schedule: GuildOperatingHours
|
|
}
|
|
```
|
|
|
|
The guild hall is a *place*. The guild is an *organization*. Keeping them separate lets you say "the guild meets at the guild hall" without conflating the building with the institution.
|
|
|
|
---
|
|
|
|
## Putting It All Together
|
|
|
|
Here is a complete example showing how locations, institutions, and characters work together in the Baker family world:
|
|
|
|
```storybook
|
|
// Enums for type safety
|
|
enum PlaceType {
|
|
bakery, residence, guild_hall, public_square
|
|
}
|
|
|
|
enum GuildRole {
|
|
guild_master, journeyman, apprentice
|
|
}
|
|
|
|
// Locations: where things happen
|
|
location BakersBakery {
|
|
type: bakery
|
|
address: "14 Main Street"
|
|
capacity: 30
|
|
owner: Martha
|
|
|
|
---description
|
|
Martha's artisan bakery on Main Street.
|
|
---
|
|
}
|
|
|
|
location BakerHome {
|
|
type: residence
|
|
address: "22 Elm Lane"
|
|
bedrooms: 4
|
|
residents: ["Martha", "David", "Jane", "Tom"]
|
|
}
|
|
|
|
location BakersGuildHall {
|
|
type: guild_hall
|
|
address: "7 Guild Row"
|
|
capacity: 100
|
|
|
|
---description
|
|
The historic Bakers Guild headquarters, established 1892.
|
|
---
|
|
}
|
|
|
|
// Institution: the organization
|
|
institution BakersGuild {
|
|
type: trade_guild
|
|
members: 50
|
|
founded: "1892"
|
|
reputation: 0.85
|
|
location: BakersGuildHall
|
|
leader: Martha
|
|
|
|
uses behaviors: [
|
|
{ tree: ManageApprentices, priority: normal },
|
|
{ tree: NegotiateSuppliers, priority: high },
|
|
{ tree: HostAnnualBakeOff, when: month is october }
|
|
]
|
|
|
|
uses schedule: GuildOperatingHours
|
|
|
|
---description
|
|
The Bakers Guild oversees apprenticeships, quality standards,
|
|
and the annual Great Bake-Off competition.
|
|
---
|
|
}
|
|
|
|
// Institution: the business
|
|
institution BakersBakeryBusiness {
|
|
type: business
|
|
owner: Martha
|
|
employees: 4
|
|
location: BakersBakery
|
|
|
|
uses behaviors: [
|
|
{ tree: DailyBakingOps, priority: high },
|
|
{ tree: InventoryManagement }
|
|
]
|
|
|
|
uses schedule: BakeryOperatingHours
|
|
}
|
|
|
|
// Characters connected to all of the above
|
|
character Martha {
|
|
age: 45
|
|
occupation: baker
|
|
workplace: BakersBakery
|
|
home: BakerHome
|
|
guild: BakersGuild
|
|
guild_role: guild_master
|
|
}
|
|
|
|
character Jane {
|
|
age: 19
|
|
occupation: apprentice_baker
|
|
workplace: BakersBakery
|
|
home: BakerHome
|
|
guild: BakersGuild
|
|
guild_role: apprentice
|
|
}
|
|
|
|
// Relationships tying it all together
|
|
relationship GuildLeadership {
|
|
Martha as guild_master { }
|
|
BakersGuild as guild { }
|
|
years_in_role: 8
|
|
}
|
|
|
|
relationship BakeryApprenticeship {
|
|
Jane as apprentice { }
|
|
Martha as mentor { }
|
|
BakersGuild as certifying_body { }
|
|
year: 1
|
|
total_years: 3
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Key Takeaways
|
|
|
|
1. **Locations** are simple: name, fields, prose blocks. They model *places*.
|
|
2. **Institutions** are richer: they add `uses behaviors` and `uses schedule` on top of fields and prose. They model *organizations*.
|
|
3. **Membership** is modeled through character fields or relationships, not built into institution syntax.
|
|
4. **Separate place from organization**: A guild hall (location) and the guild (institution) are different things.
|
|
5. **Use enums** for type-safe categorization of locations and institutions.
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
- Learn about [expressions](../reference/17-expressions.md) used in conditional behavior links
|
|
- Explore [behavior trees](./03-first-behavior-tree.md) to create the behaviors your institutions use
|
|
- See [schedules](./07-schedules.md) to define operating hours for institutions
|
|
- Read the full [Locations Reference](../reference/16a-locations.md) and [Institutions Reference](../reference/16b-institutions.md)
|