v2.0.0
Yarn Spinner is made possible by your generous patronage. Please consider supporting Yarn Spinner's development by becoming a patron!
👩🚒 Getting Help
There are several places you can go to get help with Yarn Spinner.
- Join the Yarn Spinner Discord.
- Tweet at us, at @YarnSpinnerTool.
- To report a bug, file an issue on GitHub.
📦 How To Install Yarn Spinner
To install the most recent release of Yarn Spinner for Unity, please see the Installation Instructions in the Yarn Spinner documentation.
If you want to install this particular version of Yarn Spinner for Unity, follow these steps:
Installing Yarn Spinner for Unity v2.0.0 from Git
- Open the Window menu, and choose Package Manager.
- If you already have any previous version of the Yarn Spinner package installed, remove it.
- Click the
+
button, and click Add package from git URL... - Enter the following URL:
https://github.com/YarnSpinnerTool/YarnSpinner-Unity.git#v2.0.0
Each release will have a different URL. To upgrade to future versions of Yarn Spinner, you will need to uninstall the package, and reinstall using the new URL.
📜 Changes
Yarn Spinner 2.0
Yarn Spinner 2.0 is a major new release, and contains a large number of new features and improvements.
New syntax for jumping to a different node.
- We have added a
<<jump Destination>>
command, which replaces the[[Destination]]
jump syntax.
- Accordingly, the
[[Destination]]
and[[Option|Destination]]
syntax has been removed from the language. - Instead of using
[[Option|Destination]]
syntax, combine the new<<jump Destination>>
command with shortcut->
options instead. For example:
// Before
Kim: You want a bagel?
[[Yes, please!|GiveBagel]]
[[No, thanks!|DontWantBagel]]
// After
Kim: You want a bagel?
-> Yes, please!
<<jump GiveBagel>>
-> No, thanks!
<<jump DontWantBagel>>
- The old syntax was inherited from the original Yarn language, which itself inherited it from Twine.
- We removed it for four reasons:
1. it conflated jumps and options, which are very different operations, with too-similar syntax
2. the Option-destination syntax for declaring options involved the management of non-obvious state (that is, if an option statement was inside anif
branch that was never executed, it was not presented, and the runtime needed to keep track of that)
3. it was not obvious that options accumulated and were only presented at the end of the node
4. finally, shortcut options provide a cleaner way to present the same behaviour. - No change to the bytecode is made here; these changes only affect the compiler.
Automatic upgrader for Yarn Spinner 1.0 variables.
- An automatic upgrader has been added that attempts to determine the types of variables in Yarn Spinner 1.0, and generates
<<declare>>
statements for variables.
- This upgrader infers the type of a variable based on the values that are assigned to it, and the values of expressions that it participates in.
- If the upgrader cannot determine the type of a variable, it generates a declaration of the form
<<declare $variable_name as undefined>>
. The wordundefined
is not a valid type in Yarn Spinner, which means that these declarations will cause an error in compilation (which is a signal to the developer that the script needs to be manually updated.) - For example: given the following script:
- If the upgrader cannot determine the type of a variable, it generates a declaration of the form
<<set $const_string = "foo">>
<<set $const_number = 2>>
<<set $const_bool = true>>
- The upgrader will generate the following variable declarations:
<<declare $const_string = "" as string>>
<<declare $const_number = 0 as number>>
<<declare $const_bool = false as bool>>
- The upgrader is able to make use of type even when it appears later in the program, and is able to make inferences about type using indirect information.
// These variables are participating in expressions that include
// variables we've derived the type for earlier in this program, so they
// will be bound to that type
{$derived_expr_const_string + $const_string}
{$derived_expr_const_number + $const_number}
{$derived_expr_const_bool && $const_bool}
// These variables are participating in expressions that include
// variables that we define a type for later in this program. They will
// also be bound to that type.
{$derived_expr_const_string_late + $const_string_late}
{$derived_expr_const_number_late + $const_number_late}
{$derived_expr_const_bool_late && $const_bool_late}
<<set $const_string_late = "yes">>
<<set $const_number_late = 1>>
<<set $const_bool_late = true>>
- The upgrader will also make in-line changes to any
if
orelseif
statements where the expression is determined to use a number rather than a bool will be rewritten so that the expression evaluates to a bool:
// Define some variables whose type is known before the expressions are
// hit
<<set $some_num_var = 1>>
<<set $some_other_num_var = 1>>
// This will be converted to a bool expression
<<if $some_num_var>>
<<elseif $some_other_num_var>>
<<endif>>
* Will be rewritten to:
<<elseif $some_other_num_var != 0>>
<<endif>>
You can use characters that the parser uses in scripts!
- Characters can now be escaped in lines and options.
- The
\
character can be used to write characters that the parser would otherwise use. - The following characters can be escaped:
{
}
<
>
#
/
\
- The
/
and<
characters don't usually need to be escaped if they're appearing on their own (they're only meaningful when they appear in pairs), but this allows you to escape things like commands and comments.
- The
Identifiers now support a wider range of characters.
This includes most multilingual letters and numbers, as well as symbols and emoji.
Made line conditions control the IsAvailable
flag on options that are sent to the game.
- This change was made in order to allow games to conditionally present, but disallow, options that the player can't choose. For example, consider the following script:
TD-110: Let me see your identification.
-> Of course... um totally not General Kenobi and the son of Darth Vader.
Luke: Wait, what?!
TD-110: Promotion Time!
-> You don't need to see his identification. <<if $learnt_mind_trick is true>>
TD-110: We don't need to see his identification.
- If the variable
$learnt_mind_trick
is false, a game may want to show the option but not allow the player to select it (i.e., show that this option could have been chosen if they'd learned how to do a mind trick.)- In previous versions of Yarn Spinner, if a line condition failed, the entire option was not delivered to the game. With this change, all options are delivered, and the
OptionSet.Option.IsAvailable
variable containsfalse
if the condition was not met, andtrue
if it was (or was not present.) - It's entirely up to the game to decide what to do with this information. To re-create the behaviour from previous Yarn Spinner versions, simply don't show any options whose
IsAvailable
value isfalse
.
- In previous versions of Yarn Spinner, if a line condition failed, the entire option was not delivered to the game. With this change, all options are delivered, and the
Variable declarations are now automatically determined, where possible
- If a variable is not declared (i.e. it doesn't have a
<<declare>>
statement), the compiler will now attempt to infer its declaration. - When a variable doesn't have a declaration, the compiler will try to figure out the type based on how the variable is being used. It will always try to figure out the single type that the variable must be; if it's ambiguous, or no information is available at all, it will report an error, and you will have to add a declaration.
Variable declaration descriptions use comments
- Declarations have their descriptions set using a triple-slash (
///
) comment:
/// The number of coins the player has
<<declare $coins = 0>>
- These documentation comments can be before a declaration, or on the same line as a declaration:
<<declare $player_likes_dogs = true>> /// Whether the player likes dogs or not
- Multiple-line documentation comments are also supported:
/// Whether these are the droids that the
/// guards are looking for.
<<declare $are_the_droids_we're_looking_for = false>>
A new type system has been added.
- The type-checking system in Yarn Spinner now supports types with supertypes and methods. This change has no significant impact on users writing Yarn scripts, but it enables the development of more advanced language features.
- The main impact on users of this library (such as, for example, Yarn Spinner for Unity) is that the
Yarn.Type
enumeration has been removed, and is now replaced with theYarn.IType
interface and theBuiltinTypes
class. - The type checker no longer hard-codes which operations can be run on which types; this decision is now determined by the types themselves.
- The main impact on users of this library (such as, for example, Yarn Spinner for Unity) is that the
Better Error Messages
The Compiler will no longer throw a ParseException
, TypeException
or CompilerException
when an error is encountered during compilation. Instead, CompilationResult.Diagnostics
contains a collection of Diagnostic
objects, which represent errors, warnings, or other diagnostic information related to the compiled program.
- This change was implemented so that if multiple problems can be detected in a program, they can all be reported at once, rather than the compiler stopping at the first one.
- This also allows the compiler to issue non-fatal diagnostic messages, like warnings, that do not prevent the script from being compiled, but might indicate a problem with the code.
- Exceptions will continue to be thrown if the compiler encounters an internal error (in other words, if Yarn Spinner itself has a bug.)
- If an error is encountered during compilation,
CompilationResult.Program
will benull
. - This change means that compilation failures will not cause
Compiler.Compile()
to throw an exception; code that was previously using atry...catch
to detect problems will need to be rewritten to check theCompilationResult.Diagnostics
property to find the actual problem.
- If an error is encountered during compilation,
Fixes and Smaller Changes
- Fixed a crash in
LineParser
if a null input was provided to it. - Fixed a crash in
FormatFunctionUpgrader
(which upgrades v1 Yarn scripts to v2) if an invalid format format function was encountered. - Variable declaration upgrader now generates .yarnproject files, not .yarnprogram files.
- Line tagger now adds line tags before any
//
comment in the line. - Dialogue:
LogErrorMessage
andLogDebugMessage
now perform null-checks before being invoked. Utility.GenerateYarnFileWithDeclarations
now generates files that use triple-slash (///
) comments.- Fixed a bug where expressions inside an
if
statement orelseif
statement would not be type-checked. - The keywords
enum
,endenum
andcase
are now reserved. - The type-conversion functions,
string
,number
andbool
, are no longer built-in special-case functions; they are now regular built-in functions that take a value ofAny
type. - The lexer no longer uses semantic predicates when lexing the TEXT rule, which reduces the amount of C# code present in the grammar file.
- Markup can now be escaped, using the
\
character:
\[b\]hello\[/b\]
// will appear to the user as "[b]hello[/b]", and will not
// be treated as markup
Dialogue.SetSelectedOption
can now be called within the options handler itself.- If you do this, the
Dialogue
will continue executing after the options handler returns, and you do not need to callContinue
.
- If you do this, the
- The compiler now generates better error messages for syntax errors. For example, given the following code (note the lack of an
<<endif>>
at the end):
<<if $has_key>>
Guard: You found the key! Let me unlock the door.
The compiler will produce the following error message:
Expected an <<endif>> to match the <<if>> statement on line 1
- The compiler's new error messages now also report additional information about the context of a syntax error. For example, given the following code:
<<if hasCompletedObjective("find_key" >>
// error! we forgot to add an ')'!
<<endif>>
The compiler will produce the following error message:
Unexpected ">>" while reading a function call
VirtualMachine.executionState
has been renamed toVirtualMachine.CurrentExecutionState
.- It is now a compiler error if the same line ID is used on more than one line.
- Dialogue.VariableStorage is now public.
- The ParseException, TypeException and CompilerException classes have been removed.
Yarn Spinner 2.0 for Unity
Importing Yarn Scripts
- In Yarn Spinner 1.0,
.yarn
files were individually added to the Yarn Programs list in your Dialogue Runner. - In Yarn Spinner 2.0,
.yarn
files are now added to a new 'Yarn Project’ asset, and this single asset is added to your Dialogue Runner in Unity. - Individual
.yarn
scripts are now combined into a single 'Yarn Project’, which is what you provide to yourDialogueRunner
. You no longer add multiple.yarn
files to a DialogueRunner. - To create a new Yarn Project in Unity, open the Asset menu, and choose Create -> Yarn Spinner -> Yarn Project. You can also create a new Yarn Project by selecting a Yarn Script, and clicking Create New Yarn Project.
- A new dialogue prefab, found in Packages > Yarn Spinner > Prefabs > Dialogue System, has been added.
- This prefab makes use of new, more customisable dialogue views. This prefab is designed to be a complete solution for games to use, while also being a useful jumping-off point for building custom interfaces.
- The majority of the Sample projects, including
Intro
,VisualNovel
, and3D
, have been updated to use these new dialogue views, to demonstrate how they can be used.
Variables must be declared
The new version of the Yarn anguage requires variables to be declared in order to be used. You can declare them in your .yarn scripts, or you can declare them in the Inspector for your Yarn Program.
Variables must always have a defined type, and aren't allowed to change type. This means, for example, that you can't store a string inside a variable that was declared as a number.
Variables must also have a default value. As a result, variables are never allowed to be null
.
Variable declarations can be in any part of a Yarn script. As long as they're somewhere in the file, they'll be used. You can also declare your variables in the Yarn Program itself.
-
To declare a variable on a Yarn Program in Unity, select it, and click the
+
button to create the new variable. -
To declare a variable in a script, use the following syntax:
<<declare $variable_name = "hello">> // declares a string
<<declare $variable_name = 123>> // declares a number
<<declare $variable_name = true>> // declares a boolean
Variable declarations don't have to be in the same file as where they're used. If the Yarn Program contains a script that has a variable declaration, other scripts in that Program can use the variable.
Dialogue Views replace DialogueUI
In Yarn Spinner 1.0, the component that presents lines, options and commands to the player is the DialogueUI
component. The DialogueRunner
had a single DialogueUI
, which it sent all of its content to. If you wanted to create your own custom UI for presenting dialogue to the player, you were encouraged to make your own class based off its code, and modify it to suit your needs.
In Yarn Spinner 2.0, we've made the line presentation system a little more flexible, through the use of dialogue views. A dialogue view is a component that receives lines and options. (Commands are handled by the Dialogue Runner, via either methods that have the YarnCommand
attribute, or via the Dialogue Runner's AddCommandHandler
method.)
The main difference between Yarn Spinner 1.0 and 2.0 is that while you were limited to a single DialogueUI
, in 2.0 you can have multiple dialogue views. Each view can do a different thing; for example, you might have one view that displays the text of a line on screen, another that handles audio playback, and another that displays a portrait of the currently speaking character.
Line views are also able to interrupt each other. When a line view calls the MarkLineComplete
method, the line becomes interrupted, and all line views are notified (and should do things like quickly finish displaying all text, or quickly fading out the audio.)
When a line view has finished presenting its line - for example, all of the text has appeared, or the audio has finished playing - it sends a signal that it's finished. When all line views have finished, the line becomes delivered, and the dialogue runner may choose to send another line (or wait for a signal from the player.)
The Yarn Spinner 2.0 beta ships with several examples of line views. In particular:
- The
DialogueUI
class is now a dialogue view. VoiceOverPlaybackUnity
is a dialogue view that presents voiceover audio for a line, using Unity's built-in audio components.VoiceOverPlaybackFmod
is a a dialogue view that presents voiceover audio for a line, using Fmod (if it's installed.)
Localization Support
- Yarn Spinner 2.0 has support for localizing your content into multiple languages. To localize your game, you specify which languages your project uses, and specify which of these support audio and which are text-only.
- The Yarn Project (see above) stores the references to Localization objects - one for each language that the project is using.
- A Localization object stores per-line information - both the localized text for the line, as well as an optional asset for the line (such as an audio clip).
- Localizations get their content from Yarn scripts. Every Yarn script has at least one localization - the 'base' localization. This is the language that the
.yarn
file was written in.
- When a Yarn script is imported, a string table is generated for the base localization. You don't edit this string table; it's generated for you.
- When you want to translate a Yarn script into other languages, you generate a new string table by selecting the script, and clicking the Create New button for the language you want to add. A new string table is generated, which you can edit.
- The list of languages you support is defined by those available in the Yarn Project.
- If the appropriate language cannot be found for the selected language, the original language of your Yarn Project is used.
- Localised assets, such as voice-over clips, are automatically located and set up.
- The Dialogue Runner fetches the localized data it needs from a component called a Line Provider. Yarn Spinner 2.0 ships with three Line Providers:
TextLineProvider
provides a line with localized text.AudioLineProvider
provides a line with localized text and a reference to an AudioClip.AddressableLineProvider
provides a line with localized text, and uses the Addressable Assets system (if it's installed in your project) to get a localized AudioClip.
Yarn Commands parameters now have types
Commands registered via the YarnCommand
attribute can now take parameter types besides strings. Parameters can also be optional. Additionally, these methods are now cached, and are faster to call.
Dialogue.AddFunction now uses functions that can take multiple parameters. You no longer use a single Yarn.Value[]
parameter; you can now have up to 5, which can be strings, integers, floats, doubles, bools, or Yarn.Value
s.
Markup
Yarn Spinner 2.0 introduces markup. When you add tags to your lines, Yarn Spinner will parse them for you, which means you don't need to implement this feature yourself.
Markup looks similar to BBCode:
Mae: Wow, this looks [shake]spooky[/shake]!
Yarn Spinner doesn't define any tags for you. All Yarn Spinner does is tell you which parts of your line have markup; it's up to you to decide what to do with the information. For example, in the line above, you might have your line views make all text that inside the shake
tag shake around.
When a line of dialogue is delivered to your game's line views, they receive three different things:
- The raw text of the line, as it appears in the script (i.e. with the markup present)
- The plain text of the line, with all markup removed
- A collection of markup ranges, describing which parts of the plain text have which attributes.
Attributes can be nested, and can also have properties - additional values that describe extra info. For example, a shake
attribute might have an amount
property:
Mae: Wow, this looks [shake amount=2]spooky[/shake].
If a line of dialogue begins with a character's name followed by a colon (:
), Yarn Spinner acts as though it has a character
attribute. For example, these two lines are effectively identical:
Mae: Hey!
and
[character name="Mae"]Mae: [/character]Hey!
Markup replaces Format Functions as a language feature. Format functions will no longer work; you will need to adapt your syntax. For example:
[plural {$pies} one="pie" many="pies"]
Is now:
[plural value={$pies} one="pie" many="pies" /]
Overall Changelog
Added
- Added a 3D speech bubble sample, for dynamically positioning a speech bubble above a game character. (@radiatoryang)
- Added a phone chat sample. (@radiatoryang)
- Added a visual novel template. (@radiatoryang)
- Added support for voice overs. (@Schroedingers-Cat)
- Added a new API for presenting and managing lines of dialogue.
- Added a new API for working with localizations.
- Added an option to DialogueUI to allow hiding character names.
- The Yarn Spinner Window (Window -> Yarn Spinner) now shows the current version of Yarn Spinner.
- InMemoryVariableStorage now shows the current state of variables in the Inspector. (@radiatoryang)
- InMemoryVariableStorage now supports saving variables to file, and to PlayerPrefs. (@radiatoryang)
- The dialogue runner can now be configured to log less to the console, reducing the amount of noise it generates there. (@radiatoryang)
- Warning messages and errors now appear to help users diagnose two common problems: (1) not adding a Command properly, (2) can't find a localization entry for a line (either because of broken line tag or bad connection to Localization Database) (@radiatoryang)
- Made options that have a line condition able to be presented to the player, but made unavailable.
- This change was made in order to allow games to conditionally present, but disallow, options that the player can't choose. For example, consider the following script:
TD-110: Let me see your identification.
-> Of course... um totally not General Kenobi and the son of Darth Vader.
Luke: Wait, what?!
TD-110: Promotion Time!
-> You don't need to see his identification. <<if $learnt_mind_trick is true>>
TD-110: We don't need to see his identification.
- If the variable
$learnt_mind_trick
is false, a game may want to show the option but not allow the player to select it (i.e., show that this option could have been chosen if they'd learned how to do a mind trick.) - In previous versions of Yarn Spinner, if a line condition failed, the entire option was not delivered to the game. With this change, all options are delivered, and the
OptionSet.Option.IsAvailable
variable containsfalse
if the condition was not met, andtrue
if it was (or was not present.) - The
DialogueUI
component now has a "showUnavailableOptions" option that controls the display behaviour of unavailable options. If it's true, then unavailable options are presented, but not selectable; if it's false, then unavailable options are not presented at all (i.e. same as Yarn Spinner 1.0.) - Audio for lines in a
Localization
object can now be previewed in the editor. (@radiatoryang) - Lines can be added to a
Localization
object at runtime. They're only stored in memory, and are discarded when gameplay ends. - Commands that take a boolean parameter now support specifying that parameter by its name, rather than requiring the string
true
. - For example, if you have a command like this:
[YarnCommand("walk")]
void WalkToPoint(string destinationName, bool wait = false) {
// ...
}
Previously, you'd need to use this in your Yarn scripts:
<<walk MyObject MyDestination true>>
With this change, you can instead say this:
<<walk MyObject MyDestination wait>>
-
New icons for Yarn Spinner assets have been added.
-
New dialogue views,
LineView
andOptionListView
, have been added. These are intended to replace the previousDialogueUI
, make use of TextMeshPro for text display, and allow for easier customisation through prefabs. -
DialogueRunner
s will now automatically create and use anInMemoryVariableStorage
object if one isn't provided. -
The Inspector for
DialogueRunner
has been updated, and is now easier to use. -
Command parameters can now be grouped with double quotes. eg.
<<add-recipe "Banana Sensations">
and<<move "My Game Object" LocationName>>
(@andiCR) -
Yarn script compile errors will prevent play mode.
-
Default functions have been added for convenience.
float random()
- returns a number between 0 and 1, inclusive (proxies Unity's default prng)float random_range(float, float)
- returns a number in a given range, inclusive (proxies Unity's default prng)int dice(int)
- returns an integer in a given range, like a dice (proxies Unity's default prng)- For example,
dice(6) + dice(6)
to simulate two dice, ordice(20)
for a D20 roll.
- For example,
int round(float)
- rounds a number using away-from-zero roundingfloat round_places(float, int)
- rounds a number to n digits using away-from-zero roundingint floor(float)
- floors a number (towards negative infinity)int ceil(float)
- ceilings a number (towards positive infinity)int int(float)
- truncates the number (towards zero)int inc(float | int)
- increments to the next integerint dec(float | int)
- decrements to the previous integerint decimal(float)
- gets the decimal portion of the float
-
The
YarnFunction
attribute has been added.-
Simply add it to a static function, eg
[YarnFunction] // registers function under "example" public static int example(int param) { return param + 1; } [YarnFunction("custom_name")] // registers function under "custom_name" public static int example2(int param) { return param * param; }
-
-
The
YarnCommand
attribute has been improved and made more robust for most use cases.-
You can now leave the name blank to use the method name as the registration name.
[YarnCommand] // like in previous example with YarnFunction. void example(int steps) { for (int i = 0; i < steps; i++) { ... } } [YarnCommand("custom_name")] // you can still provide a custom name if you want void example2(int steps) { for (int i = steps - 1; i >= 0; i--) { ... } }
-
It now recognizes static functions and does not attempt to use the first parameter as an instance variable anymore.
[YarnCommand] // use like so: <<example>> static void example() => ...; [YarnCommand] // still as before: <<example2 objectName>> void example2() => ...;
-
You can also define custom getters for better performance.
[YarnStateInjector(nameof(GetBehavior))] // if this is null, the previous behavior of using GameObject.Find will still be available class CustomBehavior : MonoBehaviour { static CustomBehavior GetBehavior(string name) { // e.g., it may only exist under a certain transform, or you have a custom cache... // or it's built from a ScriptableObject... return ...; } [YarnCommand] // the "this" will be as returned from GetBehavior void example() => Debug.Log(this); // special variation on getting behavior static CustomBehavior GetBehaviorSpecial(string name) => ...; [YarnCommand(Injector = nameof(GetBehaviorSpecial))] void example_special() => Debug.Log(this); }
-
You can also define custom getters for Component parameters in the same vein.
class CustomBehavior : MonoBehaviour { static Animator GetAnimator(string name) => ...; [YarnCommand] void example([YarnParameter(nameof(GetAnimator))] Animator animator) => Debug.Log(animator); }
-
You should continue to use manual registration if you want to make an instance function (ie where the "target" is defined) static.
-
-
Sample scenes now have a render pipeline detector gameobject that will warn when the sample scene materials won't look correct in the current render pipeline.
-
Variables declared inside Yarn scripts will now have the default values set into the variable storage.
-
The console will no longer report an error indicating that a command is "already defined" when a subclass of a MonoBehaviour that has
YarnCommand
methods exists. -
DialogueRunner
will now throw an exception if a dialogue view attempts to select an
option on the same frame that options are run. -
DialogueRunner.VariableStorage
can now be modified at runtime. -
Calling
DialogueRunner.StartDialogue
when the dialogue runner is already running will now result in an error being logged.
Changed
- Individual
.yarn
scripts are now combined into a single 'Yarn Program', which is what you provide to yourDialogueRunner
. You no longer add multiple.yarn
files to a DialogueRunner. To create a new Yarn Program, open the Asset menu, and choose Create -> Yarn Spinner -> Yarn Program. You can also create a new Yarn Program by selecting a Yarn Script, and clicking Create New Yarn Program. - Version 2 of the Yarn language requires variables to be declared. You can declare them in your .yarn scripts, or you can declare them in the Inspector for your Yarn Program.
- Nicer error messages when the localized text for a line of dialogue can't be found.
- DialogueUI is now a subclass of DialogueViewBase.
- Moved Yarn Spinner classes into the
Yarn.Unity
namespace, or one of its children, depending on its purpose. - Dialogue.AddFunction now uses functions that can take multiple parameters. You no longer use a single
Yarn.Value[]
parameter; you can now have up to 5, which can be strings, integers, floats, doubles, bools, orYarn.Value
s. - Commands registered via the
YarnCommand
attribute can now take parameter types besides strings. Parameters can also be optional. Additionally, these methods are now cached, and are faster to call. - Inline expressions (for example,
One plus one is {1+1}
) are now expanded. - Added Help URLs to various classes. (@radiatoryang)
- Fixed an issue where programs failed to import if a source script reference is invalid
- Fixed an issue where the DialogueUI would show empty lines when showCharacterName is false and the line has no character name
- Certain private methods in
DialogueUI
have changed to protected, making it easier to subclass (@radiatoryang) - Fixed an issue where option buttons from previous option prompts could re-appear in later prompts (@radiatoryang)
- Fixed an issue where dialogue views that are not enabled were still being waited for (@radiatoryang)
- Upgrader tool now creates new files on disk, where needed (for example, .yarnproject files)
YarnProgram
, the asset that stores references to individual .yarn files for compilation, has been renamed toYarnProject
. Because this change makes Unity forget any existing references to "YarnProgram" assets, when upgrading to this version, you must set the Yarn Project field in your Dialogue Runners again.Localization
, the asset that mapped line IDs to localized data, is now automatically generated for you by theYarnProject
.- You don't create them yourselves, and you no longer need to manually refresh them.
- The
YarnProject
always creates at least one localization: the "Base" localization, which contains the original text found in your.yarn
files. - You can create more localizations in the
YarnProject
's inspector, and supply the language code to use and a.csv
file containing replacement strings.
- Renamed the 'StartHere' demo to 'Intro', because it's not actually the first step in installing Yarn Spinner.
- Simplified the workflow for working with Addressable Assets.
- You now import the package, enable its use on your Yarn Project, and click the Update Asset Addresses button to ensure that all assets have an address that Yarn Spinner knows about.
- The 3D, VisualNovel, and Intro examples have been updated to use the new
LineView
andOptionsListView
components, rather thanDialogueUI
. DialogueRunner.ResetDialogue
is now marked as Obsolete (it had the same effect as just callingStartDialogue
anyway.)- The
LineStatus
enum's values have been renamed, to better convey their purpose:Running
is nowPresenting
.Interrupted
remains the same.Delivered
is nowFinishedPresenting
.Ended
is nowDismissed
.
- The
ResetDialogue()
method now takes an optional parameter to restart from. If none is provided, the dialogue runner attempts to restart from the start node, followed by the current node, or else throws an exception. DialogueViewBase.MarkLineComplete
, the method for signalling that the user wants to interrupt or proceed to the next line, has been renamed toReadyForNextLine
.DialogueRunner.continueNextLineOnLineFinished
has been renamed toautomaticallyContinueLines
.
Removed
-
Support for Unity 2018 LTS has been dropped, and 2019 LTS (currently 2019.4.32f1) will be the minimum supported version. The support scheme for Yarn Spinner will be clarified in the CONTRIBUTING docs. If you still require support for 2018, please join our Discord!
-
Commands registered via the
YarnCommand
attribute can no longer accept aparams
array of parameters. If your command takes a variable number of parameters, use optional parameters instead. -
The
[[Destination]]
and[[Option|Destination]]
syntax has been removed from the language.- This syntax was inherited from the original Yarn language, which itself inherited it from Twine.
- We removed it for four reasons:
- it conflated jumps and options, which are very different operations, with too-similar syntax;
- the Option-destination syntax for declaring options involved the management of non-obvious state (that is, if an option statement was inside an
if
branch that was never executed, it was not presented, and the runtime needed to keep track of that); - it was not obvious that options accumulated and were only presented at the end of the node;
- finally, shortcut options provide a cleaner way to present the same behaviour.
- We have added a
<<jump Destination>>
command, which replaces the[[Destination]]
jump syntax. - No change to the bytecode is made here; these changes only affect the compiler.
- Instead of using
[[Option|Destination]]
syntax, use shortcut options instead. For example:
// Before
Kim: You want a bagel?
[[Yes, please!|GiveBagel]]
[[No, thanks!|DontWantBagel]]
// After
Kim: You want a bagel?
-> Yes, please!
<<jump GiveBagel>>
-> No, thanks!
<<jump DontWantBagel>>
- InMemoryVariableStorage no longer manages 'default' variables (this concept has moved to the Yarn Program.) (@radiatoryang)
LocalizationDatabase
, the asset that stored references toLocalization
assets and manages per-locale line lookups, has been removed. This functionality is now handled byYarnProject
assets. You no longer supply a localization database to aDialogueRunner
or to aLineProvider
- the work is handled for you.AddressableAudioLineProvider
has been removed.AudioLineProvider
now works with addressable assets, if the package is installed and your Yarn Project has been configured to use them.- You no longer specify a list of languages available to your project in the Preferences menu or in the project settings. This is now controlled from the Yarn Project.
- The
StartDialogue()
method (with no parameters) has been removed. Instead, provide a node name to start from when callingStartDialogue(nodeName)
.