Sunday, January 16, 2022

Darner's Digest, vol. 3: on the Yarn Spinner v2.0 release + a YS primer

Darner's Digest is a series of blog posts about Yarn Spinner, a free open source Unity dialogue tree plugin.

On December 21st, 2021, the Yarn Spinner project finally made its public YS v2.0 for Unity release

YS 2.0 has gone through six (6!) preview versions / betas over the last few years, with several debates and redesigns that have finally culminated in this version. If you're familiar with Yarn Spinner already, you should go read the changelog for upgrade notes from v1.0 to v2.0.

But a lot about YS and its ecosystem have changed, so it's probably helpful to recap what's going on.

1. What is Yarn Spinner in 2022?
2. When to use Yarn Spinner
3. How to use Yarn Spinner
4. Current Strengths / Weaknesses
5. The Future



WHAT IS YARN SPINNER IN 2022

The Yarn Spinner project is made of two main parts, which can be confusing:

  • Yarn Spinner "Core", generic dialogue engine processor thing ("virtual machine") + script compiler written in C#. None of it is Unity specific. 
    • related: Yarn "language" spec, a programming specification / standard for how Yarn should operate in any game engine
  • Yarn Spinner Unity plugs the core into Unity and adds a convenient wrapper. You will need to mod this and personalize it for your unique game project.
    • there are decent updated ports for Gamemaker Studio 2, Godot, JavaScript (linked at the end of this post)
Yarn is inspired by Twine. It is meant to be simple and easy for writers:
// one line at a time, pattern is {CharacterName}:{Dialogue}
Alice: Hello, I'm a game character named Alice!
Bob: And I'm Bob!

// use "->" and indents for branching choices
-> Alice is cool (choice 1)
    Alice: Thanks, I know I'm cool.
-> Bob is weird (choice 2)
    Bob: I'm not that weird, am I?
    Alice: No comment.
But it's also meant to be very extensible for game developers:
// custom command example: "ChangeShoes" calls Unity C# game code to swap the character's shoe sprites
<<ChangeShoes Alice ChaChaHeels>>
Bob: Wow Alice, I love those cha cha heels!

// custom markup example: "[g]" hooks into Unity C# to make certain text glow and jiggle in-game
Alice: I dance like I am [g]possessed by a ghost[/g]...

Some games do all their cutscene scripting and even enemy AI in Yarn Spinner, because really, it's just a simple scripting language that does whatever you tell it to do. Nothing stops you from adding more commands, functions, markup tags, or new ways to process the script.

// custom NPC AI script example?
<<if GetHealth("Player") > 50>>
<<RunAway 10.0>>
<<else>>
<<Attack "Player">>
<<endif>>

WHEN TO USE YARN SPINNER

The two most famous Yarn Spinner projects are Night In The Woods and A Short Hike. Both of those famous games are very typical video game RPG style things where you walk around a world and talk to NPCs, one at a time. And so this is the ideal use case for Yarn Spinner: action adventure games starring existential millennial animal protagonists.

There are three other common choices for game dialogue in Unity:

Ink is a popular free open source project by Inkle Studios. Their games (80 Days, Heaven's Vault) make heavy use of dynamic text and procedural generation, great for throwing paragraphs of text at the player. If your project goes beyond typical game dev needs, or does lots of experimental stuff with text or proc gen, or dips its toes into interactive fiction, then Ink is probably a better choice.

Fungus is another common free open source project, which prioritizes a visual node workflow and lots of built-in examples. Like any other visual node workflow, it seems nice and convenient at first, but once you have 1000+ words across multiple scripts, this workflow scales poorly and feels cumbersome. It is great for Unity beginners, or for small jams / prototypes with light dialogue requirements. However, it isn't in active development anymore, and maintenance since 2021 will be a bit spotty.

Dialogue System is an all-in-one node-based visual editor in Unity asset with ready-made samples for Mass Effect / Skyrim style dialogues. It seems fine and people have used it successfully (Disco Elysium? really?) but if you do decide to buy it, then (in my opinion) you should avoid the cumbersome visual node editor workflow and rely more on the text file importers.

So to review, here's my advice for Unity devs making games with dialogue:
  • know a good amount of Unity coding + making a typical gamey game with occasional conversations? try Yarn Spinner
  • know a good amount of Unity coding Unity coding + making a big text-rich interactive fiction-y thing with paragraphs of text, or need heavy proc gen power? try Ink
  • know very little Unity coding + making a small game? try Fungus
  • have money to spare + lots of other Unity assets you need to hook into? maybe buy Dialogue System
Q: How do I know if I'm experienced enough with Unity to make good use of YS?

A: Can you imagine 3+ different ways to architect a dialogue system for Unity? Can you name 3+ specific problems with the Unity UI system? 
  • If yes to both (or "mostly yes") then I'd say you are experienced enough to get good use out of Yarn Spinner. 
  • If you can't answer those questions, then you might have a bad time with YS
Additionally, for any teams using source control, Yarn and Ink's text formats mean the scripts are easily diff-able and hand-edited.

HOW TO USE YARN SPINNER

A lot has changed since Yarn Spinner v1.0. Before I would've recommended my Unity editor plugin Merino, or the semi-official Yarn Editor. However, I've since abandoned my editor, and the semi-official editor feels a bit bloated and slow to me. I wouldn't recommend either anymore.

So my new 2021 recommended Yarn Spinner Unity workflow for writers is now this: Write Yarn dialogue in VS Code. You'll want these two extensions --
  • Yarn Spinner Extension: adds basic syntax highlighting and visual node graph
  • Yarn Spinner Language Server: adds find references (!) and autocomplete (+ automatically grabs comments + overloads from Unity C#!!!) and highlights any compile errors... feels like the fuckin future, basically amazing
VS Code is a solid writing interface: a big textbox that gets out of your way. Add the language server functionality and now writers have built-in autocomplete and help too.
Yarn syntax is, by design, simpler and more limited than most programming languages:
  • Put dialogue in a .yarn text file (with UTF-8 encoding.)
  • All dialogue must be in a node; nodes start with a title header, then --- to begin node content, and === to end the node.
  • There's  Dialogue Text, ->Choices, $Variables, <<Commands>>, Functions(), [Markup], and #LineTags
    • Variables are static typed and can be bool, int, float, or string
    • Commands call one shot C# functions or manipulate variables / flow control (e.g. <<set $apples to 3>>)
    • Functions call static C# functions and return data back into Yarn Spinner (e.g. <<if dice() == 6>> could return a random number Dice() function from C#)
    • Markup lets writers expose substrings to C# (e.g. I am very [b]hungry[/b] could convert the word "hungry" to bold text when you display it in-game)
    • Line Tags are hashtags that go at the end of a line, so you can localize or attach voice over to that line later. (e.g. Hello #line:85 could link to row 85 in your localization spreadsheet, and so the file French.csv line 85 would read "Bonjour" and the game could also play "/VoiceOver/French/85.wav")
Make sure to read the overhauled YS v2.0 documentation! There's also two comprehensive sample Unity tutorials, a simple example and a more complex example.

CURRENT STRENGTHS / WEAKNESSES

Strengths:
  • medium-weight dialogue framework that does all the hard "backend" stuff (virtual machine, scripting language, compiling, tooling, localization and asset linking) and then gets out of your way so you can make your own UI and game logic
  • free and open source, in active development
  • simple writer-friendly scripting language
    • very extensible with Unity C# and VS Code tooling (auto complete!!!)
  • static typed / static compiled, flag errors at editor time
  • human-readable text-based file format
Weaknesses:
  • not a turn-key beginner framework, you need to be somewhat experienced with Unity already
  • Yarn language, by design, avoids some code constructs (e.g. no while() or for() loops) that some complex games may need
  • most code samples in the google results will be for the old v1.0 API and it'll confuse you when the code doesn't work in v2.0+ ... as a general rule, if the Yarn tutorial or resource is dated from 2020 or before, then it's probably obsolete.
  • very difficult / impossible to save and load the dialogue state in the middle of a dialogue node. That is: when you implement save states in your game, you'll only be able to load back to the start of the current node -- NOT the exact line and VM state. Smart people are currently working on better save support, but the "vm state save" feature is still a while away.

THE FUTURE

  • People are porting the Yarn spec to other game engines and languages
    • the JS port "bondage.js" has a great new fork + wrapper "YarnBound" updated for v2.0!
    • the GameMaker Studio 2 port and Godot ports are particularly far along
    • there's an official C++ port / Unreal Engine port in the works, but it's complicated so it'll take a while
  • The core maintainers of Yarn Spinner have multiple sponsors to support continued development, so it'll still probably see some solid upgrades / improvements in the future. This isn't a small dead thing.
  • Again, if you want to use Yarn Spinner in your project, you should join the Yarn Spinner Discord for help and questions