Yarn Spinner for Unreal is in Pre-release now.
Yarn Spinner for Unreal Engine is a pure-C++ implementation of the Yarn Spinner dialogue system for Unreal Engine. It runs compiled Yarn programs with the goal of full feature parity with Yarn Spinner for Unity, including node groups, saliency, detours, smart variables, localisation, markup, and voice over support.
The entire plugin is intended to be Blueprint-accessible. You can set up dialogue, handle commands, read/write variables, save/load state, swap projects at runtime, and build custom presenters entirely from Blueprints with no C++ required.
A sample project will be coming soon, during the pre-release period!
Requires Unreal Engine 5.4 or later. If you want to use Yarn Spinner for Unreal Engine with an earlier version of Unreal Engine, please contact us via https://yarnspinner.dev
Yarn Spinner for Unreal Engine is not yet for sale (it will always be available here for free, too). We rely on your support to keep everything free and accessible. If you want to support us during the Alpha period, you can support us on or . GitHub sponsors of $25 and above, and Patreon members of the "Scribe" or above tier will receive a license to the paid version when it is released.
The VM, protobuf parser, library, and markup system were all written to match Unity's behaviour, but there are some differences:
CLDR plural rules -- Unity includes the full Unicode CLDR v42.0 database (~150 languages). This implementation has rules covering ~130 languages. Coverage is comprehensive, but if you're using [plural] or [ordinal] markup tags with a some languages, you might get the default "one/other" fallback instead of the correct plural form.
No Unicode NFC normalisation -- Unity normalises markup input text to NFC (composed) form before parsing. Unreal doesn't have a built-in NFC normaliser, so precomposed and decomposed Unicode characters are treated as-is. This only matters if your Yarn scripts contain combining characters like e + \u0301 instead of é.
Async model -- Unity uses C# async/await with YarnTask and CancellationTokenSource chains. This implementation uses Unreal delegates and a two-tier UYarnCancellationToken system (hurry-up then next-content). The behaviour is the same, but the presenter API uses UE-idiomatic patterns instead of tasks.
Command discovery -- Unity uses [YarnCommand] attributes on methods. This implementation uses Blueprint-callable UFUNCTION methods on registered command handler objects, plus a C++ AddCommandHandler API. Both approaches register commands, just with diffeent syntax.
Error handling -- Unity throws exceptions for invalid states (missing variables, bad option indices, etc.). This implementation uses UE_LOG warnings/errors and defensive fallbacks where possible, which is more idiomatic for Unreal Engine.
Localisation -- Unity has multiple line provider backends (built-in, Unity Localization package, Addressables). This implementation uses Unreal's FText and string table system. You can subclass the line provider to plug in your own localisation pipeline.
Blueprint support -- This implementation exposes the full dialogue system to Blueprints. Every component is Blueprintable, every control method is BlueprintCallable, all events are BlueprintAssignable, and presenter methods are BlueprintNativeEvent. A UYarnBlueprintLibrary provides 30+ static utility functions. See Blueprint Support for details.
Persistence -- Unity has SaveStateToPersistentStorage/LoadStateFromPersistentStorage. This implementation provides SaveVariablesToSlot/LoadVariablesFromSlot via UYarnBlueprintLibrary, using Unreal's native USaveGame system.
This project uses the Yarn Spinner Public License. You're free to use it in your own projects, commercial or otherwise. The only restrictions are around redistributing it as part of a competing dialogue tool, and using it to train AI models. Full details are in LICENSE.md.
Copy the YarnSpinner/ folder from this repository into your Unreal project's Plugins/ directory (so that YarnSpinner.uplugin is at Plugins/YarnSpinner/YarnSpinner.uplugin).
Open your project in the Unreal Editor -- the plugin will be detected automatically.
Install ysc
A game can have multiple .yarnproject files, each with its own sourceFiles scope -- useful for separating story dialogue, NPC barks, tutorials, etc. Each one compiles independently into its own UYarnProject asset.
The Yarn Spinner compiler (ysc) compiles a .yarnproject and all .yarn files in its sourceFiles scope into a single binary (.yarnc), a string table CSV, and a metadata CSV. The editor plugin runs ysc automatically at import time via a custom UFactory, parses the outputs into an in-memory program representation (UYarnProgram), and cleans up the temp files. At runtime, a stack-based virtual machine executes the program. The VM handles control flow, variable storage, function calls, saliency selection, and content delivery. A dialogue runner component orchestrates the VM and routes lines, options, and commands to presenter components in your scene.
Compilation is always the full set of source files as defined by the project -- there's no incremental or per-file compilation. The editor plugin watches your .yarn source files on disk and automatically reimports the associated UYarnProject asset when any change is detected -- edits, new files, or changes to the .yarnproject itself. Rapid saves are debounced into a single reimport. You can also reimport manually via right-click in the Content Browser.
You write dialogue in Yarn, drag in the .yarnproject, and the plugin handles compilation, file watching, and everything else.
The plugin has three layers:
Core (Source/YarnSpinner/) contains the runtime engine. The protobuf parser reads compiled .yarnproject binaries. The virtual machine (FYarnVirtualMachine) executes instructions. The built-in library provides operators and functions (arithmetic, comparisons, visited, random_range, format, etc.). Variable storage (IYarnVariableStorage) holds game state. The markup parser applies CLDR plural rules, [select]/[plural]/[ordinal] replacement markers, and the adoption agency algorithm for nested tags. The saliency system selects content when multiple candidates match. The smart variable evaluation VM resolves computed variables.
Dialogue Runner (UYarnDialogueRunner) is the main component you add to your actor. It owns the VM, registers built-in functions, discovers commands from handler objects, coordinates presenters, and exposes delegates for dialogue lifecycle events (OnDialogueStart, OnNodeStart, OnNodeComplete, OnDialogueComplete, OnUnhandledCommand). All configuration is done through its UPROPERTY fields in the Details panel. Every control method is BlueprintCallable and every event is BlueprintAssignable.
Presenters display content to the player. UYarnDialoguePresenter is the base class -- it delivers lines with typewriter animation and handles the hurry-up/next-content cancellation flow. UYarnOptionsPresenter shows dialogue choices. UYarnVoiceOverPresenter plays audio files synced to lines. UYarnWidgetPresenter manages UMG widgets for dialogue UI. All presenters are Blueprintable -- subclass them in Blueprints and override RunLine, RunOptions, and other events without writing C++.
The plugin is designed for Blueprint-first development. Every component, method, and event is accessible from Blueprints.
Dialogue control -- start, stop, pause, and resume dialogue. Check if dialogue is running. Get the current node name. Swap Yarn projects at runtime.
Command handling -- add any Blueprint to the runner's CommandHandlerObjects array. Functions matching command names are discovered and called automatically with type-converted parameters. No string parsing needed.
Variable access -- read and write Yarn variables by name. Get/set typed values (string, float, bool). List all variables. Check if a variable exists. Listen for variable changes with callbacks.
Save/load -- one-call save and load of all Yarn variables to disk via Unreal's USaveGame system. Manage save slots (check existence, delete).
Runtime project swap -- change which Yarn project a runner uses at runtime via SetYarnProject. Useful for level transitions, DLC, or modding.
Custom presenters -- subclass UYarnDialoguePresenter in Blueprints and override RunLine and RunOptions to build custom dialogue UI without any C++.
Custom option widgets -- subclass UYarnOptionWidget to customise option button appearance. Override SetupOption, SetOptionUnavailable, OnOptionSelected, OnOptionDeselected.
Event binding -- bind to OnDialogueStart, OnDialogueComplete, OnNodeStart, OnNodeComplete, OnUnhandledCommand, OnVariableChanged, OnOptionSelected, OnVoiceOverStarted, OnVoiceOverComplete.
Localisation -- change locale at runtime, query available locales, add runtime localised strings.
Project inspection -- query node names, line IDs, tags, variable declarations, and project statistics from Blueprints.
Debug overlay -- add a UYarnDebugHUDComponent for a real-time debug display showing variables, execution history, and current dialogue state. Toggle with a configurable key.
A static function library providing 30+ utility functions accessible from any Blueprint. All functions appear under Yarn Spinner in the action menu.
The central component. Add it to an actor, assign a Yarn Project asset, and call StartDialogue().
Configuration properties (all editable in Details panel):
YarnProject (BlueprintReadOnly) -- the imported Yarn project asset to run
StartNode (BlueprintReadWrite) -- which node to begin from (default: "Start")
bAutoStart (BlueprintReadWrite) -- start dialogue when the game begins
BlueprintCallable methods:
SetYarnProject -- swap to a different Yarn project at runtime
StartDialogue / StartDialogueFromStart -- begin dialogue
StopDialogue -- stop immediately
BlueprintAssignable events:
OnDialogueStart -- dialogue has begun
OnDialogueComplete -- dialogue has ended
OnNodeStart (NodeName) -- a node started executing
Base presenter class for displaying dialogue lines. Handles typewriter-style text reveal with configurable speed (letters per second), auto-advance timing, and the two-tier cancellation system (hurry-up reveals text instantly, next-content advances to the next line). Supports character name extraction and markup-processed text.
BlueprintNativeEvent methods (override in Blueprint subclasses):
RunLine (Line, bCanHurry) -- display a line of dialogue. Must call OnLinePresentationComplete when done.
RunOptions (Options) -- display dialogue choices. Must call OnOptionSelected(Index) when the player picks one.
BlueprintCallable methods:
OnLinePresentationComplete -- signal that line presentation is done
OnOptionSelected (Index) -- signal that an option was chosen
SetAutoAdvanceEnabled / IsAutoAdvanceEnabled -- auto-advance control
BlueprintReadOnly state:
bIsPresentingLine / bIsPresentingOptions -- current presentation state
CurrentLine / CurrentOptions -- current content being presented
Ready-to-use text presenter that creates and manages a UMG widget. Handles typewriter effects with configurable speed.
TypewriterSpeed (BlueprintReadWrite) -- characters per second (0 = instant)
BackgroundColor / TextColor / CharacterNameColor (BlueprintReadWrite) -- appearance
WidgetClass
Shows dialogue choices. Receives an option set from the runner, creates UI for each option, handles selection via mouse/keyboard/gamepad, and reports the selected option back.
Configuration (all BlueprintReadWrite):
OptionWidgetClass -- the option button widget class
OptionsContainer -- panel to add option widgets to
bShowUnavailableOptions / bStrikethroughUnavailable -- unavailable option display
BlueprintCallable methods:
SelectOptionByIndex / SelectNextOption / SelectPreviousOption -- navigation
ConfirmSelectedOption -- confirm selection
GetSelectedOptionIndex
BlueprintAssignable events:
OnOptionSelected (OptionIndex)
OnOptionsDisplayComplete / OnOptionsDismissed
Individual option button widget. Subclass in Blueprints to customise appearance.
BlueprintNativeEvent methods:
SetupOption (Option, Index) -- initialise with option data
SetOptionUnavailable -- style as unavailable
OnOptionSelected / OnOptionDeselected -- focus state
Bound widgets (add these to your UMG widget):
OptionText (UTextBlock, BindWidget)
OptionButton (UButton, BindWidget)
Plays audio files synced to dialogue lines. Looks up audio assets by line ID and plays them through a UAudioComponent. Supports fade-in/fade-out and interruption.
bEndLineWhenVoiceOverComplete (BlueprintReadWrite) -- auto-advance on audio end
FadeOutTimeOnInterrupt / WaitTimeBeforeStart / WaitTimeAfterComplete (BlueprintReadWrite) -- timing
AudioComponent
Default variable storage. Stores variables in a TMap. Implements the IYarnVariableStorage interface.
BlueprintCallable methods:
SetString / SetNumber / SetBool / SetValue -- set variables (BlueprintNativeEvent)
TryGetValue / Contains -- read variables (BlueprintNativeEvent)
BlueprintAssignable events:
OnVariableChanged (VariableName, NewValue)
Full localisation support. Auto-detects system culture, supports fallback locales.
bAutoDetectCulture / TextLocaleCode (BlueprintReadWrite) -- locale configuration
bUseFallback / FallbackLocaleCode (BlueprintReadWrite) -- fallback configuration
GetLocaleCode
Debug overlay for monitoring dialogue state at runtime.
DialogueRunner (BlueprintReadWrite) -- runner to monitor
DebugWidgetClass (BlueprintReadWrite) -- custom debug widget class
ToggleKey (BlueprintReadWrite) -- key to show/hide (default: F3)
Commands can be handled three ways:
1. Blueprint Command Handler Objects (recommended for Blueprints) -- Add any UObject to the runner's CommandHandlerObjects array. Create functions matching command names. Parameters auto-convert from strings to the function's parameter types (FString, float, int, bool, FVector, FRotator, etc.).
2. C++ Lambda Registration:
3. OnUnhandledCommand event -- catch-all for commands not handled by methods 1 or 2. Fires with the full command text string.
From Yarn:
Localisation uses the Yarn Spinner compiler's CSV string table export. The compiler generates a -Lines.csv file containing all line IDs and their text. Translate the CSV, reimport, and the plugin resolves localised text at runtime through the line provider. The built-in line provider supports auto-detection of system culture, manual locale override, and fallback locales -- all configurable from Blueprints at runtime.
The UYarnVoiceOverPresenter component plays audio assets matched to dialogue line IDs. Place your audio files in a content directory structure that maps to line IDs, configure the presenter with the base path, and it will automatically find and play the right audio for each line. Supports USoundBase assets (wav, ogg, etc.). Override GetVoiceOverClip in a Blueprint subclass for custom audio resolution.
dotnet tool install YarnSpinner.Console --global --version 3.1.0-alpha1Write your dialogue in .yarn files. Create a .yarnproject file that defines which .yarn files to include via sourceFiles globs.
Drag your .yarnproject into the Content Browser. The plugin automatically runs ysc compile, parses the compiled program, string table, and metadata, and creates a UYarnProject asset.
Add a UYarnDialogueRunner component to an actor, assign your imported Yarn Project asset, and call StartDialogue().
VariableStorage (BlueprintReadWrite) -- where game state is stored (auto-created if not set)
DialoguePresenters (BlueprintReadWrite) -- array of presenter components that receive lines and options
LineProvider (BlueprintReadWrite) -- localisation provider (auto-created if not set)
CommandHandlerObjects (BlueprintReadWrite) -- array of objects with functions matching command names
SaliencyStrategy (BlueprintReadWrite) -- how to pick between competing content candidates
bRunSelectedOptionAsLine (BlueprintReadWrite) -- re-display the chosen option as a line of dialogue
bVerboseLogging (BlueprintReadWrite) -- log all VM execution for debugging
IsDialogueRunning -- check if active
Continue -- advance to next content
RequestHurryUp / RequestNextLine / RequestHurryUpOption -- cancellation flow
SelectOption -- pick an option by index
GetCurrentNodeName -- get executing node name
GetCurrentCancellationToken / GetCurrentOptionsCancellationToken -- for presenter use
OnNodeComplete (NodeName) -- a node finished executing
OnUnhandledCommand (CommandText) -- unhandled command received
OnDialogueStarted / OnDialogueComplete -- dialogue lifecycleOnNodeEnter / OnNodeExit (NodeName) -- node lifecycle
OnHurryUpRequested / OnNextLineRequested -- cancellation events
OnOptionsHurryUpRequested -- option cancellation
OnPrepareForLines (LineIDs) -- pre-load upcoming lines
StartAutoAdvanceTimer / CancelAutoAdvanceTimer -- timer management
GetDialogueRunner -- get the owning runner
IsHurryUpRequested / IsNextContentRequested -- check cancellation state
GetDialogueWidget() (BlueprintCallable) -- get the widget instance
bShowLastLine -- show the last line above options
bUseFadeEffect / FadeInDuration / FadeOutDuration -- fade effects
bEnableKeyboardNavigation -- keyboard/gamepad navigation
NavigateUpKey / NavigateDownKey / ConfirmKey (and alternates) -- configurable keys
AreOptionsVisibleGetVoiceOverClip (BlueprintNativeEvent) -- override to customise audio lookup
OnVoiceOverStarted / OnVoiceOverComplete (BlueprintAssignable) -- events
Clear -- remove all variables (BlueprintNativeEvent)
GetAllVariables -- get all variables as typed maps (float, string, bool)
SetAllVariables -- restore from typed maps (with optional clear)
GetAllVariablesAsMap -- get all as a single FYarnValue map
GetDebugString -- formatted debug output
AddStringChangeListener / AddNumberChangeListener / AddBoolChangeListener -- per-variable callbacks
RemoveChangeListener -- remove a callback
RegisterSmartVariableEvaluator / UnregisterSmartVariableEvaluator -- smart variable support
SetLocaleCodeGetAvailableLocales (BlueprintCallable) -- list available translations
AddLocalizedString (BlueprintCallable) -- add runtime translations
bShowByDefault (BlueprintReadWrite) -- show at start
bAutoLogEvents (BlueprintReadWrite) -- auto-log dialogue events
ScreenAnchor (BlueprintReadWrite) -- position on screen
ToggleDebugHUD / ShowDebugHUD / HideDebugHUD / IsDebugHUDVisible (BlueprintCallable)
Project Inspection
GetAllNodeNames, HasNode, GetNodeCount, GetLineCount, GetAllLineIDs, GetNodeTags, GetAllDeclaredVariableNames, GetDeclaredVariableDefaultValue
Variable Access
GetAllVariableNames, GetAllVariables, HasVariable, GetVariableAsString, GetVariableAsNumber, GetVariableAsBool, SetStringVariable, SetNumberVariable, SetBoolVariable
Persistence
DialogueRunner->AddCommandHandler(TEXT("shake"), [this](const TArray<FString>& Params)
{
float Intensity = FCString::Atof(*Params[0]);
// shake the camera
});<<shake 2.5>>
<<fade 1.0>>SaveVariablesToSlot, LoadVariablesFromSlot, DoesVariableSlotExist, DeleteVariableSlot
Value Conversion
MakeYarnValueFromString, MakeYarnValueFromNumber, MakeYarnValueFromBool, YarnValueToString, GetYarnValueTypeName
Runner Helpers
GetDialogueRunner (find on actor), GetAllDialogueRunners (find all in level)
Learn how to get started with Yarn Spinner in Unreal Engine 5.
This is a Pre-release of Yarn Spinner for Unreal Engine. There will be bugs, we might change the API or features with an update, or something may break. We do not recommend you use this to ship a game just yet.
Please submit issues or feature requests via this form during the pre-release period:
This gets you from zero to running dialogue in about five minutes. It assumes you already know how to write Yarn and use Unreal Engine.
Visit https://github.com/YarnSpinnerTool/YarnSpinner-UnrealEngine to download the plugin. Then:
Copy the YarnSpinner/ plugin folder into your Unreal project's Plugins/ directory.
Open your project in the Unreal Editor -- the plugin will be detected automatically.
The plugin needs ysc (the Yarn Spinner Cosole) to compile your .yarn files. Install the required version of it globally with:
The editor plugin will find ysc automatically if it's on your PATH or in a standard dotnet tools location (~/.dotnet/tools/).
Create a .yarnproject file and your .yarn files. The .yarnproject tells the compiler which .yarn files to include -- the sourceFiles field is a list of globs or specific paths:
This compiles every .yarn file in the project directory and its subdirectories. You can be more specific:
A game can have multiple .yarnproject files, each pointing to different sets of .yarn files. Each one compiles independently into its own program -- useful for separating main story dialogue, NPC barks, tutorials, etc. Each project becomes its own UYarnProject asset in Unreal.
Drag your .yarnproject file and .yarn files into the Content Browser. The editor plugin automatically runs ysc compile on it, which compiles all .yarn files in the project's sourceFiles scope into a single binary program, string table, and metadata CSV. The plugin parses those outputs and creates a UYarnProject asset. The temp files are cleaned up automatically.
Compilation is always the full set of source files as defined by the project -- there's no incremental or per-file compilation.
The editor plugin watches your .yarn files on disk. When you save a change to any .yarn file (or the .yarnproject itself), the corresponding UYarnProject asset is automatically reimported -- no manual action needed. Adding a new .yarn file that matches the project's sourceFiles globs also triggers automatic reimport. Rapid saves are debounced into a single reimport.
You can also reimport manually by right-clicking the asset in the Content Browser and selecting Reimport.
Here's the minimal setup:
Create an actor in your level (or use an existing one).
Add a UYarnDialogueRunner component. In the Details panel, set Yarn Project to your imported Yarn project asset.
Add a UYarnDialoguePresenter component
Call StartDialogue on the dialogue runner component:
Other dialogue control nodes available in Blueprints:
Start Dialogue -- begin from a specific node name
Start Dialogue From Start -- begin from the configured StartNode
Stop Dialogue -- stop immediately
Is Dialogue Running
Or tick bAutoStart in the Detals panel and set StartNode to your starting node name -- dialogue begins automatically when the game starts.
That's it. Run the game and your dialogue plays.
Commands let Yarn tell your game to do things.
The easiest way to handle commands in Blueprints is with *Command Handler Objects. Add any Blueprint (or Actor, or UObject) to the dialogue runner's Command Handler Objects array in the Details panel. When Yarn executes a command, the runner looks for a function with the same name on those objects.
For example, if your Yarn script has:
Create a Blueprint with functions named play_sound and shake_camera. Parameters are automatically converted from strings -- FString, float, int, bool, FVector, FRotator, etc. all work:
Create a new Blueprint (any UObject subclass)
Add a function named play_sound with an FString parameter
Add a function named shake_camera with a float parameter
The runner auto-discovers functions matching command names. No string parsing required.
You can also bind to the OnUnhandledCommand event on the dialogue runner. It fires with the full command text whenever a command isn't handled by any registered handler -- useful as a catch-all.
The runner handles these commands automatically:
<<wait 2.0>> -- pause dialogue for a duration (in seconds)
<<stop>> -- end dialogue immediately
Functions let Yarn read values from your game. Register them in C++ with a name, implementation, and parameter count:
Use them in Yarn expressions:
Yarn variables work out of the box. Declare them in your .yarn files and they're stored in an in-memory variable storage:
The UYarnBlueprintLibrary provides static functions for reading and writing variables. All are available in the Blueprint action menu under Yarn Spinner | Variables:
Reading variables:
Get Variable As Number -- get a float variable (returns false if not found or wrong type)
Get Variable As String -- get a string variable (works for any type, converts automatically)
Get Variable As Bool -- get a bool variable (returns false if not found or wrong type)
Has Variable -- check if a variable exists in storage
Writing variables:
Set Number Variable -- set a float variable
Set String Variable -- set a string variable
Set Bool Variable -- set a bool variable
All of these take a Dialogue Runner reference and the variable name (with $ prefix):
Inspecting project defaults:
Get All Declared Variable Names -- get all variables declared in a Yarn project
Get Declared Variable Default Value -- get the initial value of a declared variable
The runner creates a UYarnInMemoryVariableStorage automatically if you don't assign one. If you need persistence, implement the IYarnVariableStorage interface and assign it in the Details panel.
The in-memory variable storage supports change listeners. Register a callback that fires whenever a specific variable changes:
These are BlueprintCallable on UYarnInMemoryVariableStorage. Access the storage from the runner's VariableStorage property.
The plugin provides one-call save/load functions that persist all Yarn variables to disk using Unreal's USaveGame system. Available in Blueprints under Yarn Spinner | Persistence:
Save Variables To Slot -- save all variables to a named save slot
Load Variables From Slot -- load variables from a save slot (clears existing variables first)
Does Variable Slot Exist -- check if a save slot exists
Delete Variable Slot -- delete a save slot from disk
The default slot name is "YarnVariables" and the default user index is 0. Use different slot names for multiple save slots (e.g., "YarnSave_Slot1", "YarnSave_Slot2").
All three variable types (float, string, bool) are serialised. The save file is written to Unreal's standard save game directory (Saved/SaveGames/).
The dialogue runner fires events at key points during dialogue execution. Bind to these in Blueprints by dragging off the dialogue runner component and selecting the event:
On Dialogue Start -- dialogue has begun
On Dialogue Complete -- dialogue has ended
On Node Start (NodeName) -- a node has started executing
On Node Complete (NodeName) -- a node has finished executing
Options Presenter:
On Option Selected (OptionIndex) -- player picked an option
On Options Display Complete -- options finished fading in
On Options Dismissed -- options finished fading out
Voice Over Presenter:
On Voice Over Started -- audio playback began
On Voice Over Complete -- audio playback finished
Variable Storage:
On Variable Changed (VariableName, NewValue) -- any variable was modified
You can change which Yarn project a dialogue runner uses at runtime. This is useful for level transitions, DLC content, or modding support.
In Blueprints:
From C++:
SetYarnProject handles all the internal state:
Stops any active dialogue
Updates the VM to use the new program
Updates the line provider for localisation
Updates variable storage's initial value lookups
Existing variables in storage are preserved -- only the project's initial value lookups change. After swapping, call StartDialogue to begin running from the new project.
The UYarnBlueprintLibrary class provides static functions accessible from any Blueprint. Find them in the action menu under Yarn Spinner.
Query information about a Yarn project asset:
Get All Node Names -- list all nodes in a project
Has Node -- check if a node exists
Get Node Count / Get Line Count -- project statistics
Get All Line IDs -- list all dialogue line IDs
Get Dialogue Runner (Actor) -- find the runner component on an actor
Get All Dialogue Runners (WorldContext) -- find every runner in the level
Pure functions for creating and converting FYarnValue structs:
Make Yarn Value From String/Number/Bool -- create values
Yarn Value To String -- convert any value to a display string
Get Yarn Value Type Name -- get the type name ("String", "Number", "Bool")
On UYarnDialogueRunner in the Details panel:
Yarn Project -- the imported Yarn project asset to run
Start Node -- which Yarn node to begin from (default: "Start")
Auto Start -- begin dialogue when the game starts
On UYarnDialoguePresenter:
Auto Advance -- automatically continue to the next line after a delay
Auto Advance Min/Max Delay -- timing bounds for auto-advance
Auto Advance Time Per Character -- extra delay per character in the line
On UYarnWidgetPresenter:
Typewriter Speed -- characters per second (0 = instant)
Background Color / Text Color / Character Name Color -- appearance
Widget Class -- custom UMG widget class to use
On UYarnOptionsPresenter:
Option Widget Class -- the widget Blueprint to use for each option button
Show Unavailable Options -- show options the player can't pick (greyed out) instead of hiding them
Strikethrough Unavailable -- draw a strikethrough on greyed-out options
Show Last Line -- display the last line of dialogue above the options
On UYarnVoiceOverPresenter:
End Line When Voice Over Complete -- auto-advance when audio finishes
Fade Out Time On Interrupt -- fade-out duration when interrupted
Wait Time Before Start / Wait Time After Complete -- pre/post audio delays
Audio Component -- the audio component to play through
If the built-in presenters don't fit your UI, subclass UYarnDialoguePresenter.
Create a new Blueprint with UYarnDialoguePresenter as the parent class.
Override Run Line -- this receives the localised line with character name, text, and markup. Display it however you like, then call On Line Presentation Complete when done.
Override Run Options -- this receives the option set. Display the options, then call On Option Selected with the chosen index.
The FYarnLocalizedLine struct passed to RunLine contains:
Text -- the final localised text
CharacterName -- extracted character name (from "Name: text" format)
TextWithoutCharacterName -- text with the character name prefix removed
Register it the same way: add it to the DialoguePresenters array on the dialogue runner.
Subclass UYarnOptionWidget to customise option button appearance. Override these Blueprint events:
Setup Option -- initialise the widget with option data and index
Set Option Unavailable -- style the widget as unavailable
On Option Selected -- the option was highlighted/focused
On Option Deselected -- the option lost focus
The widget has OptionText (UTextBlock) and OptionButton (UButton) as bound widgets. Add them to your UMG widget and the base class wires them up.
If you're using node groups (multiple versions of the same content with when: conditions), set a saliency strategy on the runner in the Details panel. Available strategies:
First -- pick the first viable candidate
Best -- pick the most specific (highest complexity) viable candidate
BestLeastRecentlyViewed -- pick the most specific candidate that hasn't been seen recently
RandomBestLeastRecentlyViewed -- like above, but randomised among equally-good candidates (this is the default)
The built-in line provider (UYarnBuiltinLineProvider) supports full localisation. Key properties (all configurable in Details panel or from Blueprints):
Auto Detect Culture -- automatically use the system's locale
Text Locale Code -- manually set the locale (e.g., "fr", "de", "ja")
Use Fallback -- fall back to another locale if a translation is missing
Blueprint functions on the line provider:
Get Locale Code -- get the current locale
Set Locale Code -- change the locale at runtime
Get Available Locales -- list all locales that have translations
Add Localized String -- add a runtime localised string for a line ID and locale
Add a UYarnVoiceOverPresenter component to play audio synced to dialogue lines. It looks up USoundBase assets by line ID and plays them through a UAudioComponent. Configure the base content path and it handles the rest -- fade-in, fade-out, and interruption are all built in.
Override GetVoiceOverClip in a Blueprint subclass to customise how audio assets are resolved.
Add a UYarnDebugHUDComponent to your actor to get a real-time debug overlay showing:
Current node and line ID
All variables and their values
Execution history (lines, options selected, commands, node transitions)
Configure in the Details panel:
Dialogue Runner -- which runner to monitor
Toggle Key -- key to show/hide the HUD (default: F3)
Show By Default -- whether to show the HUD on start
Auto Log Events -- automatically log dialogue events to the history
You can also use the UYarnDebugWidget directly in your own UMG layouts.
The plugin supports Yarn's full markup system. Tags in your dialogue text are parsed and made available to presenters:
Register custom markup processors by implementing the IYarnMarkupProcessor interface, or use the built-in UYarnPaletteMarkupProcessor with a UYarnRichTextPalette data asset to define styles in the editor without writing code.
UYarnWidgetPresenterAdd a UYarnOptionsPresenter component. This handles showing dialogue choices. Create an option widget blueprint using UYarnOptionWidget as the base class, and assign it to OptionWidgetClass.
Wire the presenters to the runner. In the Details panel on the UYarnDialogueRunner, add your presenter components to the DialoguePresenters array.
Continue -- advance to the next content
Request Hurry Up -- speed up presentation (e.g., complete typewriter instantly)
Request Next Line -- skip the current line entirely
Select Option -- pick an option by index
Get Current Node Name -- get the name of the executing node
Set Yarn Project -- swap to a different Yarn project at runtime (see Runtime Project Swap)
Add that Blueprint to the runner's Command Handler Objects array
Get All Variable Names -- get an array of all variable names currently in storage
Get All Variables -- get a map of all variables and their values
On Unhandled Command (CommandText) -- a command wasn't handled by any registered handler
Resets presentation state
Get Node Tags -- get tags for a specific node
Get All Declared Variable Names -- list all declared variables
Get Declared Variable Default Value -- get a variable's initial value
Saliency Strategy -- how to pick between competing content candidates (First, Best, BestLeastRecentlyViewed, RandomBestLeastRecentlyViewed)
Verbose Logging -- log all VM execution to the output log for debugging
Command Handler Objects -- array of objects with functions that match command names
Use Fade Effect -- fade the options panel in/out
Fade In/Out Duration -- timing for fade effects
Enable Keyboard Navigation -- navigate options with arrow keys/WASD and confirm with Enter/Space
Navigate Up/Down Key -- configurable navigation keys (defaults: Up/Down arrows, W/S)
Confirm Key -- configurable confirm key (defaults: Enter, Space)
Optionally override On Dialogue Started, On Dialogue Complete, On Node Enter, On Node Exit, On Hurry Up Requested, On Next Line Requested, and On Prepare For Lines.
Metadata -- array of line tags (from #tag syntax in Yarn)
TextMarkup -- parsed markup attributes for effects like [bold], [shake], etc.
RawLine -- the original line data including LineID and substitutions
Fallback Locale Code -- the fallback locale (default: base language)
Screen Anchor -- position on screen (0,0 = top-left, 1,1 = bottom-right)
dotnet tool install YarnSpinner.Console --global --version 3.1.0-alpha1{
"projectFileVersion": 3,
"sourceFiles": ["**/*.yarn"],
"baseLanguage": "en"
}{
"sourceFiles": ["Dialogue/*.yarn", "Barks/*.yarn"]
}Dialogue Runner -> Start Dialogue ("Start")UYarnDialogueRunner* Runner = MyActor->FindComponentByClass<UYarnDialogueRunner>();
Runner->StartDialogue(TEXT("Start"));<<play_sound "boom">>
<<shake_camera 2.5>>DialogueRunner->AddCommandHandler(TEXT("shake"), [this](const TArray<FString>& Params)
{
float Intensity = FCString::Atof(*Params[0]);
CameraShake(Intensity);
});
DialogueRunner->AddCommandHandler(TEXT("fade"), [this](const TArray<FString>& Params)
{
float Duration = FCString::Atof(*Params[0]);
FadeToBlack(Duration);
});DialogueRunner->AddFunction(TEXT("player_health"), [this](const TArray<FYarnValue>& Params) -> FYarnValue
{
return FYarnValue(Player->GetHealth());
}, 0);
DialogueRunner->AddFunction(TEXT("has_item"), [this](const TArray<FYarnValue>& Params) -> FYarnValue
{
FString ItemName = Params[0].ConvertToString();
return FYarnValue(Inventory->HasItem(ItemName));
}, 1);<<if player_health() < 50>>
You're not looking so good.
<<endif>>
<<if has_item("key")>>
The door opens.
<<endif>>
You have {format("{0:F0}", player_health())} health remaining.<<declare $coins = 0>>
<<declare $player_name = "Adventurer">>
<<declare $has_sword = false>>
<<set $coins = $coins + 50>>
Welcome, {$player_name}! You have {$coins} coins.Get Variable As Number (Dialogue Runner, "$coins") -> OutValue, ReturnValue
Set Number Variable (Dialogue Runner, "$coins", 100.0)FYarnValue Coins;
if (DialogueRunner->GetVariableStorage()->TryGetValue(TEXT("$coins"), Coins))
{
float CoinCount = Coins.ConvertToNumber();
}
DialogueRunner->GetVariableStorage()->SetValue(TEXT("$player_name"), FYarnValue(TEXT("Hero")));Add Number Change Listener (Storage, "$coins", OnCoinsChanged)
Add String Change Listener (Storage, "$player_name", OnNameChanged)
Add Bool Change Listener (Storage, "$has_sword", OnSwordChanged)
Remove Change Listener (Handle)Save Variables To Slot (Dialogue Runner, "YarnVariables", 0) -> bool
Load Variables From Slot (Dialogue Runner, "YarnVariables", 0) -> boolDialogueRunner->OnDialogueStart.AddDynamic(this, &AMyActor::OnDialogueStarted);
DialogueRunner->OnDialogueComplete.AddDynamic(this, &AMyActor::OnDialogueEnded);
DialogueRunner->OnNodeStart.AddDynamic(this, &AMyActor::OnNodeEntered);
DialogueRunner->OnNodeComplete.AddDynamic(this, &AMyActor::OnNodeExited);
DialogueRunner->OnUnhandledCommand.AddDynamic(this, &AMyActor::OnCommand);Dialogue Runner -> Set Yarn Project (NewYarnProject)Runner->SetYarnProject(NewProject);UCLASS(Blueprintable)
class UMyPresenter : public UYarnDialoguePresenter
{
GENERATED_BODY()
public:
virtual void RunLine_Implementation(const FYarnLocalizedLine& Line, bool bCanHurry) override
{
// Display the line however you want
UE_LOG(LogTemp, Log, TEXT("%s: %s"), *Line.CharacterName, *Line.Text);
// Call this when you're done presenting the line
OnLinePresentationComplete();
}
virtual void RunOptions_Implementation(const FYarnOptionSet& Options) override
{
// Build your own UI, then call OnOptionSelected(index) when the player picks one
for (int32 i = 0; i < Options.Options.Num(); i++)
{
UE_LOG(LogTemp, Log, TEXT(" [%d] %s"), i, *Options.Options[i].Line.Text);
}
}
};I [bold]really[/bold] need your help with [shake]this[/shake]!
You need {format("{0:N0}", $coins)} coins. // thousand separators
I have [plural value={$apples} one="% apple" other="% apples"/].