Our game, Signals, is a dialogue focused job simulator about working at a radio station during a time nearing climate apocalypse.
As a first time game dev, I wanted to use a dialogue system that I didn’t have to build from the ground up, but had built in capabilities to trigger functions in Unity. I saw that Yarn met that need with its Yarn Commands feature, so I started digging in. Since it took more online digging than I had expected to get this working the way I wanted it to, I thought I’d do a devlog about it so that it could potentially help others conceptualize some of these Yarn tools. For me, it’s easier to understand concepts when they’re being used in real world scenarios, so this type of devlog would have helped me during this development.
In Signals, the main character Carem has decided to strike up a job at a remote radio station in order to distract themselves from the impending climate apocalypse. In game, this interest is manifested as a “Distraction Meter.”
It is eventually revealed to the player that this Distraction Meter also affects the player’s ability to reach certain dialogue options when talking with npc’s in the game. Each special dialogue option has a Distraction Meter limit, and if the meter is over that limit, the option won’t be selectable. You might ask why we didn’t just use the Variable Storage feature of Yarn so that if the Distraction Meter is above the special dialogue choice’s limit, it wouldn’t be displayed at all. This was our first instinct, but we quickly realized that presenting the dialogue choice and not allowing the user to interact with it was a better way to reveal to the player that there is more to the game if they choose to focus on building relationships rather than focusing on the radio station. This builds on the game’s main theme (or rather, main question), how do you choose to spend your time in the face of inevitable death? By presenting the choice, we hope to make the player think about the choice and what it means in the scheme of things.
To achieve this effect we used Yarn Commands, which are typed directly into the dialogue scripts and parsed out by the Yarn Dialogue Runner to then trigger a function somewhere in our game code. Basically, just before a special option in dialogue, the writer must simply type a Yarn Command.
[[I’m kinda scared of them.|Scared]]
[[Hey, I'm kinda busy...|Busy]]
<<SpecialOption DialogueController 3>>
[[...How've you been, Dar?|Special]]
In order for that Yarn Command to mean anything, though, I have to do some work in the game code in Unity. This Yarn Command is made up of 2 sections, the name of the Yarn Command, the Unity GameObject that that holds the script that the Yarn Command is defined in. A third element is optional if you wish to pass a string parameter to the Yarn Command’s function.
Now that the writer has defined a dialogue option as a special one with the above Yarn Command, the game has to do something with it. That’s where the function attached to the Yarn Command comes in.
public void SpecialOption(string limit)
specialOption = true;
int setLimit = int.Parse(limit);
specialOptionLimit = setLimit;
These Yarn Commands can be used to do basically anything in game.
Another place that we used Yarn Commands in Signals was to affect how the dialogue bubbles animate. We wanted to add a small amount of flair to the dialogue bubbles that match the energy level of the NPC character at the given moment that they’re talking.
At the start of each branch from the NPC, the writer simply types a command like this:
<<Dar EnergyController High>>
Oh, not you Carem. I thought you were smart! There’s absolutely no reason to be afraid of roller coasters!!!
This Yarn Command starts with the name of the function (conveniently the character’s name), the GameObject that houses the script where the Yarn Command is defined, and a parameter string that defines the energy of the NPC.
public void DarEnergy(string choice)
darDialogue = GameObject.Find("Dar").GetComponentInChildren<NPCDialogueUI>();
darDialogue.npcEnergy = NPCDialogueUI.NPCEnergy.Normal;
darDialogue.npcEnergy = NPCDialogueUI.NPCEnergy.High;
A minor issue with this setup is that when this dialogue runs, the energy level is set while Yarn is telling Unity to start typing the dialogue. This is a problem, as the function itself is telling the dialogue bubble Animator information that it needs before it pops up, but where it sits now, it gets the information after it is already activated. My current workaround for this is a bit messy… and it is probably a tell for how much of a beginner I am.
Basically, my workaround is to make the Dialogue UI Handler wait for one of these NPC Energy Yarn Commands before animating ANY dialogue bubbles… The reason this is problematic is that the writer must remember to type one of these commands before each new branch of dialogue or else the Dialogue UI handler never types the next line. I know I could probably get the Dialogue UI Handler to pre-parse the dialogue before it gets typed in order to avoid this, but my abilities in such things are limited, and I want to keep moving. This works, and it hopefully isn’t too painful once we get into writing.
I hope this helps you out in some way! We hope to put out more devlogs like this as we get into the more exciting parts of development. I’ll be doing a video version on Twitch at En and Kurt’s Cozy Corner, so follow us and keep an eye out for more devlogs and streams!