GDYarn and Writing
Things are actually starting to come together, that’s so messed up.
GDYarn and the Process of Writing
I am an enthusiastic Designer of Systems. I love it. It’s so much fun. Love getting me some requirements and sitting down for a week to come up with a solution to them. Tickles my specific autism just right.
So a few weeks ago, when we started talking about making a really text heavy, dialogue and story focused game, that part of my brain started itching, and I started doing some very vague maths. Va11 Hall-A, a game that came up in conversation a lot at the time, has a little over 200k words in it. Open Sorcery is about 90k, Hades has 300k words of spoken dialogue (voice acted!!!), and Disco Elysium has over a million. None of these are actually fair comparisons to Blacksmith directly–we can’t possibly aim for the scale of the latter two, and the former are much more text focused than our game is–but as a scaling metric? We’ve basically signed up to write a small to medium sized novel, and that’s not even starting on the rest of the game.
What this meant to me, fundamentally, is that I needed to find a way for us to write that novel that would be natural, and fluent, and easy to work with. But at the same time, I wanted something that would be easy to handle at the other end as well–some format that I could plug into code and put on screen without too much hassle.
The way I would like to write dialogue looks something like this:
Blacksmith: Which one of you was going to tell me that tea tastes different if you put it in hot water?
Wizard: Y- you were putting it in *cold water?????*
Town Crier (frowning): **Blacksmith.** Answer the question, Blacksmith.
And then text wrapped in asterisks gets made bold, or italic, and other markdown options exist for other formatting. But it turns out Godot doesn’t really have a native way to read markdown formatting, so that wasn’t ideal, although I was tempted for a while to just write that conversion myself (and I possibly will, for other projects if not this one).
At the other end, the writing that is easiest to put into Godot directly looks like this:
dialogue = {
[ “Blacksmith”, “”, “Which one of you was going to tell me that tea tastes different if you put it in hot water?” ],
[ “Wizard”, “”, “Y- you were putting it in [i]cold water?????[/i]”],
[ “Town Crier”, “frowning”, [b]Blacksmith.[/b] Answer the question, Blacksmith.”]
}
And… can you imagine trying to write 90k words of dialogue like that? Or even 10k. Hell, writing that one conversation started annoying me. So I started looking for tools that would take something that looked like the first example, and convert it into something that looked like the second, and ended up with GDYarn.
Yarn is one of the dialogue systems that came up, and after reading into it more (and learning that someone I work with had used it before), it looked promising. Yarn works nicely as a bridge between written dialogue and a game system, parsing and serving lines one at a time when requested, and it supports a number of options for branching dialogue trees through the use of a connected storage object that presents data as a key:value dictionary. It only officially supports the Unity game engine, but GDYarn exists as an unofficial implementation for Godot.
So I can write conversation.yarn, which looks like:
Blacksmith: Which one of you was going to tell me that tea tastes different if you put it in hot water?
Wizard: Y- you were putting it in [i]cold water?????[/i]
Town Crier: [b]Blacksmith.[/b] Answer the question, Blacksmith.
And on the game engine side, I can set up a YarnRunner object and a YarnGUI object, and give one a link to the other, and give the latter a couple of links to textboxes to put text in, and then when I hit play:
YarnRunner: (to YarnGUI) next_line(“Blacksmith: Which one of you was going to tell me that tea tastes different if you put it in hot water?”)
YarnGUI: set_name_text(“Blacksmith”)
set_line_text(“Which one of you was going to tell me that tea tastes different if you put it in hot water?”)
And it just works.
Actually, it doesn’t, because at the time of writing GDYarn has a couple of bugs, but the main one was easy to fix. I’ve also been expanding the kinds of information we can set about a specific line, so actually the new and improved dialogue system (idk, Yarn+?) works like:
YarnRunner: (to YarnGUI) next_line(“Town Crier, right, frowning: [b]Blacksmith.[/b] Answer the question, Blacksmith.”)
YarnGUI: set_name_text(“Town Crier”)
set_image(character: Town Crier, side: right, emotion: frowning)
set_line_text(“[b]Blacksmith.[/b] Answer the question, Blacksmith.”)
And I think that’s all it needs to do for the moment. I have very little doubt I will need to come back to this and add more as the dialogue needs of the game develop, but that’s something to worry future me with.
What I’ve Been Working On
Not writing shorter blog posts, evidently, or even making sure I can reasonably fit everything into one.
As I mentioned last week, core game UI. Which is now in place, so over the next week I am implementing two new items into it. The first is a screen for talking to customers using the cool new dialogue system I have been going on about, and the second is a place to list the tasks, orders, and obligations that the player has so they don’t forget.