UE5 Plugin Changelog
New updates and improvements to the StoryFlow plugin for Unreal Engine.
UE5 Plugin v1.2.2
Sync Crash Fixes, Revision Control Support & Dialogue Tags
Fixes an editor crash when a synced asset cannot be saved, dialogues silently missing from packaged builds and plugin downloads that would not extract on Linux or macOS. Sync now checks assets out of revision control and rewrites only what changed, dialogue nodes raise tag events and the auto-created dialogue widget can be handed to your own UI.
What's New
Bug Fixes
- Editor crash when a synced asset cannot be saved: a single
.uassetthat could not be written (checked into revision control and still read-only, or with its permissions stripped) took down the whole editor on every sync, reported from Linux as a crash insideUPackage::SavewithError saving '.../Characters/characters_leonardo.uasset'. The plugin was leaving the engine’s default save error device in place, and that device raises on any failure before the plugin’s own error handling could run. A failed save is now reported by name and skipped while the rest of the import continues, and the log names the actual remedy: a read-only target asks you to clear the read-only flag or check the file out of revision control, anything else points at file permissions and free disk space - Dialogues missing from packaged builds: script assets took their package path straight from your StoryFlow file and folder names, so any name containing a character Unreal does not allow in package names (a space, an apostrophe, a dot) produced assets the loader and cooker can never resolve. The editor and Play In Editor kept working from the in-memory packages while every dialogue silently dropped out of the packaged game, sync logged
Ensure condition failed: ConvertedToPath, and a name containing a dot could hard-crash the editor in the asset registry during import. Script names and each subfolder segment are now sanitized, with a stable suffix so distinct sources cannot collide (act 1stays separate fromact_1), and a warning names the offending script and the path it imported as. Names that are already valid pass through unchanged, so a clean project gets no duplicate assets on re-import, and runtime lookups still key off the raw relative path. If a project already synced under a broken name, delete the assets it produced (theContent/StoryFlowfolder in a default setup) and sync again: the fix creates the correct assets but does not remove the old unusable ones - Downloads that would not extract on Linux or macOS: the release archives were built with a tool that writes Windows path separators inside zip entries. Windows extractors tolerate that, but Linux and Mac extractors treat the backslash as part of the file name, so the archive unpacked into a garbage tree and Unreal reported
Failed to open descriptor file '...StoryFlowPlugin\StoryFlowPlugin.uplugin'. Archives are now written with spec-compliant forward slashes, every engine package is checked for stray separators and for the descriptor at its expected path before it is uploaded, and a release step then extracts a published zip on real Linux to confirm it lands where Unreal looks for it - 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 at runtime even though the editor preview was correct. The import read only the variables and strings from
global-variables.jsonand never its assets section, so the asset key was never registered in the project’s resolved asset pool, which is the runtime’s final fallback for images and audio. Custom image and audio character variables and character map values had the same gap incharacters.json, where only the single portrait was imported. Both files’ asset sections are now imported into that pool, which is also what makes global and character audio resolve runScriptmap parameters arriving empty: a map wired into arunScriptnode’s map parameter reached the called script empty, while scalar parameters, array parameters and direct global map reads all worked. The importer dropped the parameter’s key and value types, so the runtime rebuilt the wrong input handle name and never matched the wired edge. Key and value types are now carried on the parameter and the handle is rebuilt the way the editor wires it
New Features
- Dialogue tag events: a dialogue node tagged in StoryFlow editor 1.6.0 or newer now raises
OnDialogueTagReached(Tag)on the component, once per tag in authored order, immediately afterOnDialogueUpdated, matching the editor’s On Dialogue Tag Reached semantics. Tags fire only when a node is entered through an edge, so returning from a Set node, resuming and live variable re-interpolation never re-fire them, while revisiting the node later does. The current line’s tags are also onFStoryFlowDialogueStateand readable at any time throughGetCurrentDialogueTags(). Untagged nodes and scripts exported by older editor versions behave exactly as before - Access to the dialogue widget:
GetDialogueWidget()returns the widget the component created fromDialogueWidgetClass, and the newOnDialogueWidgetCreated(Widget)event fires once that widget has been created, initialized and placed, beforeOnDialogueStarted, so you can parent it before the first content event arrives. The getter is valid from that event until dialogue end, and every dialogue creates a fresh widget, so ask again rather than caching one across dialogues bAutoAddWidgetToViewport: a new component setting that decides who places the dialogue widget. It defaults totrue, which is exactly the previous behavior: the component adds the widget to the viewport when dialogue starts and removes it when dialogue ends. Turn it off and the component only creates and initializes the widget before handing it over, so it can live in your HUD, a widget stack or a 3D widget component, withOnDialogueEndedas your cue to tear it down. Two things to know in that mode: the component’s reference is the only one it keeps, so a widget it lets go of is garbage collected unless you parented it or hold your own reference, and a dialogue that restarts while an earlier widget still exists broadcasts noOnDialogueEnded, so the cue there isOnDialogueWidgetCreatedarriving with a different widgetDetachFromComponenton the dialogue widget: unsubscribes a widget from its component’s events and forgets the component. With the game owning placement, the component calls it on every widget it lets go of, so a widget in the middle of a fade out is not driven by the next dialogue: without it that widget would still receive the nextOnDialogueStarted, replay its show animation and repaint itself with the new lines. After detaching,GetStoryFlowComponentreturns null and the widget helpers routed through it (SelectOption,AdvanceDialogue,GetCurrentDialogueState) do nothing, so a fade out that still talks to the component needs your own reference. CallInitializeWithComponentagain to reattach
Improvements
- Sync only rewrites what changed: every sync used to rewrite every script, character and project asset even when nothing had changed, so one unwritable file anywhere failed the whole sync. Each asset now records a hash of the source it was imported from and skips the disk write when that source is unchanged and the asset file is still on disk. A steady state sync writes nothing at all and a real story edit writes only the assets it touched. The hash is recorded only after a successful save, so a save that failed (or was deferred because you were in Play In Editor) retries on the next sync
- Synced assets are checked out of revision control: sync wrote packages directly, so in a Perforce workspace every checked-in StoryFlow asset failed to save on every sync, because those files stay read-only until they are checked out. The importer now checks a tracked file out before overwriting it and marks newly created files for add, so a sync lands in your pending changelist as exactly the assets the story edit touched, ready to review and submit. A file it cannot check out (exclusively checked out by a teammate, for example) is reported by name with the reason while the rest of the import continues, and a newly written file that revision control already tracks warns that your workspace is out of date. Projects with no provider enabled are unaffected: every one of these calls is a success no-op
- First sync after upgrading rewrites every asset once: assets imported by earlier versions carry no import hash, so the first sync after installing 1.2.2 rewrites every script, character and project asset once. Under revision control that first sync checks out the whole StoryFlow folder, which is expected. Every sync after it touches only what actually changed
UE5 Plugin v1.2.1
Typed Map & Array Blueprint APIs, UE 5.8 Support
Adds Blueprint typed get and set functions for map variables and typed getters for array variables, so game code reads and writes maps and arrays without unpacking FStoryFlowVariant. Also adds Unreal Engine 5.8 support.
What's New
New Features
- Typed map get/set API: read and write map variables from Blueprint or C++ as a native
TMapwithout touchingFStoryFlowVariant. Eight typed getters cover the supported key and value combinations:GetStringToBoolMap,GetStringToIntMap,GetStringToFloatMap,GetStringToStringMapand the integer-keyGetIntToBoolMap,GetIntToIntMap,GetIntToFloatMap,GetIntToStringMap, each returning a populatedTMap. TheStringTo*getters accept both string-keyed and enum-keyed maps.*ToStringMapreturns the string-family value types, resolving string and enum values through the string table for localized text and returning image, audio and character values as raw asset keys - Typed map setters:
SetStringToBoolMap,SetStringToIntMap,SetStringToFloatMap,SetStringToStringMapand the matchingSetIntTo*Mapfunctions write a wholeTMapinto a map variable. Writes fireOnVariableChangedand live-refresh the active dialogue. A type mismatch logs a warning and leaves the variable untouched GetMapKeysInOrder: returns a map variable’s keys as aTArray<FString>in the order the editor serialized them. BecauseTMapis unordered, this is the way to iterate a map’s entries deterministically. Integer keys are returned stringified- Typed array getters:
GetBoolArrayVariable,GetIntArrayVariable,GetFloatArrayVariable,GetStringArrayVariable,GetEnumArrayVariable,GetImageArrayVariableandGetAudioArrayVariableunpack an array variable into a plain Blueprint array of the matching type, so reading array values no longer means unwrapping eachFStoryFlowVariantby hand. String and enum elements resolve through the string table while image and audio elements stay raw - Unreal Engine 5.8 support: the plugin now builds against UE 5.8 and ships a 5.8 package, covering Unreal Engine 5.3 through 5.8
UE5 Plugin v1.2.0
Map Variables, Modulo Nodes & Array Write APIs
Adds full runtime support for the editor's map variable type including forEachMap loops, runScript map parameters and save game persistence. Also adds modulo and moduloFloat nodes, Blueprint array variable setters, a GetMapVariable accessor and a batch of evaluator fixes covering loops, arrays, float reads and enum conversions.
What's New
New Features
- Map variables: full runtime support for the editor’s map variable type.
getMap,setMap,getMapValue,setMapValue,hasMapKey,mapSize,mapKeys,mapValues,removeMapKeyandclearMapare all handled, with entry order preserved exactly as the editor serializes it so key and value listings iterate like the HTML runtime forEachMaploops: iterate a map with the current entry snapshotted per iteration and both the key and the value exposed as loop outputs for the bodysetMapaliases live map storage like the HTML runtime, so after assigning one map variable to another both observe the same mutations; asset to runtime copy boundaries detach the storage so script data is never modifiedrunScriptinput parameters and output returns now carry map values across script boundaries- Added
GetMapVariableonUStoryFlowComponent, returning a map variable as parallelKeysandValuesarrays ofFStoryFlowVariantwith string and enum values resolved through the string table for localized text while keys stay raw identifiers - Added the typed
Set*ArrayVariableBlueprint functions (SetBoolArrayVariable,SetIntArrayVariable,SetFloatArrayVariable,SetStringArrayVariable,SetEnumArrayVariable,SetImageArrayVariable,SetAudioArrayVariableandSetCharacterArrayVariable) so game code can write array variables, mirroring the Unity plugin’s API; writes fireOnVariableChangedand live-refresh the active dialogue like the scalar setters - Added
moduloandmoduloFloatmath nodes - Map variables persist through save games and map string values resolve through the strings table like scalar strings
Bug Fixes
- Fixed bool array elements reading
falseinside their ownforEachloop body (e.g. wired into a branch condition) caused by the boolean chain processor wiping the loop’s live element cache and replacing it with a stale default - Fixed
ResetVariablesleaving raw string-table keys (likevar_3_value) in string variables instead of localized text - Fixed
setArrayElementnodes reading their inline index and value from the wrong exported data fields, which broke set-element operations without wired inputs - Fixed float reads returning the default for whole-number inline values, so a value of
2now reads as2.0instead of0 - Fixed
IntToEnumandStringToEnumconversions always evaluating to an empty string; enum value lists are now kept on import and resolved from the downstream node like the HTML runtime - Fixed Set* nodes returning the type default instead of the variable they set when used as a value source for downstream nodes
- Fixed
setCharacterVardestroying array character variables on first write; array writes now evaluate the wired array input instead of coercing the array to a scalar - Fixed input handle matching where a scalar suffix could swallow its array sibling, breaking
arrayContainsandfindInneedles andgetArrayElementindexes - Fixed
setArrayElementandaddTo*nodes never resolving wired image, audio and character values due to handle names not matching the editor’s exported numbered handles
Improvements
- Execution trace output now matches the shapes emitted by the other runtimes for cross-runtime comparison, and a map trace fixture package was added under
TestContent - Added the plugin’s first automation test suites:
StoryFlow.EnumConversions(6 tests) andStoryFlow.ArrayVariables(5 tests) drive the real component, subsystem and globals path through a standalone GameInstance
UE5 Plugin v1.1.1
Character Runtime APIs, Array Reads & Localized Strings
Adds Blueprint APIs for reading character arrays, resolving portraits and reacting to live character variable mutations, plus a generic GetArrayVariable. GetStringVariable now returns localized text, and unsupported node types now log a clear warning instead of silently returning defaults.
What's New
New Features
- Character runtime APIs —
GetCharacter,GetCharacterArrayVariable,GetCharacterVariableNamesandGetCharacterPortraitare now exposed onUStoryFlowComponentso game code can drive multi-character UIs without reaching into private runtime state OnCharacterVariableChangeddelegate — Blueprint-assignable multicast that fires after asetCharacterVarnode mutatesName,Imageor a custom variable, with(CharacterPath, VariableName, Value)parameters; lets non-speaker portraits and HUDs react to live mutations- Added
GetArrayVariableonUStoryFlowComponent— returns any array variable asTArray<FStoryFlowVariant>with string and enum elements routed through the string table for localized text; image, audio and character elements pass through as raw keys GetCharacterPortrait(CharacterPath, AssetKey)walks the standard character → script → project asset pools and falls back to the cached cross-script texture, mirroring the resolution path used byBuildDialogueState; pass an emptyAssetKeyto use the character’s currentImagefield (which reflects runtimesetCharacterVar("Image", ...)changes)
Bug Fixes
- Fixed
FStoryFlowVariable,FStoryFlowNode,FStoryFlowDialogueStateand related struct fields not appearing in the Details panel for Blueprint variable instances — fields are now markedVisibleAnywhereso authored values and runtime state can be inspected in-editor
Improvements
GetStringVariablenow resolves the stored value through the string table before returning, matching the Unity plugin and giving Blueprint callers localized text instead of raw string keys — callers that relied on the raw key will need to look it up directly on the variant- Evaluator chains (
EvaluateBooleanFromNode,EvaluateIntegerFromNode,EvaluateFloatFromNode,EvaluateStringFromNodeand the shared array evaluator) now log a one-shot warning per node when they encounter a source node of an unsupported type instead of silently returning the type’s default value — surfaces scripts that use node types from a newer editor version - The
ProcessNode“unhandled node type” warning now reports the node id alongside the type string for easier diagnosis
UE5 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 widget with detached character image, UI-optimized texture import settings, and fixes for media variable evaluation, RunScript parameter passing, and array operations.
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 Unreal project instead of requiring source files in the build directory, enabling fast script-only iteration without re-copying images and audio
- Added
WBP_Dialogue_Portraitexample widget with the character portrait displayed as a large image anchored to bottom center of the screen, separate from the dialogue panel - Imported textures are now automatically configured for UI usage:
UserInterface2Dcompression, no mipmaps, UI texture group, and sRGB enabled — prevents blurry images in UMG widgets
Bug Fixes
- Fixed
PlayAudionot resolving audio assets from character or project resolved assets - Fixed
SetBackgroundImagenot resolving image assets through evaluation chains - Fixed
SetCharacterVarwith Image type not evaluating connected node chains for the value - Fixed character images not resolving when referenced across script boundaries (e.g. via
RunScript) - Fixed media variable evaluation (
GetImage,GetAudio) not checking all asset resolution sources - Fixed
RunScriptoutput parameters not passing return values back to the calling script - Fixed array
Push,Pop,RemoveAt, andInsertoperations not correctly modifying the source array - Fixed execution tracing for cross-runtime debugging
Improvements
- Added execution trace logging (
[SF-TRACE]prefix) for node processing, edge traversal, variable changes, and script calls — matches the trace format used by the Godot and Unity plugins for cross-runtime comparison
UE5 Plugin v1.0.7
Blueprint Variable Access & forEach Loop Fixes
Fixes variable access from Blueprint outside of active dialogue, adds typed character variable functions with asset picker support, and resolves forEach loop issues with character variable arrays and boolean cache staleness.
What's New
New Features
- Added typed character variable Blueprint functions (
GetCharacterBoolVariable,SetCharacterBoolVariable,GetCharacterIntVariable, etc.) that accept aUStoryFlowCharacterAssetreference instead of a string path — enables native Unreal asset picker in Blueprint for selecting characters - Character Name field now properly resolves through the string table, returning the localized display name instead of the raw string key
Bug Fixes
- Fixed all variable getter/setter Blueprint functions (
GetBoolVariable,SetBoolVariable,GetIntVariable, etc.) failing with “Variable not found” warning when called outside of active dialogue (e.g., from BeginPlay) — global variables now fall back to the subsystem’s runtime state when the execution context isn’t initialized - Fixed character variable access (
GetCharacterVariable,SetCharacterVariable) also failing outside of active dialogue — same subsystem fallback applied - Fixed
GetLocalizedStringnot resolving string keys when called outside of active dialogue - Fixed character variables being keyed by internal ID instead of display name in the importer, causing runtime lookups by name to fail
- Fixed
GetCharacterVarnodes not working as array sources forforEachloops - Fixed
forEachloops not clearing boolean evaluation caches between iterations, causing stale results from previous iterations to carry over - Fixed
forEachloop context being pushed once at initialization instead of per-iteration, which broke nested loop tracking and the loop index - Fixed defensive
NodeIdchecks on loop stack pop operations to prevent popping the wrong loop context in nested forEach scenarios - Fixed
ProcessBooleanChaindefault case not clearing cached output before re-evaluation, causing stale boolean values when the same node was evaluated multiple times
Improvements
- Legacy character variable functions (
GetCharacterVariable,SetCharacterVariable) moved to “Character (Legacy)” Blueprint category — still functional but new typed versions are recommended - Updated example
WBP_Dialoguewidget to auto-advance dialogue after a short delay for narrative-only nodes
UE5 Plugin v1.0.6
Text Block Visibility Conditions
Fixes text block conditions not being evaluated, so conditional text blocks now correctly show or hide based on their visibility rules.
What's New
Bug Fixes
- Fixed text blocks in dialogue nodes ignoring their visibility conditions — text blocks with conditions were always shown regardless of whether their condition evaluated to true or false; they now use the same visibility evaluation as dialogue options
UE5 Plugin v1.0.5
Node Input Matching Fix
Fixes connected node inputs failing to evaluate due to handle suffix mismatch with the editor's export format.
What's New
Bug Fixes
- Fixed connected node inputs not being found when evaluating data edges (e.g. a SET node receiving a value from a RANDOM or GET node) - the editor exports handles with numbered suffixes that the runtime now matches via prefix fallback
UE5 Plugin v1.0.4
3D Audio, Audio Advance & Character Evaluators
Adds optional 3D spatial audio, auto-advance when dialogue audio finishes, overridable audio functions, and GetCharacterVar support in all evaluator types.
What's New
New Features
- 3D Audio Support: Optional bUse3DAudio toggle that switches dialogue audio from 2D to attached 3D sound on the owning actor, with DialogueAttenuation property for controlling falloff
- Overridable Audio Functions: PlayDialogueAudio and StopDialogueAudio are now BlueprintNativeEvent for custom audio system overrides
- Audio Advance-on-End: Dialogue nodes with audioAdvanceOnEnd auto-advance when audio finishes playing, with audioAllowSkip to let players skip early
- GetCharacterVar in Evaluators: GetCharacterVar nodes can now be evaluated in boolean, integer, float, and string contexts with dynamic character input resolution
UE5 Plugin v1.0.3
Multi-Version Build Support & Stability
Adds support for building the plugin across multiple Unreal Engine versions, improves API documentation, and includes stability fixes.
What's New
Improvements
- Multi-Version Build System: New build script for compiling the plugin against UE 5.3, 5.4, 5.5, 5.6, and 5.7 in a single run
- Improved API Documentation: Updated variable API comments and type annotations to reflect the name-based lookup introduced in v1.0.2
Bug Fixes
- Fixed Build Script: Resolved issues with the automated build pipeline that could cause packaging failures on certain configurations
- Fixed Variable Lookup Edge Case: Corrected a rare issue where stale variable name indices could return incorrect values after rapid script switching
UE5 Plugin v1.0.2
Name-Based Variable API
Public Blueprint variable functions now use display names instead of internal UUIDs for a cleaner developer experience.
What's New
Improvements
- Name-Based Variable API: Get/Set variable functions on StoryFlowComponent, ProjectAsset, and ScriptAsset now accept variable display names instead of internal UUIDs, with O(1) name-to-ID index lookup
UE5 Plugin v1.0.1
Live Sync Stability & Variable Change Event
Fixes a critical live sync crash and improves the OnVariableChanged delegate for Blueprint users.
What's New
Improvements
- OnVariableChanged Delegate: Now passes the full FStoryFlowVariable struct instead of raw VariableId and FStoryFlowVariant, giving Blueprint users Variable.Name, Variable.Type, and Variable.Value from a single output pin
Bug Fixes
- Fixed Live Sync Crash: Assets are now updated in-place instead of deleted and recreated during sync, preventing UObjectArray refcount assertion crashes
- Fixed Concurrent Import: Added import guard to prevent overlapping imports from rapid WebSocket messages
UE5 Plugin v1.0.0
Initial Release
The first official release of the StoryFlow plugin for Unreal Engine 5, bringing full dialogue runtime support to UE5 projects.
What's New
New Features
- Full Runtime Engine: Complete execution engine with full node type coverage and O(1) edge lookups
- StoryFlow Component: Actor component for running dialogues with full Blueprint and C++ API
- 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 - RunScript Interface: Parameter passing, output extraction, and exit route routing for called scripts
- Random Branch Node: Weighted random path selection with dynamic integer weight evaluation
- Character System: Per-asset character DataAssets with GetCharacterVar/SetCharacterVar and built-in Name/Image fields
- Audio Playback: Dialogue audio with SoundClass, volume controls, loop, reset, and MP3-to-WAV auto-conversion
- Save & Load: Slot-based persistence for global variables, runtime characters, and once-only option tracking
- Click-to-Advance: AdvanceDialogue() for narrative dialogue nodes with no options
- Built-in Dialogue UI: Default widget with auto-fallback when no custom UI is assigned
- JSON Importer: Import preserving folder structure with Textures/Audio/Data asset organization
- Live Sync: WebSocket client with PIE-safe sync guard to prevent asset replacement crashes
- Toolbar Integration: StoryFlow toolbar in Blueprint, Widget, Animation BP, and Behavior Tree editors
- Localization: String variable values and inline strings resolved through string tables at runtime
Unreal Engine Plugin