GodYarnIt is a port of Kyperbelt's GDYarn to Godot 4. It allows you to create interactive dialogues using a simple markup language with strong similarities to twine. It is easy enough to get, but powerful enough to take your games to the next level with branching narratives that can change based on user interactions.
GodYarnIt, like GDYarn, is a reconstruction of YarnSpinner completely written in GDScript. The project aims to be as feature complete as possible compared to the C# version but may forgo certain things in lieu of similar alternatives that make it blend better with the Godot ecosystem.
This port not only includes code fixes (GDScript saw many changes in Godot 4), but also major code documentation as well as some re-naming done to some classes, methods and variables. When I began working on the port, I noticed that there are some bugs that needed me to dig deeper into the code (especially the one where the wait command doesn't work correctly, as also pointed out in BreadcrumpIsTaken's fork - that one's fixed on here btw). This was a huge hassle, however, because the original code wasn't well-documented, didn't always stick to the GDScript Style Guide and often didn't use any type-hints or insightful and consistent class/method/variable names. Hence, I decided to go the long way and gave the code a big face-lift and extensive documentation. While I don't know for sure whether I will keep working on this repository long-term, the main goal of this fork (besides making it functional for Godot 4) is to make the original code more intuitive to use so that if Kyperbelt or anyone else wants to expand on it further, they don't need to spend weeks trying to understand every script to fix a bug or implement a new feature.
- Compatibility with Godot 4 (incl. port bug fixes)
- Compile multiple Yarn files into a single Program
- Inline Expressions
{3 * $variable + foo()}
- Format Functions
[func {$value} args...]
(select, plural, ordinal) - Pluralisation
- Persistent Variable Storage (currently can only be done manually)
- Custom Commands (implemented already, but cumbersome to use)
- Function Library Extensions (WIP)
- Option Links
[[OptionalText | TargetNode]]
(deprecated for Yarn 2.0, might get removed) - Shortcut Options
->
- Localisation (WIP)
- if/elseif/else Statements
<<if ...>>
- set command
<<set $var = 5>>
- wait command
<<wait 4>>
- support for BBCode
[b]bold[/b]
(must use RichTextLabel) - Header info processing
- Yarn 2.0+ functionalities like jumps
<<jump TargetNode>>
or variable declarations<<declare $value = true as bool>>
Go to the folder where you want to download this project to and clone it using your preferred method.
The files expect the following file path within your project: res://addons/godyarnit/
. If you'd like to drop them somewhere else, press Ctrl+Shift+R when you're in the Godot editor. This will open up a replacement prompt. Enter res://addons/godyarnit/
as your search term and the relative path to the new directory as the replacement term (you can get that path by right-clicking the directory in the editor and selecting Copy Path
). Select the folder into which you've dropped the files as your search region in the prompt. When you hit Replace
, all the file paths will be adjusted to your new location. You'll probably have to reload the editor, but afterwards you should be good!
For more information regarding this process checkout the official Godot Documentation regarding plugin installation.
Make sure the plugin directory is located in res://addons/
(case-sensitive!). If not, you will need to adjust dozens of file paths (Ctrl+Shift+F
, search GodYarnIt's directory, replace all affected paths).
Enable the plugin by going to Project > Project Settings > Plugins
and ticking GodYarnIt's checkbox.
Checkout the official Yarnspinner Tutorial page to get started writing interactive narratives! Read the introduction pages up until you hit the Unity stuff (we don't need that since we are not working in Unity). Also make sure to checkout the syntax Reference for a comprehensive list of the yarn languages capabilities.
⚠️ Some core functionalities (notably those of Yarn 2.0+) are still missing (please report any issues).
Yarn files are simple text files that are written in using the Yarn Language Syntax and can be created in the following ways:
- Web Yarn Editor for more information go (here).
- VS Code with the YarnSpinner Extension
- Any Text Editor (They are just plain text files!)
In order to start using Yarn Dialogues in your games you require the following things:
The Variable Storage node is one of the many ways that your dialogues can interact with your game. It is in charge of storing the values that your dialogues use at runtime and can be also accessed through certain script function calls like set_value(name,value)
and get_value(name)
.
At least one Variable Storage node must be added to your scene hierarchy in order to run yarn programs using the Yarn Runner. It can be found in the Create Node Popup in the Godot Editor.
-
Signals:
value_set(valName)
: emitted when a value is set. Passes in the name of the value.
This is a Resource that contains a collection of yarn script files. On its own its really not that crucial but when combined with the Yarn Runner, it allows you to combine multiple yarn scripts into a single program.
This Resource is available in the Resource drop down and can be created when adding a new resource to the Yarn Runner.
-
Properties:
- Compiled Program Name : This is the name of the Yarn Program once it is compiled.
- Compiled Program Directory: This is the directory to which you want to save the Compiled Yarn Program.
- Yarn Program Paths: This is an array of paths to
.yarn
files to be combined and compiled into a single Yarn Program. Note that they must not have any conflicting node names as this will generate an error at compile time.
The bread and butter of this whole thing. It communicates with the scripts running the Yarn Program and turns their states and outputs into useful signals and methods for UI elements. Although it would not be impossible to run Yarn Programs (compiled Yarn Dialogues) without this node, it would certainly be difficult. WAIT! Before we hit the big shiny Compile Button, let's first get to know some things about the Yarn Runner.
-
Properties:
- Start Node Title: This is the title of the Yarn Node that runs when you start the runner. This refers to the nodes in the YarnSpinner narrative script, it does not have anything to do with nodes inside Godot.
- Should Auto Start: If this is enabled, the Yarn Runner will automatically start the dialogue as soon as it enters the tree. This is fine for testing or for other specific test cases, but for the most part you will want to start the runner externally through its
start
function. - Variable Storage: The Variable Storage node that you will be using for this runner.
- Compiled Yarn Program: as Explained above, this is the resource that contains information about the program.
Right now the only way to compile and run Yarn scripts is through the Yarn Runner node. Before you can touch the compile button you must first add a Compiled Yarn Program Resource to the Yarn Runner through the Inspector.
Once it's added you can expand it, edit its various properties and add all the scripts that you want to compile. Then hit compile, and if all went well, there will be no errors displayed. Instead you will get compilation success messages! Woooo!
Set your start node title, and add a variable storage and you are ready to move on to the next step.
-
Signals:
dialogue_started
: Emitted when the dialogue has been started.next_line_prepared(prepared_line: String)
: Emitted when the runner has prepared a new line to display.prepared_line
contains that line.command_triggered(command: String, arguments: Array[String])
: Emitted when a command is being handled by the runner. Thecommand
and an array of itsarguments
are passed.options_prepared(prepared_options: Array[String])
: Emitted when options (either Shortcut Options or Dialogue Link Options) are handled by the runner.prepared_options
contains the displayed text of each option.dialogue_finished
: Emitted when the dialogue has finished.resumed
: Emitted whenresume
is called on the YarnRunnernode_started(node_name: String)
: Emitted when a new node has started running.node_name
is the title of that node.node_complete(node_name: String)
: Emitted when a node has finished running.node_name
is the title of that node.
If the Yarn Runner was the bread and butter, then a GUI is the plate you serve it on. To create a GUI for displaying Yarn Dialogues, you need a reference to a Yarn Runner node and mainly listen to the signals it outputs to receive the text that should be displayed.
GodYarnIt, like GDYarn, comes with a default GUI implementation which will be explained here. But just know that you are not forced to use the provided implementation and are more than encouraged to create your own if your use-case requires it.
-
Properties:
- Yarn Runner Path: The runner that this GUI will be listening to.
- Text Display Path: The text node that this GUI will feed lines to. Note that the only requirement of the node is that it has a
set_text(text)
function, but it is highly recommended that you use the built in Godot controls for displaying text like Label and RichTextLabel. - Name Plate Display Path: This is another text label node, that when present, will look for lines with the pattern
"<name>: <line content>"
and split them at the:
. The name will be fed to the nameplate and the line content to the Text. - Option Display Paths: An array of label nodes that will be used for displaying options (Shortcut Options or Dialogue Link Options). You can add as many as you will need (usually you should put as many as the most options that will be displayed to the user at any single time). Options nodes will be made invisible when not in use. If you use a button control, it will be automatically connected to a handler method.
- Text Speed: This is the speed at which text is displayed in characters per second. If
<= 0
, then lines will be displayed instantly.
The only requirements for the GUI display is that you call its
finish_line()
function when you want to call the next line (or close it when there is no lines left). This can be done through a script, or you can hook up a button pressed signal to it.As you can see, this GUI implementation makes no requirement for visual style - that part is entirely up to you!
The node structure of your Yarn Display will probably look like this:
- YarnGUI
- TextDisplay
- NameDisplay
- OptionsDisplays (plain control node)
- OptionDisplay0
- OptionDisplay1
- ...
- YarnRunner
- VariableStorage
-
Signals:
text_changed
: Emitted every time the text for the text display changes.line_started
: Emitted every time that a new line is received.line_finished
: Emitted every time a line finishes displaying.options_shown
: Emitted when a set of options is displayed.option_selected
: Emitted when an option selection has been made.gui_shown
: Emitted whenshow_gui()
is called.gui_hidden
: Emitted whenhide_gui()
is called.