Structure introspection
Sometimes a tool needs to see the shape of the writing, not play it: list the scenes, the blocks in each, the snippets, and the beats inside them, with their ids, types, and data. Every Patterplay engine exposes this as a read-only, static view of the compiled bundle: no flow, no play state.
A concrete example: in Unreal you can build a Sequencer of subsequences, one per beat the writer
authored, by walking the flat beat list and reading each beat’s gameData to drive audio, camera, or
animation tracks.
Two views: tree and flat
Section titled “Two views: tree and flat”Both hang off the engine (build one from your bundle, then call these, no flow needed):
getOutline()returns the nested tree: scenes → blocks → children (groups and snippets, groups preserved) → a snippet’s beats. Use it to browse or mirror the authored structure, branches and all.getBeatSequence()returns the flat, document-ordered list of every beat, each with the{ scene, block, snippet }it belongs to. Use it to lay one thing per beat.
Each beat carries the same data a played step would: id, kind (line / text / gameEvent),
character + resolved characterName, direction, the source text (un-interpolated), the
author gameData overrides, and accumulated tags. Text and names are read at the source locale.
Per engine
Section titled “Per engine”JavaScript (@patterkit/runtime):
const engine = new Engine(BUNDLE);const outline = engine.getOutline(); // OutlineScene[]for (const flat of engine.getBeatSequence()) { // flat.sceneId / flat.blockId / flat.snippetId, flat.beat.{id,kind,character,text,gameData,tags}}Unity (C#):
var engine = new Engine(bundle);List<OutlineScene> outline = engine.GetOutline();foreach (var flat in engine.GetBeatSequence()){ // flat.SceneId, flat.Beat.Id, flat.Beat.Kind, flat.Beat.GameData ...}Unreal (C++ / Blueprint):
UPatterEngine* Engine = UPatterEngine::Create(Bundle);TArray<FPatterOutlineScene> Outline = Engine->GetOutline();for (const FPatterFlatBeat& Flat : Engine->GetBeatSequence()){ // Flat.SnippetId, Flat.Beat.Id, Flat.Beat.Kind, Flat.Beat.GameData (name/type/value) ...}Both GetOutline and GetBeatSequence are BlueprintCallable, so a designer can build the Sequencer
graph without C++. One Unreal-specific wrinkle: a Blueprint struct can’t nest itself, so the tree is
stored flat on each block (Nodes) and linked by index (RootIndices, and each group node’s
ChildIndices) rather than by nested children. GetBeatSequence needs none of that.
Godot (GDScript):
var engine := PatterEngine.new(bundle)var outline := engine.get_outline()for flat in engine.get_beat_sequence(): # flat["sceneId"], flat["beat"]["id"], flat["beat"]["kind"], flat["beat"]["gameData"] ... pass- Read-only + static. These reflect the compiled bundle, not a running flow.
gameDatais the author’s raw overrides (the same the step carries); merge with your defaults if you want the full set. - Source locale.
textandcharacterNamecome from the source language; an IDs-only bundle has no embedded text, sotextis empty. - Order. Within a scene, blocks / nodes / beats are in authored order. Across scenes the order is the bundle’s scene order on most engines; the C++ (Unreal) engine iterates scenes by id. A branching multi-scene story has no single linear order anyway, so key off the scene id when it matters.
MIT-licensed open source · Made by Ian Thomas · patterkit.com