570 lines
25 KiB
HTML
570 lines
25 KiB
HTML
|
|
<!DOCTYPE HTML>
|
|||
|
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
|||
|
|
<head>
|
|||
|
|
<!-- Book generated using mdBook -->
|
|||
|
|
<meta charset="UTF-8">
|
|||
|
|
<title>Institutions - Storybook Language Guide</title>
|
|||
|
|
|
|||
|
|
|
|||
|
|
<!-- Custom HTML head -->
|
|||
|
|
|
|||
|
|
<meta name="description" content="Comprehensive documentation for the Storybook narrative simulation language">
|
|||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|||
|
|
<meta name="theme-color" content="#ffffff">
|
|||
|
|
|
|||
|
|
<link rel="icon" href="../favicon.svg">
|
|||
|
|
<link rel="shortcut icon" href="../favicon.png">
|
|||
|
|
<link rel="stylesheet" href="../css/variables.css">
|
|||
|
|
<link rel="stylesheet" href="../css/general.css">
|
|||
|
|
<link rel="stylesheet" href="../css/chrome.css">
|
|||
|
|
<link rel="stylesheet" href="../css/print.css" media="print">
|
|||
|
|
|
|||
|
|
<!-- Fonts -->
|
|||
|
|
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
|||
|
|
<link rel="stylesheet" href="../fonts/fonts.css">
|
|||
|
|
|
|||
|
|
<!-- Highlight.js Stylesheets -->
|
|||
|
|
<link rel="stylesheet" href="../highlight.css">
|
|||
|
|
<link rel="stylesheet" href="../tomorrow-night.css">
|
|||
|
|
<link rel="stylesheet" href="../ayu-highlight.css">
|
|||
|
|
|
|||
|
|
<!-- Custom theme stylesheets -->
|
|||
|
|
|
|||
|
|
|
|||
|
|
<!-- Provide site root to javascript -->
|
|||
|
|
<script>
|
|||
|
|
var path_to_root = "../";
|
|||
|
|
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
|||
|
|
</script>
|
|||
|
|
<!-- Start loading toc.js asap -->
|
|||
|
|
<script src="../toc.js"></script>
|
|||
|
|
</head>
|
|||
|
|
<body>
|
|||
|
|
<div id="body-container">
|
|||
|
|
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
|||
|
|
<script>
|
|||
|
|
try {
|
|||
|
|
var theme = localStorage.getItem('mdbook-theme');
|
|||
|
|
var sidebar = localStorage.getItem('mdbook-sidebar');
|
|||
|
|
|
|||
|
|
if (theme.startsWith('"') && theme.endsWith('"')) {
|
|||
|
|
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
|||
|
|
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
|||
|
|
}
|
|||
|
|
} catch (e) { }
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<!-- Set the theme before any content is loaded, prevents flash -->
|
|||
|
|
<script>
|
|||
|
|
var theme;
|
|||
|
|
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
|||
|
|
if (theme === null || theme === undefined) { theme = default_theme; }
|
|||
|
|
const html = document.documentElement;
|
|||
|
|
html.classList.remove('light')
|
|||
|
|
html.classList.add(theme);
|
|||
|
|
html.classList.add("js");
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
|||
|
|
|
|||
|
|
<!-- Hide / unhide sidebar before it is displayed -->
|
|||
|
|
<script>
|
|||
|
|
var sidebar = null;
|
|||
|
|
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
|||
|
|
if (document.body.clientWidth >= 1080) {
|
|||
|
|
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
|||
|
|
sidebar = sidebar || 'visible';
|
|||
|
|
} else {
|
|||
|
|
sidebar = 'hidden';
|
|||
|
|
}
|
|||
|
|
sidebar_toggle.checked = sidebar === 'visible';
|
|||
|
|
html.classList.remove('sidebar-visible');
|
|||
|
|
html.classList.add("sidebar-" + sidebar);
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
|||
|
|
<!-- populated by js -->
|
|||
|
|
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
|
|||
|
|
<noscript>
|
|||
|
|
<iframe class="sidebar-iframe-outer" src="../toc.html"></iframe>
|
|||
|
|
</noscript>
|
|||
|
|
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
|||
|
|
<div class="sidebar-resize-indicator"></div>
|
|||
|
|
</div>
|
|||
|
|
</nav>
|
|||
|
|
|
|||
|
|
<div id="page-wrapper" class="page-wrapper">
|
|||
|
|
|
|||
|
|
<div class="page">
|
|||
|
|
<div id="menu-bar-hover-placeholder"></div>
|
|||
|
|
<div id="menu-bar" class="menu-bar sticky">
|
|||
|
|
<div class="left-buttons">
|
|||
|
|
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
|||
|
|
<i class="fa fa-bars"></i>
|
|||
|
|
</label>
|
|||
|
|
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
|||
|
|
<i class="fa fa-paint-brush"></i>
|
|||
|
|
</button>
|
|||
|
|
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
|||
|
|
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
|||
|
|
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
|||
|
|
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
|||
|
|
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
|||
|
|
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
|||
|
|
</ul>
|
|||
|
|
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
|||
|
|
<i class="fa fa-search"></i>
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<h1 class="menu-title">Storybook Language Guide</h1>
|
|||
|
|
|
|||
|
|
<div class="right-buttons">
|
|||
|
|
<a href="../print.html" title="Print this book" aria-label="Print this book">
|
|||
|
|
<i id="print-button" class="fa fa-print"></i>
|
|||
|
|
</a>
|
|||
|
|
<a href="https://github.com/r3t-studios/storybook" title="Git repository" aria-label="Git repository">
|
|||
|
|
<i id="git-repository-button" class="fa fa-github"></i>
|
|||
|
|
</a>
|
|||
|
|
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div id="search-wrapper" class="hidden">
|
|||
|
|
<form id="searchbar-outer" class="searchbar-outer">
|
|||
|
|
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
|||
|
|
</form>
|
|||
|
|
<div id="searchresults-outer" class="searchresults-outer hidden">
|
|||
|
|
<div id="searchresults-header" class="searchresults-header"></div>
|
|||
|
|
<ul id="searchresults">
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
|||
|
|
<script>
|
|||
|
|
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
|||
|
|
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
|||
|
|
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
|||
|
|
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
|||
|
|
});
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<div id="content" class="content">
|
|||
|
|
<main>
|
|||
|
|
<h1 id="institutions"><a class="header" href="#institutions">Institutions</a></h1>
|
|||
|
|
<p>Institutions define organizations, groups, and systems – entities that function like characters but represent collectives rather than individuals. Unlike locations (which model <em>where</em>), institutions model <em>what structures and organizations</em> operate in your world.</p>
|
|||
|
|
<hr />
|
|||
|
|
<h2 id="syntax"><a class="header" href="#syntax">Syntax</a></h2>
|
|||
|
|
<pre><code class="language-bnf"><institution-decl> ::= "institution" <identifier> "{" <institution-body> "}"
|
|||
|
|
|
|||
|
|
<institution-body> ::= (<field> | <uses-behaviors> | <uses-schedule> | <prose-block>)*
|
|||
|
|
|
|||
|
|
<uses-behaviors> ::= "uses" "behaviors" ":" "[" <behavior-link> ("," <behavior-link>)* "]"
|
|||
|
|
|
|||
|
|
<behavior-link> ::= "{" "tree" ":" <path> ","?
|
|||
|
|
("when" ":" <expression> ","?)?
|
|||
|
|
("priority" ":" <priority-level> ","?)? "}"
|
|||
|
|
|
|||
|
|
<priority-level> ::= "low" | "normal" | "high" | "critical"
|
|||
|
|
|
|||
|
|
<uses-schedule> ::= "uses" "schedule" ":" <identifier>
|
|||
|
|
| "uses" "schedules" ":" "[" <identifier> ("," <identifier>)* "]"
|
|||
|
|
</code></pre>
|
|||
|
|
<p>An institution declaration consists of:</p>
|
|||
|
|
<ul>
|
|||
|
|
<li>The <code>institution</code> keyword</li>
|
|||
|
|
<li>A unique name (identifier)</li>
|
|||
|
|
<li>A body block containing fields, resource links, and optional prose blocks</li>
|
|||
|
|
</ul>
|
|||
|
|
<hr />
|
|||
|
|
<h2 id="basic-institution"><a class="header" href="#basic-institution">Basic Institution</a></h2>
|
|||
|
|
<p>The simplest institution has a name and descriptive fields:</p>
|
|||
|
|
<pre><code class="language-storybook">institution BakersGuild {
|
|||
|
|
type: trade_guild
|
|||
|
|
members: 50
|
|||
|
|
founded: "1892"
|
|||
|
|
reputation: 0.85
|
|||
|
|
}
|
|||
|
|
</code></pre>
|
|||
|
|
<hr />
|
|||
|
|
<h2 id="fields"><a class="header" href="#fields">Fields</a></h2>
|
|||
|
|
<p>Institution fields describe properties of the organization:</p>
|
|||
|
|
<pre><code class="language-storybook">institution BakersGuild {
|
|||
|
|
type: trade_guild
|
|||
|
|
members: 50
|
|||
|
|
founded: "1892"
|
|||
|
|
reputation: 0.85
|
|||
|
|
dues_annual: 120
|
|||
|
|
meeting_frequency: "monthly"
|
|||
|
|
accepts_apprentices: true
|
|||
|
|
max_apprentices: 10
|
|||
|
|
location: BakersGuildHall
|
|||
|
|
}
|
|||
|
|
</code></pre>
|
|||
|
|
<h3 id="common-field-patterns"><a class="header" href="#common-field-patterns">Common Field Patterns</a></h3>
|
|||
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|||
|
|
<tr><td><code>type</code></td><td>enum/identifier</td><td>Category of organization</td></tr>
|
|||
|
|
<tr><td><code>members</code></td><td>integer</td><td>Membership count</td></tr>
|
|||
|
|
<tr><td><code>founded</code></td><td>string</td><td>Establishment date</td></tr>
|
|||
|
|
<tr><td><code>reputation</code></td><td>float</td><td>Public standing (0.0-1.0)</td></tr>
|
|||
|
|
<tr><td><code>location</code></td><td>identifier</td><td>Where the institution operates</td></tr>
|
|||
|
|
<tr><td><code>leader</code></td><td>identifier</td><td>Who runs the institution</td></tr>
|
|||
|
|
</tbody></table>
|
|||
|
|
</div>
|
|||
|
|
<p>These are conventions – you define whatever fields make sense for your world.</p>
|
|||
|
|
<hr />
|
|||
|
|
<h2 id="prose-blocks"><a class="header" href="#prose-blocks">Prose Blocks</a></h2>
|
|||
|
|
<p>Institutions support prose blocks for rich narrative documentation:</p>
|
|||
|
|
<pre><code class="language-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 with suppliers.
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
---charter
|
|||
|
|
Article I: All members shall maintain the highest standards of
|
|||
|
|
baking quality. Article II: Apprentices must complete a three-year
|
|||
|
|
training program. Article III: Monthly meetings are mandatory.
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
---traditions
|
|||
|
|
Every autumn, the Guild hosts the Great Bake-Off, a competition
|
|||
|
|
open to all members. The winner earns the title of Master Baker
|
|||
|
|
for the following year.
|
|||
|
|
---
|
|||
|
|
}
|
|||
|
|
</code></pre>
|
|||
|
|
<p><strong>Prose block rules:</strong></p>
|
|||
|
|
<ul>
|
|||
|
|
<li>Start with <code>---tag_name</code> on its own line</li>
|
|||
|
|
<li>Content is free-form text (Markdown supported)</li>
|
|||
|
|
<li>End with <code>---</code> on its own line</li>
|
|||
|
|
<li>Multiple prose blocks per institution are allowed</li>
|
|||
|
|
<li>Each tag must be unique within the institution</li>
|
|||
|
|
</ul>
|
|||
|
|
<hr />
|
|||
|
|
<h2 id="resource-linking-behaviors"><a class="header" href="#resource-linking-behaviors">Resource Linking: Behaviors</a></h2>
|
|||
|
|
<p>Institutions can link to <a href="./11-behavior-trees.html">behavior trees</a> using the <code>uses behaviors</code> clause. This defines what actions the institution takes as a collective entity.</p>
|
|||
|
|
<h3 id="simple-behavior-linking"><a class="header" href="#simple-behavior-linking">Simple Behavior Linking</a></h3>
|
|||
|
|
<pre><code class="language-storybook">institution BakersGuild {
|
|||
|
|
type: trade_guild
|
|||
|
|
members: 50
|
|||
|
|
|
|||
|
|
uses behaviors: [
|
|||
|
|
{ tree: ManageApprentices },
|
|||
|
|
{ tree: NegotiateSuppliers },
|
|||
|
|
{ tree: HostEvents }
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
</code></pre>
|
|||
|
|
<p>Each behavior link is an object with a <code>tree</code> field referencing a behavior tree by name or path.</p>
|
|||
|
|
<h3 id="behavior-links-with-priority"><a class="header" href="#behavior-links-with-priority">Behavior Links with Priority</a></h3>
|
|||
|
|
<pre><code class="language-storybook">institution BakersGuild {
|
|||
|
|
type: trade_guild
|
|||
|
|
|
|||
|
|
uses behaviors: [
|
|||
|
|
{ tree: ManageApprentices, priority: normal },
|
|||
|
|
{ tree: NegotiateSuppliers, priority: high },
|
|||
|
|
{ tree: HostEvents, priority: low }
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
</code></pre>
|
|||
|
|
<p>Priority levels: <code>low</code>, <code>normal</code> (default), <code>high</code>, <code>critical</code>.</p>
|
|||
|
|
<h3 id="conditional-behavior-links"><a class="header" href="#conditional-behavior-links">Conditional Behavior Links</a></h3>
|
|||
|
|
<pre><code class="language-storybook">institution BakersGuild {
|
|||
|
|
type: trade_guild
|
|||
|
|
|
|||
|
|
uses behaviors: [
|
|||
|
|
{ tree: ManageApprentices },
|
|||
|
|
{ tree: NegotiateSuppliers, priority: high },
|
|||
|
|
{ tree: EmergencyMeeting, when: reputation < 0.3, priority: critical }
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
</code></pre>
|
|||
|
|
<p>The <code>when</code> clause takes an <a href="./17-expressions.html">expression</a> that determines when the behavior activates.</p>
|
|||
|
|
<h3 id="behavior-link-fields"><a class="header" href="#behavior-link-fields">Behavior Link Fields</a></h3>
|
|||
|
|
<div class="table-wrapper"><table><thead><tr><th>Field</th><th>Required</th><th>Type</th><th>Description</th></tr></thead><tbody>
|
|||
|
|
<tr><td><code>tree</code></td><td>Yes</td><td>path</td><td>Reference to a behavior tree</td></tr>
|
|||
|
|
<tr><td><code>priority</code></td><td>No</td><td>priority level</td><td>Execution priority (default: <code>normal</code>)</td></tr>
|
|||
|
|
<tr><td><code>when</code></td><td>No</td><td>expression</td><td>Activation condition</td></tr>
|
|||
|
|
</tbody></table>
|
|||
|
|
</div>
|
|||
|
|
<hr />
|
|||
|
|
<h2 id="resource-linking-schedules"><a class="header" href="#resource-linking-schedules">Resource Linking: Schedules</a></h2>
|
|||
|
|
<p>Institutions can link to <a href="./14-schedules.html">schedules</a> using the <code>uses schedule</code> or <code>uses schedules</code> clause.</p>
|
|||
|
|
<h3 id="single-schedule"><a class="header" href="#single-schedule">Single Schedule</a></h3>
|
|||
|
|
<pre><code class="language-storybook">institution BakersGuild {
|
|||
|
|
type: trade_guild
|
|||
|
|
uses schedule: GuildOperatingHours
|
|||
|
|
}
|
|||
|
|
</code></pre>
|
|||
|
|
<h3 id="multiple-schedules"><a class="header" href="#multiple-schedules">Multiple Schedules</a></h3>
|
|||
|
|
<pre><code class="language-storybook">institution BakersGuild {
|
|||
|
|
type: trade_guild
|
|||
|
|
uses schedules: [WeekdaySchedule, WeekendSchedule, HolidaySchedule]
|
|||
|
|
}
|
|||
|
|
</code></pre>
|
|||
|
|
<hr />
|
|||
|
|
<h2 id="complete-syntax-example"><a class="header" href="#complete-syntax-example">Complete Syntax Example</a></h2>
|
|||
|
|
<p>An institution using all available features:</p>
|
|||
|
|
<pre><code class="language-storybook">institution BakersGuild {
|
|||
|
|
type: trade_guild
|
|||
|
|
members: 50
|
|||
|
|
founded: "1892"
|
|||
|
|
reputation: 0.85
|
|||
|
|
dues_annual: 120
|
|||
|
|
location: BakersGuildHall
|
|||
|
|
leader: Martha
|
|||
|
|
accepts_apprentices: true
|
|||
|
|
|
|||
|
|
uses behaviors: [
|
|||
|
|
{ tree: ManageApprentices, priority: normal },
|
|||
|
|
{ tree: NegotiateSuppliers, priority: high },
|
|||
|
|
{ tree: HostAnnualBakeOff, when: month is october, priority: high },
|
|||
|
|
{ tree: EmergencyMeeting, when: reputation < 0.3, priority: critical }
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
uses schedule: GuildOperatingHours
|
|||
|
|
|
|||
|
|
---description
|
|||
|
|
The Bakers Guild has been the backbone of the town's bread trade
|
|||
|
|
since 1892. Martha Baker currently serves as Guild Master.
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
---membership_rules
|
|||
|
|
New members must be nominated by an existing member and pass
|
|||
|
|
a baking trial. Apprentices are accepted from age 16.
|
|||
|
|
---
|
|||
|
|
}
|
|||
|
|
</code></pre>
|
|||
|
|
<hr />
|
|||
|
|
<h2 id="membership-modeling"><a class="header" href="#membership-modeling">Membership Modeling</a></h2>
|
|||
|
|
<p>Institutions themselves don’t have a built-in membership list. Instead, model membership through character fields or relationships:</p>
|
|||
|
|
<h3 id="via-character-fields"><a class="header" href="#via-character-fields">Via Character Fields</a></h3>
|
|||
|
|
<pre><code class="language-storybook">character Martha {
|
|||
|
|
age: 45
|
|||
|
|
guild_member: true
|
|||
|
|
guild_role: guild_master
|
|||
|
|
guild: BakersGuild
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
character Jane {
|
|||
|
|
age: 19
|
|||
|
|
guild_member: true
|
|||
|
|
guild_role: apprentice
|
|||
|
|
guild: BakersGuild
|
|||
|
|
}
|
|||
|
|
</code></pre>
|
|||
|
|
<h3 id="via-relationships"><a class="header" href="#via-relationships">Via Relationships</a></h3>
|
|||
|
|
<pre><code class="language-storybook">relationship GuildMembership {
|
|||
|
|
Martha as guild_master { }
|
|||
|
|
BakersGuild as organization { }
|
|||
|
|
bond: 0.95
|
|||
|
|
years_active: 20
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
relationship Apprenticeship {
|
|||
|
|
Jane as apprentice { }
|
|||
|
|
BakersGuild as guild { }
|
|||
|
|
Martha as mentor { }
|
|||
|
|
years_completed: 1
|
|||
|
|
years_remaining: 2
|
|||
|
|
}
|
|||
|
|
</code></pre>
|
|||
|
|
<hr />
|
|||
|
|
<h2 id="institutions-vs-characters"><a class="header" href="#institutions-vs-characters">Institutions vs. Characters</a></h2>
|
|||
|
|
<p>Both institutions and characters can use behaviors and schedules, but they serve different purposes:</p>
|
|||
|
|
<div class="table-wrapper"><table><thead><tr><th>Aspect</th><th>Institutions</th><th>Characters</th></tr></thead><tbody>
|
|||
|
|
<tr><td>Represents</td><td>Organizations, collectives</td><td>Individuals</td></tr>
|
|||
|
|
<tr><td>Species</td><td>No</td><td>Yes (optional)</td></tr>
|
|||
|
|
<tr><td>Templates</td><td>No</td><td>Yes (optional)</td></tr>
|
|||
|
|
<tr><td><code>uses behaviors</code></td><td>Yes</td><td>Yes</td></tr>
|
|||
|
|
<tr><td><code>uses schedule</code></td><td>Yes</td><td>Yes</td></tr>
|
|||
|
|
<tr><td>Prose blocks</td><td>Yes</td><td>Yes</td></tr>
|
|||
|
|
<tr><td>Participation in relationships</td><td>Yes (via name)</td><td>Yes (via name)</td></tr>
|
|||
|
|
</tbody></table>
|
|||
|
|
</div>
|
|||
|
|
<p>Use institutions when you need an entity that acts collectively: a guild votes, a government issues decrees, a school enrolls students.</p>
|
|||
|
|
<hr />
|
|||
|
|
<h2 id="use-cases"><a class="header" href="#use-cases">Use Cases</a></h2>
|
|||
|
|
<ul>
|
|||
|
|
<li><strong>Organizations</strong>: Guilds, companies, governments, religions</li>
|
|||
|
|
<li><strong>Social structures</strong>: Families, tribes, castes, classes</li>
|
|||
|
|
<li><strong>Systems</strong>: Economic systems, magical systems, legal frameworks</li>
|
|||
|
|
<li><strong>Abstract entities</strong>: Dream logic, fate, cultural norms</li>
|
|||
|
|
<li><strong>Collectives</strong>: Military units, sports teams, musical ensembles</li>
|
|||
|
|
</ul>
|
|||
|
|
<hr />
|
|||
|
|
<h2 id="complete-example-baker-family-world"><a class="header" href="#complete-example-baker-family-world">Complete Example: Baker Family World</a></h2>
|
|||
|
|
<pre><code class="language-storybook">use schema::enums::{GuildRole, InstitutionType};
|
|||
|
|
|
|||
|
|
institution BakersGuild {
|
|||
|
|
type: trade_guild
|
|||
|
|
members: 50
|
|||
|
|
founded: "1892"
|
|||
|
|
reputation: 0.85
|
|||
|
|
location: BakersGuildHall
|
|||
|
|
leader: Martha
|
|||
|
|
annual_dues: 120
|
|||
|
|
accepts_apprentices: true
|
|||
|
|
max_apprentices_per_mentor: 2
|
|||
|
|
|
|||
|
|
uses behaviors: [
|
|||
|
|
{ tree: ManageApprentices, priority: normal },
|
|||
|
|
{ tree: NegotiateSuppliers, priority: high },
|
|||
|
|
{ tree: HostAnnualBakeOff, when: month is october, priority: high }
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
uses schedule: GuildOperatingHours
|
|||
|
|
|
|||
|
|
---description
|
|||
|
|
The Bakers Guild has served the town since 1892, ensuring quality
|
|||
|
|
standards and fair pricing across all bakeries. Monthly meetings
|
|||
|
|
are held at the Guild Hall, and the annual Bake-Off is the
|
|||
|
|
highlight of the autumn calendar.
|
|||
|
|
---
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
institution TownCouncil {
|
|||
|
|
type: government
|
|||
|
|
members: 12
|
|||
|
|
meets: "first Monday of each month"
|
|||
|
|
location: TownHall
|
|||
|
|
jurisdiction: "town limits"
|
|||
|
|
|
|||
|
|
uses behaviors: [
|
|||
|
|
{ tree: ReviewPetitions },
|
|||
|
|
{ tree: AllocateBudget, priority: high }
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
---description
|
|||
|
|
The elected body governing the town. Martha Baker has been
|
|||
|
|
lobbying them for years about flour import tariffs.
|
|||
|
|
---
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
institution BakersBakeryBusiness {
|
|||
|
|
type: business
|
|||
|
|
owner: Martha
|
|||
|
|
employees: 4
|
|||
|
|
location: BakersBakery
|
|||
|
|
annual_revenue: 180000
|
|||
|
|
established: "2011"
|
|||
|
|
|
|||
|
|
uses behaviors: [
|
|||
|
|
{ tree: DailyBakingOps, priority: high },
|
|||
|
|
{ tree: InventoryManagement },
|
|||
|
|
{ tree: CustomerService }
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
uses schedule: BakeryOperatingHours
|
|||
|
|
|
|||
|
|
---description
|
|||
|
|
The business entity behind Baker's Bakery. Martha runs the
|
|||
|
|
operation with help from her daughter Jane (apprentice baker),
|
|||
|
|
two full-time bakers, and a part-time cashier.
|
|||
|
|
---
|
|||
|
|
}
|
|||
|
|
</code></pre>
|
|||
|
|
<hr />
|
|||
|
|
<h2 id="validation-rules"><a class="header" href="#validation-rules">Validation Rules</a></h2>
|
|||
|
|
<ol>
|
|||
|
|
<li><strong>Unique names</strong>: Institution names must be unique within their scope</li>
|
|||
|
|
<li><strong>Valid field values</strong>: All fields must have values conforming to <a href="./18-value-types.html">value types</a></li>
|
|||
|
|
<li><strong>Unique field names</strong>: No duplicate field names within an institution</li>
|
|||
|
|
<li><strong>Unique prose tags</strong>: No duplicate prose block tags within an institution</li>
|
|||
|
|
<li><strong>Valid behavior links</strong>: Each behavior link must have a <code>tree</code> field</li>
|
|||
|
|
<li><strong>Valid priority levels</strong>: Priority must be <code>low</code>, <code>normal</code>, <code>high</code>, or <code>critical</code></li>
|
|||
|
|
<li><strong>Valid schedule references</strong>: Schedule names in <code>uses schedule</code>/<code>uses schedules</code> must be valid identifiers</li>
|
|||
|
|
<li><strong>Valid identifiers</strong>: Institution names must follow identifier rules (<code>[a-zA-Z_][a-zA-Z0-9_]*</code>)</li>
|
|||
|
|
</ol>
|
|||
|
|
<hr />
|
|||
|
|
<h2 id="cross-references"><a class="header" href="#cross-references">Cross-References</a></h2>
|
|||
|
|
<ul>
|
|||
|
|
<li><a href="./10-characters.html">Characters</a> – Characters can be members of institutions</li>
|
|||
|
|
<li><a href="./16a-locations.html">Locations</a> – Institutions can be associated with locations</li>
|
|||
|
|
<li><a href="./11-behavior-trees.html">Behavior Trees</a> – Institutions can use behaviors</li>
|
|||
|
|
<li><a href="./14-schedules.html">Schedules</a> – Institutions can use schedules</li>
|
|||
|
|
<li><a href="./15-relationships.html">Relationships</a> – Model membership via relationships</li>
|
|||
|
|
<li><a href="./17-expressions.html">Expressions</a> – Conditional behavior activation</li>
|
|||
|
|
<li><a href="./18-value-types.html">Value Types</a> – All field value types</li>
|
|||
|
|
<li><a href="./16-other-declarations.html">Other Declarations</a> – Overview of all utility declarations</li>
|
|||
|
|
<li><a href="./19-validation.html">Validation Rules</a> – Complete validation reference</li>
|
|||
|
|
</ul>
|
|||
|
|
|
|||
|
|
</main>
|
|||
|
|
|
|||
|
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
|||
|
|
<!-- Mobile navigation buttons -->
|
|||
|
|
<a rel="prev" href="../reference/16a-locations.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
|||
|
|
<i class="fa fa-angle-left"></i>
|
|||
|
|
</a>
|
|||
|
|
|
|||
|
|
<a rel="next prefetch" href="../reference/16-other-declarations.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
|||
|
|
<i class="fa fa-angle-right"></i>
|
|||
|
|
</a>
|
|||
|
|
|
|||
|
|
<div style="clear: both"></div>
|
|||
|
|
</nav>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
|||
|
|
<a rel="prev" href="../reference/16a-locations.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
|||
|
|
<i class="fa fa-angle-left"></i>
|
|||
|
|
</a>
|
|||
|
|
|
|||
|
|
<a rel="next prefetch" href="../reference/16-other-declarations.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
|||
|
|
<i class="fa fa-angle-right"></i>
|
|||
|
|
</a>
|
|||
|
|
</nav>
|
|||
|
|
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- Livereload script (if served using the cli tool) -->
|
|||
|
|
<script>
|
|||
|
|
const wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
|||
|
|
const wsAddress = wsProtocol + "//" + location.host + "/" + "__livereload";
|
|||
|
|
const socket = new WebSocket(wsAddress);
|
|||
|
|
socket.onmessage = function (event) {
|
|||
|
|
if (event.data === "reload") {
|
|||
|
|
socket.close();
|
|||
|
|
location.reload();
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
window.onbeforeunload = function() {
|
|||
|
|
socket.close();
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
window.playground_copyable = true;
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
|
|||
|
|
<script src="../elasticlunr.min.js"></script>
|
|||
|
|
<script src="../mark.min.js"></script>
|
|||
|
|
<script src="../searcher.js"></script>
|
|||
|
|
|
|||
|
|
<script src="../clipboard.min.js"></script>
|
|||
|
|
<script src="../highlight.js"></script>
|
|||
|
|
<script src="../book.js"></script>
|
|||
|
|
|
|||
|
|
<!-- Custom JS scripts -->
|
|||
|
|
|
|||
|
|
|
|||
|
|
</div>
|
|||
|
|
</body>
|
|||
|
|
</html>
|