Files
storybook/docs/book/advanced/22-integration.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

362 lines
17 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>Integration Guide - 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="integration-guide"><a class="header" href="#integration-guide">Integration Guide</a></h1>
<p>This chapter covers how to integrate Storybook into larger systems game engines, simulation frameworks, and custom applications.</p>
<h2 id="architecture-overview"><a class="header" href="#architecture-overview">Architecture Overview</a></h2>
<p>Storybook operates in two phases:</p>
<ol>
<li><strong>Compile time</strong>: <code>.sb</code> files are parsed, validated, and compiled into SBIR</li>
<li><strong>Runtime</strong>: A simulation engine consumes SBIR and drives character behavior</li>
</ol>
<pre><code> Compile Time Runtime
.sb files → [Storybook Compiler] → SBIR → [Simulation Engine] → Character Actions
</code></pre>
<h2 id="the-storybook-compiler"><a class="header" href="#the-storybook-compiler">The Storybook Compiler</a></h2>
<p>The compiler is a Rust library and CLI tool that processes <code>.sb</code> files.</p>
<h3 id="cli-usage"><a class="header" href="#cli-usage">CLI Usage</a></h3>
<pre><code class="language-bash"># Compile a directory of .sb files
storybook compile path/to/project/
# Compile with output path
storybook compile path/to/project/ -o output.sbir
# Validate without producing output
storybook check path/to/project/
</code></pre>
<h3 id="as-a-library"><a class="header" href="#as-a-library">As a Library</a></h3>
<p>The compiler can be embedded as a Rust dependency:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use storybook::syntax::parse_file;
use storybook::resolve::resolve_files;
// Parse .sb files into ASTs
let ast = parse_file(source_code)?;
// Resolve across multiple files
let resolved = resolve_files(vec![ast1, ast2, ast3])?;
// Access resolved data
for character in resolved.characters() {
println!("{}: {:?}", character.name, character.fields);
}
<span class="boring">}</span></code></pre></pre>
<h3 id="key-types"><a class="header" href="#key-types">Key Types</a></h3>
<p>The resolved output provides these primary types:</p>
<div class="table-wrapper"><table><thead><tr><th>Type</th><th>Description</th></tr></thead><tbody>
<tr><td><code>ResolvedFile</code></td><td>Container for all resolved declarations</td></tr>
<tr><td><code>ResolvedCharacter</code></td><td>Character with merged species/template fields</td></tr>
<tr><td><code>ResolvedBehavior</code></td><td>Behavior tree with resolved subtree references</td></tr>
<tr><td><code>ResolvedLifeArc</code></td><td>State machine with validated transitions</td></tr>
<tr><td><code>ResolvedSchedule</code></td><td>Schedule with resolved time blocks</td></tr>
<tr><td><code>ResolvedRelationship</code></td><td>Relationship with resolved participant references</td></tr>
<tr><td><code>ResolvedInstitution</code></td><td>Institution with resolved fields</td></tr>
<tr><td><code>ResolvedLocation</code></td><td>Location with resolved fields</td></tr>
<tr><td><code>ResolvedSpecies</code></td><td>Species with resolved includes chain</td></tr>
<tr><td><code>ResolvedEnum</code></td><td>Enum with variant list</td></tr>
</tbody></table>
</div>
<h2 id="runtime-integration"><a class="header" href="#runtime-integration">Runtime Integration</a></h2>
<h3 id="behavior-tree-execution"><a class="header" href="#behavior-tree-execution">Behavior Tree Execution</a></h3>
<p>Runtimes are responsible for:</p>
<ol>
<li><strong>Tick-based evaluation</strong>: Call the behavior tree root each frame/tick</li>
<li><strong>Action execution</strong>: Interpret action nodes (e.g., <code>MoveTo</code>, <code>Attack</code>)</li>
<li><strong>Condition evaluation</strong>: Evaluate expression nodes against current state</li>
<li><strong>Decorator state</strong>: Maintain timer/counter state for stateful decorators</li>
</ol>
<h3 id="life-arc-execution"><a class="header" href="#life-arc-execution">Life Arc Execution</a></h3>
<ol>
<li>Track the current state for each life arc instance</li>
<li>Evaluate transition conditions each tick</li>
<li>Execute on-enter actions when transitioning</li>
<li>Maintain state persistence across ticks</li>
</ol>
<h3 id="schedule-execution"><a class="header" href="#schedule-execution">Schedule Execution</a></h3>
<ol>
<li>Get the current simulation time</li>
<li>Find the matching schedule block (considering temporal constraints and recurrences)</li>
<li>Execute the associated behavior tree action</li>
</ol>
<h3 id="relationship-queries"><a class="header" href="#relationship-queries">Relationship Queries</a></h3>
<p>Provide APIs for querying the relationship graph:</p>
<ul>
<li>Find all relationships for a character</li>
<li>Get bond strength between two entities</li>
<li>Query perspective fields (self/other)</li>
</ul>
<h2 id="lsp-integration"><a class="header" href="#lsp-integration">LSP Integration</a></h2>
<p>Storybook includes a Language Server Protocol (LSP) implementation for editor support:</p>
<ul>
<li><strong>Hover information</strong>: Documentation for keywords and declarations</li>
<li><strong>Go to definition</strong>: Navigate to declaration sources</li>
<li><strong>Diagnostics</strong>: Real-time error reporting</li>
<li><strong>Completions</strong>: Context-aware suggestions</li>
</ul>
<p>The LSP server reuses the compilers parser and resolver, providing the same validation as the CLI.</p>
<h3 id="editor-setup"><a class="header" href="#editor-setup">Editor Setup</a></h3>
<p>The Storybook LSP works with any editor that supports LSP:</p>
<ul>
<li><strong>VS Code</strong>: Via the Storybook extension</li>
<li><strong>Zed</strong>: Via the zed-storybook extension</li>
<li><strong>Other editors</strong>: Any LSP-compatible editor</li>
</ul>
<h2 id="tree-sitter-grammar"><a class="header" href="#tree-sitter-grammar">Tree-sitter Grammar</a></h2>
<p>A Tree-sitter grammar is provided for syntax highlighting and structural queries:</p>
<pre><code>tree-sitter-storybook/
grammar.js # Grammar definition
src/ # Generated parser
</code></pre>
<p>The Tree-sitter grammar supports:</p>
<ul>
<li>Syntax highlighting in editors</li>
<li>Structural code queries</li>
<li>Incremental parsing for large files</li>
</ul>
<h2 id="file-organization-for-integration"><a class="header" href="#file-organization-for-integration">File Organization for Integration</a></h2>
<p>Organize your project to support both authoring and runtime consumption:</p>
<pre><code>my-game/
storybook/ # Storybook source files
schema/
core_enums.sb
templates.sb
beings.sb
world/
characters/
behaviors/
relationships/
assets/
narrative.sbir # Compiled output for runtime
src/
narrative_engine.rs # Runtime that consumes SBIR
</code></pre>
<h2 id="cross-references"><a class="header" href="#cross-references">Cross-References</a></h2>
<ul>
<li><a href="./21-sbir-format.html">SBIR Format</a> - The compiled binary format</li>
<li><a href="../reference/19-validation.html">Validation Rules</a> - What the compiler checks</li>
<li><a href="../reference/09-overview.html">Language Overview</a> - Compilation pipeline</li>
</ul>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../advanced/21-sbir-format.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="../advanced/23-best-practices.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="../advanced/21-sbir-format.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="../advanced/23-best-practices.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>