Yarn Spinner 2.0 Beta 1 Release Notes
This document describes the important changes to Yarn Spinner 2.0, with particular focus on breaking changes.
Note! This is not the most recent version of Yarn Spinner; to see it, go to the releases list!
This is a little long, but it's important, so we really appreciate you taking the time to read it. And while you're here, please consider becoming a patron of the project, so that we can keep making Yarn Spinner the best it can be.
We are tremendously grateful to every single person who's contributed to version 2.0. We'd especially like to thank @Schroedingers-Cat, for helping to figure out the Dialogue Views and Localisation systems, and to @radiatoryang for contributing some fantastic sample projects.
Thank you!
❤️
The Yarn Spinner Team
🐛 This Beta Is Buggy; It's A Work In Progress; Please Tell Us About The Bugs So We Can Fix Them; Thank You
This is a beta version of Yarn Spinner 2.0. The majority of the important work has been done, but we have not finished working on it. There are almost certainly bugs in here that render this version not ready for use in your game. Additionally, future beta versions can and will change the language and API.
Beta documentation for the API is available at yarnspinner.dev/api/beta.
Please file bugs on this beta! We want to make it as solid and bug-free as we can, so if you encounter a problem, please file an issue.
🎬 The Most Important Parts
If you're in a hurry, we've prepared some videos that show you the most significant new changes in Yarn Spinner 2.0.
- Scripts must be added to a program, and you use that program with your Dialogue Runner.
- Variables must now be declared before they can be used.
- Localisation now involves creating localisation assets, and use them with a Dialogue Runner.
👩🚒 Getting Help
There are several places you can go to get help with the Yarn Spinner beta.
- Join the Yarn Spinner Discord.
- Tweet at us, at @YarnSpinnerTool, or use the #YS2beta hashtag.
- To report a bug, file an issue on GitHub.
📦 How To Install Yarn Spinner 2.0 Beta 1
The beta is available as a Unity package, using a Git URL. Additional download options will be available for the final release.
To install Yarn Spinner 2.0 Beta 1 into your Unity project, follow these steps:
- Open the Window menu, and choose Package Manager.
- If you already have 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-beta1
Each beta will have a different URL. To upgrade to future versions of the Yarn Spinner 2.0 beta, you will need to uninstall the package, and reinstall using the new URL.
🚨 Known Issues and Missing Features
- Documentation for Yarn Spinner 2.0 is not complete.
- API documentation is available, but not everything is described
- Articles and tutorial content have not yet been updated, and currently reflect the older Yarn Spinner 1.2 feature set.
- Unity:
- Several bugs exist in this release. You are strongly encouraged to review the list of known issues in the beta before installing the package.
- Beta 1 does not include the following features. These features will change the syntax of the language:
- Automated script upgrade tools are coming in future betas, but are not available in Beta 1.
🖍 The Yarn language syntax has changed
Syntax changes to the Yarn language itself mean that you will almost certainly find that your code no longer compiles like it did. This document outlines what those changes are, and what changes need to happen to your code to fix them.
In future beta versions of 2.0, we will be shipping tools that perform automated upgrades of your scripts. In this first beta, you'll need to upgrade your scripts manually.
📥 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 Program' asset, and this single asset is added to the Yarn Program field in your Dialogue Runner.
Individual .yarn
scripts are now combined into a single 'Yarn Program', which is what you provide to your DialogueRunner
. 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.
💁♂️ Variables must be declared
Version 2 of the Yarn language 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, 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.)
Examples
Line views are used in every sample that ships with Yarn Spinner 2.0. If you'd like to see them in action, take a look at these samples:
- Start Here: This sample makes use of two line views: one to display the text (
FadingLineView
), and one to present voice-over audio (VoiceOverPlaybackUnity
). - Visual Novel: This sample doesn't feature voice-over, but uses two line views as well: one to draw the text, and one to update a view that shows the currently speaking character's name.
🌏 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.
You then create a Localization Database, which 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).
Localization Databases 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. When you're done translating, select the Localization Database, and click Update. This will fill the Localization objects with the per-language data they need.
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.
Examples
The Space example is fully translated into English and German, in both text and audio. Take a look at its Dialogue Runner, and the Line Provider it uses.
🌠 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.
Examples
The Visual Novel example makes extensive use of commands. Take a look at the VNManager
class, which registers the commands in its Awake
method.
🎨 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" /]
📄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.
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.
Removed
- 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.