Godot Plugin Changelog
New updates and improvements to the StoryFlow plugin for Godot.
Godot Plugin v1.2.2
Export Fixes, Autoload Reliability & Dialogue Tags
Fixes exported games shipping without media and without a project the runtime can load, plus an intermittent parse failure that killed the StoryFlow autoload when launching a scene. Sync now reports failed writes instead of announcing success, and dialogue nodes can emit tag events.
What's New
Bug Fixes
- Media missing from exported games: images and audio resolved in the editor and in play mode but failed in an exported game with
Source media file not found, so dialogues rendered without portraits or sound. Godot exports pack only the imported version of a media file (CompressedTexture2D,AudioStreamWAVand so on), never the raw bytes, and the importer read media exclusively through file buffers. Media now falls back toResourceLoaderwhen the raw file is not readable, reaching the imported resource through Godot’s path remap. Loading a project at runtime also no longer spams “Could not create directory” errors on the read-onlyres://of an exported game - Exported games never auto-loading a synced project: a project synced from a
project.storyflowbuild was not found at startup in an exported game, because Godot never packs a readableproject.storyflow: unimported it is left out of the pack, imported it is replaced by the plugin’s marker resource. The sync now publishes the parsed project file into the output directory asproject.json, which exports pack as raw bytes. Verified end to end against a PCK export - Intermittent autoload parse failure: running a scene from the editor occasionally died with
Parser Error: Could not find type "StoryFlowProject" in the current scopeatstoryflow_manager.gd:9, killing theStoryFlowRuntimeautoload for that run. Global class name resolution in a running game reads a cache file the editor can be rewriting at the moment the game process launches (godotengine/godot#75388). Every script the game parses at runtime now resolves its sibling classes by path instead of through that cache.class_namedeclarations are unchanged, so game code keeps using the global names - Global and character image and audio variables falling back to defaults: a global Image variable wired into a Set Character Variable node showed the character’s default portrait instead of the assigned image, even though the editor preview was correct. The importer read only the variables and strings from
global-variables.jsonand never its assets section, so the asset key had nothing to resolve against at runtime. Custom image and audio character variables and character map values had the same gap incharacters.json, where only the portrait was imported. Both files’ assets are now imported into the project asset pool, which is also what makes global and character audio resolve {charVar.Name}rendering as literal placeholder text: reaching through a character-type variable to a field on the character it points to, for example{player1.Name}, printed the placeholder verbatim in Godot while the editor runtime resolved it. Character-type variables now resolve their inner fields,{Character.Name}is matched case-insensitively and string-typed inner character variable values resolve through the string table, for parity with the editor runtime- Sync reporting success after failed writes: failed media copies, build directory copies, directory creation and metadata writes only pushed a line into the Output log while the dock still announced a clean
Sync: <title> (N scripts). Syncs and manual imports now append “N errors. Check Output log.” whenever something failed. The total is exposed asget_error_count()onStoryFlowImporter, andStoryFlowWebSocketSync.sync_completenow carries it as a seconderror_countargument, so anything connected to that signal needs its callback updated to take two arguments - Truncated import metadata breaking project auto-discovery:
storyflow_import_meta.jsonwas rewritten in place, so a sync interrupted mid-write left a truncated file behind and the project failed to load on the next launch. The metadata is now staged in a sibling temp file and renamed over the target, so a write that cannot complete leaves the previously published metadata intact - Runaway copy when the output directory sits inside the build directory: the sync descended into its own output and filled the disk instead of failing (observed 300 levels deep and still going after 19 seconds). An overlapping copy step is now refused, logged and counted like any other failure, and everything beside the nested directory is still copied
- Phantom empty script in every project:
storyflow_import_meta.jsonwas picked up by script discovery and imported as an empty script. It is now skipped
New Features
- Dialogue tag events: a dialogue node tagged in StoryFlow editor 1.6.0 or newer now emits
dialogue_tag_reached(tag)onStoryFlowComponent, once per tag, in authored order, immediately afterdialogue_updated, matching the editor’s On Dialogue Tag Reached semantics. The current line’s tags are also exposed astagsonStoryFlowDialogueState. Tags fire only on a fresh entry into the node: re-rendering the same line (a Set node returning, a resume, a variable-change refresh) never re-fires them, while revisiting the node later does. Tag strings pass through untouched, and a handler may advance, select, stop or restart the dialogue while tags are still firing. Untagged nodes and older.sfefiles without the field behave exactly as before
Improvements
- First sync after upgrading cleans up the output directory: older plugin versions left a duplicate copy of every media file at its build-relative path and a verbatim
project.storyflowin the output directory. Both are removed on the first sync or import after the upgrade. The runtime resolves media from theimages/,audio/andmedia/copies and the project from the publishedproject.json, so the surviving files are the ones the runtime and exports load. A removed duplicate takes its orphaned.importsidecar with it and its directory is dropped when that leaves it empty, and the output directory itself is never removed. Files the current sync published are never cleaned up, including paths that differ from a build-side path only in case - Sync only rewrites what changed: every sync used to rewrite the whole build directory unconditionally, so Godot re-imported every copied file, including a full parse of the copied project file, even when nothing had changed. Copies now compare content (size first, then MD5) and skip the write when the destination already matches, and each media file is written once per sync instead of twice. Anything unreadable or missing is copied, so doubt always resolves toward copying
Godot Plugin v1.2.1
Typed Map Get/Set API & Flexible Dialogue UI Roots
Adds typed get and set methods for map variables on StoryFlowComponent so game scripts read and write maps as typed Dictionaries, and lets the dialogue UI scene be rooted on any node type instead of only Control for worldspace dialogue.
What's New
New Features
- Typed map get/set API: read and write map variables from GDScript as typed
Dictionaryvalues. Eight typed getters cover the supported key and value combinations:get_string_to_bool_map,get_string_to_int_map,get_string_to_float_map,get_string_to_string_mapand the integer-keyget_int_to_bool_map,get_int_to_int_map,get_int_to_float_map,get_int_to_string_map, each returning aDictionary. Thestring_to_*getters read both string-keyed and enum-keyed maps, and the*_to_string_mapgetters resolve string and enum values through the string table while returning image, audio and character values as raw asset keys. Iterate a returned map in insertion order withDictionary.keys() - Typed map setters:
set_string_to_bool_map,set_string_to_int_map,set_string_to_float_map,set_string_to_string_mapand the matchingset_int_to_*_mapmethods write a wholeDictionaryinto a map variable. Writes emitvariable_changedand live-refresh the active dialogue. A missing variable or a key or value type mismatch logs a warning and is a no-op. Every accessor takes an optionalis_globalflag to target global variables - Flexible dialogue UI roots: the built-in dialogue UI scene can now be rooted on any node type rather than only
Control, so dialogue can be hosted under aNode3Dor other non-Controlparent for worldspace and in-scene presentation
Godot Plugin v1.2.0
Map Variables, Modulo Nodes & Array Setter APIs
Adds full map variable support with eleven new node types, save persistence and a get_map_variable API, new modulo arithmetic nodes, typed array setter APIs for game code and fixes for Set node value outputs, array character variables, enum conversions and setArrayElement.
What's New
New Features
- Map variable support: script and global variables can now be maps, stored as Godot Dictionaries with key and value type metadata. All eleven map node types are implemented:
getMap,setMap,getMapValue,setMapValue,hasMapKey,mapSize,mapKeys,mapValues,removeMapKey,clearMapandforEachMap setMapaliases the target variable to the source map’s storage like the HTML runtime, so a laterclearMaporsetMapValueon one variable is observed through the other. Assigning from read-only sources such asrunScriptoutputs snapshots the entries into a fresh map insteadforEachMapiterates map entries with Key and Value outputs usable by connected nodes on each iteration, integrated with the existing loop stack and continuation rules- Map variables persist in save data, keeping their key and value type metadata and entry order. Saves from versions without map support load with sensible defaults
- Maps flow through
runScriptmap parameter and output ports, so sub-scripts can receive maps from and return maps to the calling script - Added
get_map_variable(variable_name)onStoryFlowComponent, which reads a script or global map variable from game code and returns it as a Dictionary - Modulo nodes: added the integer
moduloand floatmoduloFloatarithmetic nodes. Both return 0 when the divisor is 0, matching the divide nodes - Typed array setter APIs on
StoryFlowComponent:set_bool_array_variable,set_int_array_variable,set_float_array_variable,set_string_array_variable,set_enum_array_variable,set_image_array_variable,set_audio_array_variableandset_character_array_variablelet game code write array variables by display name, mirroring the Unity and Unreal plugins. Writes notify listeners and live-refresh any active dialogue, like every variable change
Improvements
- Execution traces now match the HTML runtime more closely: variable reads emit a
VAR GETline on every data pull and evaluation lines use the editor’s node type names, making cross-runtime debugging output directly comparable
Bug Fixes
- Fixed Set nodes used as value sources returning type defaults instead of the variable’s value.
setBool,setInt,setFloat,setString,setEnum,setImage,setAudio,setCharacterandsetCharacterVarnow expose their value on output ports exactly like their Get counterparts,setCharacterVaralso works as an array source andsetBackgroundImageas an image source - Fixed
setCharacterVardestroying array-typed character variables on write. The handler had no array branch, so it coerced the input to a scalar and overwrote the array on first write - Fixed input edge matching where a scalar handle could swallow its array sibling on nodes carrying both inputs, causing
arrayContainsandfindInneedles and array element indexes to resolve against the wrong edge and return defaults - Fixed
intToEnumandstringToEnumconversions always evaluating to empty strings. Enum value lists were dropped on import and the conversion nodes were unreachable from the evaluator chain. Enum values are now also resolved from the downstream node when the editor exports conversion nodes without data, matching the HTML runtime - Fixed
setArrayElementreading its inline index and value from the wrong data fields - Fixed whole-number inline values on float nodes evaluating to 0. Editor JSON carries no type hint on inline values, so whole numbers imported as integers and were rejected by float inputs
Godot Plugin v1.1.1
Character APIs, Array Variables & Forward-Compat Warnings
Adds new public GDScript APIs for reading character portraits, custom variables and character arrays from game code, resolves string variables through the string table, and warns instead of silently skipping unsupported node types from newer editor versions.
What's New
New Features
- Character read APIs on
StoryFlowComponent—get_character(character_path)returns the liveStoryFlowCharacterobject,get_character_variables(character_path)lists the names of a character’s custom variables, andget_character_portrait(character_path, asset_key = "")resolves a portrait to aTexture2Dwalking the character → script → project asset pools. Useful for rendering multi-character UIs without reaching into private manager state - Added
get_character_array_variable(variable_name)— reads a script or global variable whose element type is character and returns the array of character paths, each usable with the other character APIs above - Added
get_array_variable(variable_name)— generic reader for any array variable, returningArray[StoryFlowVariant]with string and enum elements resolved through the string table - Added
character_variable_changed(character_path, variable_name, value)signal — emitted when asetCharacterVarnode mutates a character’sName,Imageor custom variable, so non-speaker UIs can react to off-screen character updates get_character_variablenow handles the built-in"Image"field symmetrically with"Name", returning the character’s current portrait asset key
Improvements
get_string_variablenow routes its result through the string table, so callers receive localized text rather than raw string keys — matches the Unity plugin’s behavior- Unsupported node types from newer editor versions now emit a
push_warningand fall through to the default output instead of being silently skipped, so scripts authored against a newer plugin keep flowing on older runtimes. Warnings also fire from boolean, integer, float, string, enum and array evaluator chains, deduplicated per dialogue run via the execution context
Godot Plugin v1.1.0
Data-Only Sync, Portrait UI & Execution Fixes
Adds support for data-only WebSocket sync (skip asset copying for fast iteration), a new Portrait dialogue UI with detached character image, and fixes for media loading, RunScript evaluation, array operations, and variable access outside dialogue.
What's New
New Features
- Data-only sync support — when the StoryFlow Editor syncs with “Data Only” enabled, the plugin reuses previously imported assets from the output directory instead of requiring source files in the build directory, enabling fast script-only iteration without re-copying images and audio
- Added
StoryFlowDialogueUIPortraitscene — alternative dialogue UI with the character portrait rendered as a large image anchored to bottom center of the screen, separate from the dialogue panel. Portrait scales responsively with viewport height. Assign todialogue_ui_sceneon StoryFlowComponent to use it - Portrait height ratio and bottom offset are exposed as
@exportproperties for easy customization
Bug Fixes
- Fixed image import failing for files with mismatched extensions (e.g. PNG data saved as .jpg) — importer now detects actual format from file header magic bytes
- Fixed media assets (images, audio) not loading correctly during WebSocket sync when file paths contained subdirectories
- Fixed background image not persisting across dialogue nodes as expected
- Fixed
PlayAudionot resolving audio assets from resolved asset sources - Fixed
RunScriptoutput nodes not evaluating return values back to the calling script - Fixed array
Push,Pop,RemoveAt, andInsertoperations not correctly modifying the source array - Fixed script parameter passing not propagating values through
RunScriptnode connections - Fixed variable access (
get_variable,set_variable) failing when called outside of active dialogue — global variables now fall back to the manager’s runtime state - Fixed character variable lookup failing due to variables being keyed by internal ID instead of display name
Godot Plugin v1.0.3
Inline Values, Character Variables & Editor Settings
Fixes comparison and arithmetic nodes ignoring inline values, character variable lookup failures, forEach loop issues, and editor dock settings not persisting.
What's New
Bug Fixes
- Fixed inline values on comparison and arithmetic nodes being ignored — nodes like
>=,>,+, etc. silently read their inline values as 0 instead of the configured number, causing incorrect evaluation results (e.g.0 >= 15becoming0 >= 0) - Fixed character variable nodes (
getCharacterVar) always returning empty values — the importer was keying variables by their internal ID instead of their human-readable name, causing lookup mismatches at runtime - Fixed
getCharacterVarnodes not working as array sources forforEachloops - Fixed
forEachloop context not persisting across iterations, causing variable state to reset each loop - Fixed boolean evaluation caches not clearing between
forEachiterations, leading to stale condition results - Fixed character string keys not resolving through the global strings table
- Fixed editor dock settings (port, output directory, build directory) resetting to defaults on Godot editor reload — settings are now persisted via ConfigFile
- Fixed sync output directory not updating from the current field value on each sync
Godot Plugin v1.0.2
Script Selector & Text Block Fixes
Adds a dropdown script selector to the StoryFlowComponent inspector and fixes text blocks not appearing in dialogue.
What's New
New Features
- Script Path Dropdown: The script_path property in the StoryFlowComponent inspector now shows a dropdown listing all imported scripts, replacing the plain text field — script paths are cached during import and WebSocket sync
Bug Fixes
- Fixed text blocks in dialogue nodes not appearing — visibility conditions were not being evaluated, and the built-in dialogue UI was not rendering text blocks at all
Godot Plugin v1.0.1
String Variables & Media Loading Fixes
Fixes string variable interpolation, node input matching, and media assets failing to load at runtime.
What's New
Bug Fixes
- Fixed string variables displaying raw localization keys instead of actual text in dialogue
- Fixed connected node inputs (e.g. SET receiving value from RANDOM) not being found due to handle suffix mismatch
- Fixed audio and image assets not loading at runtime when reimporting from the same directory
Godot Plugin v1.0.0
Initial Release
The first official release of the StoryFlow plugin for Godot 4, bringing full dialogue runtime support to Godot projects.
What's New
New Features
- Full Runtime Engine: Complete GDScript execution engine with full node type coverage
- StoryFlow Component: Node for running dialogues with typed signals
- StoryFlow Runtime: Autoload singleton for shared state management
- Variable System: Boolean, integer, float, string, enum, image, audio, and character types
- Array Operations: Full array support with ForEach loops across all variable types
- Text Interpolation: Live variable interpolation with
{varname}and{Character.Name}syntax - Script Execution: RunScript (call/return with parameters) and RunFlow (jump with exit flows)
- Character System: GetCharacterVar/SetCharacterVar with built-in Name and Image fields
- Audio Playback: Loop, reset, advance-on-end, and allow-skip support
- Background Images: Dynamic background image support with persistence and reset
- Save & Load: Slot-based persistence for global variables, characters, and once-only options
- Built-in Dialogue UI: Default dialogue UI scene with auto-fallback
- Editor Dock: StoryFlow dock panel with Live Sync and Import sections
- JSON Importer: Import StoryFlow Editor projects preserving build directory structure
- Live Sync: WebSocket client for real-time sync with StoryFlow Editor
- Toolbar Button: StoryFlow logo button with Connect/Sync toggle
Unreal Engine Plugin