Files
storybook/docs/book/reference/10-characters.html
Sienna Meridian Satterwhite 16deb5d237 release: Storybook v0.2.0 - Major syntax and features update
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
2026-02-13 21:52:03 +00:00

612 lines
26 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE HTML>
<html lang="en" class="light sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Characters - 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="characters"><a class="header" href="#characters">Characters</a></h1>
<p>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.</p>
<h2 id="syntax"><a class="header" href="#syntax">Syntax</a></h2>
<pre><code class="language-bnf">&lt;character-decl&gt; ::= "character" &lt;identifier&gt; &lt;species-clause&gt;? &lt;template-clause&gt;? &lt;body&gt;
&lt;species-clause&gt; ::= ":" &lt;qualified-path&gt;
&lt;template-clause&gt; ::= "from" &lt;qualified-path&gt; ("," &lt;qualified-path&gt;)*
&lt;body&gt; ::= "{" &lt;body-item&gt;* "}"
&lt;body-item&gt; ::= &lt;field&gt;
| &lt;uses-behaviors&gt;
| &lt;uses-schedule&gt;
&lt;uses-behaviors&gt; ::= "uses" "behaviors" ":" &lt;behavior-link-list&gt;
&lt;uses-schedule&gt; ::= "uses" ("schedule" | "schedules") ":" (&lt;qualified-path&gt; | &lt;schedule-list&gt;)
&lt;behavior-link-list&gt; ::= "[" &lt;behavior-link&gt; ("," &lt;behavior-link&gt;)* "]"
&lt;behavior-link&gt; ::= "{" &lt;behavior-link-field&gt;* "}"
&lt;behavior-link-field&gt; ::= "tree" ":" &lt;qualified-path&gt;
| "when" ":" &lt;expression&gt;
| "priority" ":" ("low" | "normal" | "high" | "critical")
&lt;schedule-list&gt; ::= "[" &lt;qualified-path&gt; ("," &lt;qualified-path&gt;)* "]"
&lt;field&gt; ::= &lt;identifier&gt; ":" &lt;value&gt;
&lt;value&gt; ::= &lt;literal&gt;
| &lt;qualified-path&gt;
| &lt;list&gt;
| &lt;object&gt;
| &lt;prose-block&gt;
| &lt;override&gt;
&lt;prose-block&gt; ::= "---" &lt;identifier&gt; &lt;content&gt; "---"
</code></pre>
<h2 id="components"><a class="header" href="#components">Components</a></h2>
<h3 id="name"><a class="header" href="#name">Name</a></h3>
<p>The characters identifier. Must be unique within its scope and follow standard identifier rules (alphanumeric + underscore, cannot start with digit).</p>
<h3 id="species-optional"><a class="header" href="#species-optional">Species (Optional)</a></h3>
<p>The species clause (<code>: SpeciesName</code>) defines what the character fundamentally <em>is</em>. This is distinct from templates, which define what attributes they <em>have</em>.</p>
<ul>
<li><strong>Purpose</strong>: Ontological typing—what kind of being this is</li>
<li><strong>Validation</strong>: Must reference a defined <code>species</code> declaration</li>
<li><strong>Single inheritance</strong>: A character can only have one species</li>
<li><strong>Default behavior</strong>: Species fields are inherited automatically</li>
</ul>
<p>Example:</p>
<pre><code class="language-storybook">character Martha: Human {
age: 34
}
</code></pre>
<h3 id="template-inheritance-optional"><a class="header" href="#template-inheritance-optional">Template Inheritance (Optional)</a></h3>
<p>The template clause (<code>from Template1, Template2</code>) specifies templates from which the character inherits fields. Templates provide reusable attribute sets.</p>
<ul>
<li><strong>Purpose</strong>: Compositional inheritance—mix-and-match capabilities and traits</li>
<li><strong>Multiple inheritance</strong>: Characters can inherit from multiple templates</li>
<li><strong>Merge semantics</strong>: Fields from later templates override earlier ones</li>
<li><strong>Override allowed</strong>: Character fields override all inherited fields</li>
</ul>
<p>Example:</p>
<pre><code class="language-storybook">character Martha: Human from Baker, BusinessOwner {
specialty: "sourdough"
}
</code></pre>
<h3 id="fields"><a class="header" href="#fields">Fields</a></h3>
<p>Fields define the characters attributes using the standard field syntax. All <a href="./18-value-types.html">value types</a> are supported.</p>
<p><strong>Common field categories:</strong></p>
<ul>
<li><strong>Physical traits</strong>: <code>height</code>, <code>weight</code>, <code>age</code>, <code>eye_color</code></li>
<li><strong>Personality</strong>: <code>confidence</code>, <code>patience</code>, <code>dedication</code></li>
<li><strong>Professional</strong>: <code>skill_level</code>, <code>specialty</code>, <code>recipes_mastered</code></li>
<li><strong>State tracking</strong>: <code>energy</code>, <code>mood</code>, <code>orders_today</code></li>
<li><strong>Capabilities</strong>: <code>can_teach</code>, <code>can_work_independently</code></li>
</ul>
<h3 id="prose-blocks"><a class="header" href="#prose-blocks">Prose Blocks</a></h3>
<p>Characters can contain multiple prose blocks for narrative content. Common tags:</p>
<ul>
<li><code>---backstory</code>: Character history and origin</li>
<li><code>---appearance</code>: Physical description</li>
<li><code>---personality</code>: Behavioral traits and quirks</li>
<li><code>---motivation</code>: Goals and desires</li>
<li><code>---secrets</code>: Hidden information</li>
</ul>
<p>Prose blocks are narrative-only and do not affect simulation logic.</p>
<h3 id="behavior-integration"><a class="header" href="#behavior-integration">Behavior Integration</a></h3>
<p>Characters can link to <a href="./14-behavior-trees.html">behavior trees</a> using the <code>uses behaviors</code> clause.</p>
<pre><code class="language-storybook">character Guard {
uses behaviors: [
{
tree: combat::patrol_route
priority: normal
},
{
tree: combat::engage_intruder
when: threat_detected
priority: high
}
]
}
</code></pre>
<p>Each behavior link includes:</p>
<ul>
<li><strong><code>tree</code></strong>: Qualified path to the behavior tree (required)</li>
<li><strong><code>when</code></strong>: Condition expression for activation (optional)</li>
<li><strong><code>priority</code></strong>: Execution priority (optional, default: <code>normal</code>)</li>
</ul>
<p>See <a href="./11-behavior-trees.html">Behavior Trees</a> for details on behavior tree syntax and semantics.</p>
<h3 id="schedule-integration"><a class="header" href="#schedule-integration">Schedule Integration</a></h3>
<p>Characters can follow <a href="./16-schedules.html">schedules</a> using the <code>uses schedule</code> or <code>uses schedules</code> clause.</p>
<pre><code class="language-storybook">character Baker {
uses schedule: BakerySchedule
}
character Innkeeper {
uses schedules: [WeekdaySchedule, WeekendSchedule]
}
</code></pre>
<ul>
<li>Single schedule: <code>uses schedule: ScheduleName</code></li>
<li>Multiple schedules: <code>uses schedules: [Schedule1, Schedule2]</code></li>
</ul>
<p>The runtime selects the appropriate schedule based on temporal constraints. See <a href="./14-schedules.html">Schedules</a> for composition and selection semantics.</p>
<h2 id="species-vs-templates"><a class="header" href="#species-vs-templates">Species vs. Templates</a></h2>
<p>The distinction between species (<code>:</code>) and templates (<code>from</code>) reflects ontological vs. compositional typing:</p>
<div class="table-wrapper"><table><thead><tr><th>Feature</th><th>Species (<code>:</code>)</th><th>Templates (<code>from</code>)</th></tr></thead><tbody>
<tr><td><strong>Semantics</strong></td><td>What the character <em>is</em></td><td>What the character <em>has</em></td></tr>
<tr><td><strong>Cardinality</strong></td><td>Exactly one</td><td>Zero or more</td></tr>
<tr><td><strong>Example</strong></td><td><code>: Human</code>, <code>: Dragon</code></td><td><code>from Warrior, Mage</code></td></tr>
<tr><td><strong>Purpose</strong></td><td>Fundamental nature</td><td>Reusable trait sets</td></tr>
<tr><td><strong>Override</strong></td><td>Can override species fields</td><td>Can override template fields</td></tr>
</tbody></table>
</div>
<p>Example showing both:</p>
<pre><code class="language-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
}
</code></pre>
<h2 id="field-resolution-order"><a class="header" href="#field-resolution-order">Field Resolution Order</a></h2>
<p>When a character inherits from species and templates, fields are resolved in this order (later overrides earlier):</p>
<ol>
<li><strong>Species fields</strong> (base ontology)</li>
<li><strong>Template fields</strong> (left to right in <code>from</code> clause)</li>
<li><strong>Character fields</strong> (highest priority)</li>
</ol>
<p>Example:</p>
<pre><code class="language-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)
</code></pre>
<h2 id="validation-rules"><a class="header" href="#validation-rules">Validation Rules</a></h2>
<p>The Storybook compiler enforces these validation rules:</p>
<ol>
<li><strong>Unique names</strong>: Character names must be unique within their module</li>
<li><strong>Species exists</strong>: If specified, the species must reference a defined <code>species</code> declaration</li>
<li><strong>Templates exist</strong>: All templates in the <code>from</code> clause must reference defined <code>template</code> declarations</li>
<li><strong>No circular inheritance</strong>: Templates cannot form circular dependency chains</li>
<li><strong>Field type consistency</strong>: Field values must match expected types from species/templates</li>
<li><strong>Reserved fields</strong>: Cannot use reserved keywords as field names</li>
<li><strong>Behavior trees exist</strong>: All behavior tree references must resolve to defined <code>behavior</code> declarations</li>
<li><strong>Schedules exist</strong>: All schedule references must resolve to defined <code>schedule</code> declarations</li>
<li><strong>Prose tag uniqueness</strong>: Each prose tag can appear at most once per character</li>
</ol>
<h2 id="examples"><a class="header" href="#examples">Examples</a></h2>
<h3 id="basic-character"><a class="header" href="#basic-character">Basic Character</a></h3>
<pre><code class="language-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.
---
}
</code></pre>
<h3 id="character-with-species"><a class="header" href="#character-with-species">Character with Species</a></h3>
<pre><code class="language-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.
---
}
</code></pre>
<h3 id="character-with-template-inheritance"><a class="header" href="#character-with-template-inheritance">Character with Template Inheritance</a></h3>
<pre><code class="language-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.
---
}
</code></pre>
<h3 id="character-with-all-features"><a class="header" href="#character-with-all-features">Character with All Features</a></h3>
<pre><code class="language-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.
---
}
</code></pre>
<h3 id="character-with-overrides"><a class="header" href="#character-with-overrides">Character with Overrides</a></h3>
<pre><code class="language-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"
}
</code></pre>
<h2 id="use-cases"><a class="header" href="#use-cases">Use Cases</a></h2>
<h3 id="protagonist-definition"><a class="header" href="#protagonist-definition">Protagonist Definition</a></h3>
<p>Define rich, dynamic protagonists with complex attributes:</p>
<pre><code class="language-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.
---
}
</code></pre>
<h3 id="npc-templates"><a class="header" href="#npc-templates">NPC Templates</a></h3>
<p>Create diverse NPCs from templates:</p>
<pre><code class="language-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
}
</code></pre>
<h3 id="ensemble-casts"><a class="header" href="#ensemble-casts">Ensemble Casts</a></h3>
<p>Define multiple related characters:</p>
<pre><code class="language-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.
---
}
</code></pre>
<h2 id="cross-references"><a class="header" href="#cross-references">Cross-References</a></h2>
<ul>
<li><a href="./16-other-declarations.html#species">Species</a> - Species declarations</li>
<li><a href="./16-other-declarations.html#templates">Templates</a> - Template definitions and strict mode</li>
<li><a href="./18-value-types.html">Value Types</a> - All supported value types</li>
<li><a href="./11-behavior-trees.html">Behavior Trees</a> - Character behavior integration</li>
<li><a href="./14-schedules.html">Schedules</a> - Character schedule integration</li>
<li><a href="./15-relationships.html">Relationships</a> - Relationships between characters</li>
<li><a href="./13-life-arcs.html">Life Arcs</a> - Character state machines over time</li>
</ul>
<h2 id="related-concepts"><a class="header" href="#related-concepts">Related Concepts</a></h2>
<ul>
<li><strong>Instantiation</strong>: Characters are concrete instances; they cannot be instantiated further</li>
<li><strong>Composition</strong>: Prefer template composition over deep species hierarchies</li>
<li><strong>Modularity</strong>: Characters can reference behaviors and schedules from other modules</li>
<li><strong>Narrative-driven</strong>: Use prose blocks to embed storytelling directly with data</li>
</ul>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../reference/09-overview.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/11-behavior-trees.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/09-overview.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/11-behavior-trees.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>