Files
storybook/docs/book/advanced/21-sbir-format.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

290 lines
15 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>The SBIR Binary Format - 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="the-sbir-binary-format"><a class="header" href="#the-sbir-binary-format">The SBIR Binary Format</a></h1>
<p>SBIR (Storybook Intermediate Representation) is the compiled binary format produced by the Storybook compiler. It transforms human-readable <code>.sb</code> files into an optimized, machine-consumable format for simulation runtimes.</p>
<h2 id="compilation-pipeline"><a class="header" href="#compilation-pipeline">Compilation Pipeline</a></h2>
<pre><code>.sb files → Lexer → Parser → AST → Resolver → SBIR Binary
</code></pre>
<ol>
<li><strong>Lexer</strong>: Tokenizes raw text into tokens</li>
<li><strong>Parser</strong>: Builds an Abstract Syntax Tree (AST) from tokens</li>
<li><strong>Resolver</strong>: Validates, resolves cross-references, merges templates, and produces SBIR</li>
</ol>
<h2 id="what-sbir-contains"><a class="header" href="#what-sbir-contains">What SBIR Contains</a></h2>
<p>SBIR represents the fully resolved state of a Storybook project:</p>
<ul>
<li><strong>Characters</strong>: All fields resolved (species + templates merged, overrides applied)</li>
<li><strong>Behaviors</strong>: Behavior trees with all subtree references inlined</li>
<li><strong>Life Arcs</strong>: State machines with validated transitions</li>
<li><strong>Schedules</strong>: Time blocks with resolved action references</li>
<li><strong>Relationships</strong>: Participants with resolved entity references</li>
<li><strong>Institutions</strong>: Fully resolved field sets</li>
<li><strong>Locations</strong>: Fully resolved field sets</li>
<li><strong>Species</strong>: Fully resolved inheritance chains</li>
<li><strong>Enums</strong>: Complete variant lists</li>
</ul>
<h2 id="resolution-process"><a class="header" href="#resolution-process">Resolution Process</a></h2>
<h3 id="template-merging"><a class="header" href="#template-merging">Template Merging</a></h3>
<p>When a character uses templates, SBIR contains the fully merged result:</p>
<p><strong>Source:</strong></p>
<pre><code class="language-storybook">species Human { lifespan: 70, speed: 1.0 }
template Warrior { speed: 1.5, strength: 10 }
character Conan: Human from Warrior {
strength: 20
}
</code></pre>
<p><strong>In SBIR, Conans fields are:</strong></p>
<ul>
<li><code>lifespan: 70</code> (from Human)</li>
<li><code>speed: 1.5</code> (Warrior overrides Human)</li>
<li><code>strength: 20</code> (Conan overrides Warrior)</li>
</ul>
<h3 id="cross-file-reference-resolution"><a class="header" href="#cross-file-reference-resolution">Cross-File Reference Resolution</a></h3>
<p>SBIR resolves all <code>use</code> statements and qualified paths. A relationship referencing <code>Martha</code> in a different file is resolved to the concrete character definition.</p>
<h3 id="validation"><a class="header" href="#validation">Validation</a></h3>
<p>Before producing SBIR, the resolver validates all constraints documented in <a href="../reference/19-validation.html">Validation Rules</a>:</p>
<ul>
<li>All references resolve to defined declarations</li>
<li>No circular dependencies</li>
<li>Type consistency</li>
<li>Domain constraints (bond ranges, schedule validity)</li>
</ul>
<h2 id="design-goals"><a class="header" href="#design-goals">Design Goals</a></h2>
<p><strong>Compact</strong>: SBIR strips comments, whitespace, and redundant structure.</p>
<p><strong>Self-contained</strong>: No external references everything is resolved and inlined.</p>
<p><strong>Fast to load</strong>: Simulation runtimes can load SBIR without re-parsing or re-resolving.</p>
<p><strong>Validated</strong>: If SBIR was produced, the source was valid. Runtimes do not need to re-validate.</p>
<h2 id="usage"><a class="header" href="#usage">Usage</a></h2>
<p>SBIR is consumed by simulation runtimes that drive character behavior, schedule execution, life arc transitions, and relationship queries. The specific binary format is implementation-defined and may evolve between versions.</p>
<p>For the current SBIR specification, see the <a href="../SBIR-v0.2.0-SPEC.html">SBIR v0.2.0 Spec</a>.</p>
<h2 id="cross-references"><a class="header" href="#cross-references">Cross-References</a></h2>
<ul>
<li><a href="../reference/09-overview.html">Language Overview</a> - Compilation model</li>
<li><a href="../reference/19-validation.html">Validation Rules</a> - What is validated before SBIR production</li>
<li><a href="./22-integration.html">Integration Guide</a> - How runtimes consume SBIR</li>
</ul>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../advanced/20-patterns.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/22-integration.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/20-patterns.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/22-integration.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>