This repository has been archived on 2024-02-25. You can view files and clone it, but cannot push or open issues or pull requests.
Go to file
2022-05-16 08:44:20 +02:00
addons/Wol chore: upped version to alpha3 2022-01-10 10:08:42 +01:00
ExampleDialogue feat: added a bunch of features 2021-12-09 18:43:03 +01:00
.gitattributes made several fixes and started work on editor 2021-12-06 17:31:55 +01:00
.gitignore feat: added colors and protagonist to preview 2021-12-08 20:29:52 +01:00
change-version.sh chore: upped version to alpha3 2022-01-10 10:08:42 +01:00
default_env.tres first commit 2021-11-20 11:10:20 +01:00
Dialogue.gd feat: added example + tutorial 2021-11-27 22:05:24 +01:00
Dialogue.tscn wip: started working on tutorial & relevant files 2021-11-27 18:02:47 +01:00
dialogue.wol feat: made a bunch of changes for a web version 2021-12-12 13:12:29 +01:00
export_presets.cfg chore: upped version to alpha3 2022-01-10 10:08:42 +01:00
LICENSE.md Added LICENSE 2021-11-25 21:55:15 +01:00
project.godot feat: made a bunch of changes for a web version 2021-12-12 13:12:29 +01:00
README.md Removed "actively" from README 2022-05-16 08:44:20 +02:00
TestScene.tscn capitalised some files 2021-12-06 17:42:27 +01:00

The friendly tool for writing game dialogue, in and for Godot

Getting Started | Documentation | Tutorial | Web Editor | Follow me 🐦!


Wol is a tool for creating interactive dialogue for games. Its based on YarnSpinner and it's Yarn language. (currently under heavy development, very unstable, do not use for production)

Write your conversations in Yarn, a simple programming language that's designed to be easy for writers to learn, while also powerful enough to handle whatever you need.

Yarn's similar in style to Twine, so if you already know that, you'll be right at home! If you don't, that's cool - Yarn's syntax is extremely minimal, and there's not much there to learn.

Wol is maintained by Bram Dingelstad, if you need a programmer or designer for your next (Godot) project, you can hire him!

Getting Started

This repo contains the code for the Wol nodes & Yarn compiler. If you want to use it in a game engine other than Godot, you should get the appropriate package for your game engine. Check out YarnSpinner-Unity for a Unity version of this project.

Download from AssetLib

Unfortunately, this option isn't available yet. Stay tuned!

Clone this repository / download the zip

  1. Extract the repository in a folder of your choice.
  2. Import the project in Godot.
  3. Run the scene to get a taste of Wol!
  4. Move the addons folder to your Godot project.
  5. Enable the plugin in your Project Settings.
  6. Setup the Wol node using the documentation or tutorial!

Roadmap

There are few things that need to be ironed out to be 100% feature compatible with the original YarnSpinner.

  • Integration with Godot's translation/localization system.
    • Auto generation for #line: suffixes
  • Support for format functions.
  • ~Support~ Fix for conditional options.
  • In-editor dialogue editor with preview.
    • Lines connecting different nodes if they refer to eachother.
    • Error hints when doing something wrong.
    • Basic saving, opening and saving-as.
  • Remove all printerr in favor of (soft) asserts.
  • Fully extend the documentation of this project.
  • Porting to usable signals in Godot.
  • Providing helpful errors when failing to compile.
  • Having a working repository with example code.

On request

If for whatever reason a lot of people want more documentation or certain features, here's some additional stuff I'll do:

  • Write a more advanced "Custom Wol Node" tutorial.
  • Perhaps write a little bit about the internals 🤷 (?).

Getting Help

There are several places to get help with Wol, and stay up to date with what's happening.

  • Follow me on Twitter or @ me!
  • Open an issue on Github!
  • Email bram [at] dingelstad.works for more indepth questions or inqueries for consultancy. You can also email me to hire me for all your Godot needs!

License

Wol is available under the MIT License. This means that you can use it in any commercial or noncommercial project. The only requirement is that you need to include attribution in your game's docs. A credit would be very, very nice, too, but isn't required. If you'd like to know more about what this license lets you do, tldrlegal.com have a very nice write up about the MIT license that you might find useful.

Made by Bram Dingelstad, kyperbelt & Secret Lab

Yarn Spinner was originally created by Secret Lab, an Australian game dev studio. Say hi to them for me!!

Started on Godot by kyperbelt (thank you so much for the initial work!) and completed by Bram Dingelstad. Say hi to me as well!

Help Me Make Wol & Secret Lab's Yarn Spinner!

Wol & Yarn Spinner needs your help to be as awesome as it can be! You don't have to be a coder to help out - we'd love to have your help in improving this or YarnSpinner's documentation, in spreading the word, and in finding bugs.

Tutorial

Welcome to Wol! In this tutorial, youll learn how to use Wol in a Godot project to create interactive dialogue.

Well start by downloading and installing Wol. Well then take a look at the core concepts that power Wol / Yarn, and write some dialogue. After that, well explore some of the more advanced features of Wol & Yarn.

Introducing Wol

Wol & Yarn (Spinner) are tools for writing interactive dialogue in games - that is, conversations that the player can have with characters in the game. Yarn Spinner does this by letting you write your dialogue in a programming language called Yarn.

Yarn is designed to be as minimal as possible. For example, the following is valid Yarn code:

Gregg: I think I might be sick.
Mae: True friendship: Letting your friend make you sick.
Gregg: True bros.
Mae: True bros.

Wol will take each line, one at a time, and deliver them to the game. Its entirely up to the game to decide what to do with the lines; for example, the game that these lines are from, Night in the Woods, displays them in speech bubbles, one character at a time, and waits for the user to press a button before showing the next one.

Quick Start

Well begin by playing the example game that comes with Wol. Its very short - about 2 minutes long. After that we'll make some small changes!

  1. Create a new empty Godot project.
  2. Download and install Wol. Go to the Getting started section, and follow the directions there.
  3. Open the example scene (res://ExampleDialogue/ExampleScene.tscn).
  4. Play the game. Use the left and right arrow keys to move, and the enter key to talk to characters.

Were now ready to start looking under the hood, to see how Wol & Yarn power this game.

The Wol Editor

Wol & Yarn Spinner stores its dialogue in .yarn (or .wol) files. These are plain text files, which means you can edit them in any plain text editor (Visual Studio Code is a good option, and Secret Labs offers a syntax highlighting extension to make it nice to use!)

You can also use the Wol Editor, which is a tool in the Godot editor for working with Yarn code. This editor is useful because it lets you view the structure of your dialogue in a very visual way. (This is not completed yet however)

Reading Yarn

In this section of the tutorial, were going to open the file Sally.yarn, and look at what its doing.

Open Sally.yarn in your editor of choice.

Wol & Yarn groups all of its dialogue into nodes. Nodes contain everything: your lines of dialogue, the choices you show to the player, and the commands that you send to the game. The Sally.yarn file contains four of them: Sally, Sally.Watch, Sally.Exit, and Sally.Sorry. The example game is set up so that when you walk up to Sally and press the spacebar, the game will start running the Sally node.

Go to the Sally node.

Lets take a look at what that node contains. Heres the entire text of it:

<<if visited("Sally") is false>>
    Player: Hey, Sally. #line:794945
    Sally: Oh! Hi. #line:2dc39b
    Sally: You snuck up on me. #line:34de2f
    Sally: Don't do that. #line:dcc2bc
<<else>>
    Player: Hey. #line:a8e70c
    Sally: Hi. #line:305cde
<<endif>>

<<if not visited("Sally.Watch")>>
    [[Anything exciting happen on your watch?|Sally.Watch]] #line:5d7a7c
<<endif>>

<<if $sally_warning and not visited("Sally.Sorry")>>
    [[Sorry about the console.|Sally.Sorry]] #line:0a7e39
<<endif>>
[[See you later.|Sally.Exit]] #line:0facf7

Take a second now to look at this code, and get a feel for its structure.

Lines and Logic

Well now take a closer look at each part of this code, and explain whats going on.

<<if visited("Sally") is false>>
    Player: Hey, Sally. #line:794945
    Sally: Oh! Hi. #line:2dc39b
    Sally: You snuck up on me. #line:34de2f
    Sally: Don't do that. #line:dcc2bc
<<else>>
    Player: Hey. #line:a8e70c
    Sally: Hi. #line:305cde
<<endif>>

The first line of code in this node checks to see if Wol has already run this node. visited is a function that is built into Wol. It returns true if the node you specify has been run before. Youll notice that this line is wrapped in << and >> symbols. This tells Wol that its control code, and not meant to be shown to the player.

If they havent run the Sally node yet, it means that this is the first time that weve spoken to Sally in this game. As a result, we run lines in which Sally and the player character meet. Otherwise, we instead run some shorter lines. Each line in Wol is just a run of text, which is sent directly to the game. Its up to the game to decide how it wants to display it; in the example game, its shown at the top of the screen.

At the end of each line, youll see a #line: tag. This tag lets Wol identify lines across multiple translations, and is optional if you arent translating your game into other languages. Wol can automatically generate them for you (not supported yet however).

Options

Heres the next part of the code.

<<if not visited("Sally.Watch")>>
    [[Anything exciting happen on your watch?|Sally.Watch]] #line:5d7a7c
<<endif>>

<<if $sally_warning and not visited("Sally.Sorry")>>
    [[Sorry about the console.|Sally.Sorry]] #line:0a7e39
<<endif>>

In the next part of the code, we do a check, and if it passes, we add an option. Options are things that the player can select; in this game, theyre things the player can say, but like lines, its up to the game to decide what to do with them. Options are shown to the player when the end of a node is reached.

The first couple of lines here test to see whether the player has run the node Sally.Watch. If they havent, then the code adds a new option. Options are wrapped with [[ and ]]. The text before the | is shown to the player, and the text after is the name of the node that will be run if the player chooses the option. Like lines, options can have line tags for localisation.

If the player has run the Sally.Watch node before, this code wont be run, which means that the option to run it again wont appear.

The rest of this part does a similar thing as the first: it does a check, and adds another option if the check passes. In this case, it checks to see if the variable $sally_warning is true, and if the player has not yet run the Sally.Sorry node. $sally_warning is set in a different node - its in the node Ship, which is stored in the file Ship.yarn.

[[See you later.|Sally.Exit]] #line:0facf7

The very last line of the node adds an option, which takes the player to the Sally.Exit line. Because this option isnt inside an if statement, its always added.

When Wol hits the end of the node, all of the options that have been accumulated so far will be shown to the player. Wol will then wait for the player to make a selection, and then start running the node that they selected.

And thats how the node works!

Writing Some Dialogue

Lets write some dialogue! Well add a couple of lines to the Ship.

Open the file Ship.yarn. It contains a single node, called Ship - go to it.

This code uses couple of features that we didnt see in Sally: commands, and variables.

Commands

Commands are messages that Wol sends to your game, but arent intended to be shown to the player. Commands let you control things in your scene, like moving the camera around, or instructing a character to move to another point.

Because every game is different, Wol leaves the task of defining most commands to you. Wol defines two built-in commands: wait, which pauses the dialogue for a certain number of seconds, and stop, which ends the dialogue immediately.

The example game defines its own command, setsprite, which is used to change the sprite that the Ship characters face is displaying. You can see this in action in the file Ship.yarn:

Player: How's space?
Ship: Oh, man.
<<setsprite ShipFace happy>>
Ship: It's HUGE!
<<setsprite ShipFace neutral>>

Variables

Variables are how you store information about what the player has done in the game. We saw variables in use in the Sally node, where the variable $sally_warning was used to control whether some content was shown or not. This variable is set in here, in the Ship node - it represents whether or not the player has heard Sallys warning about the console from the Ship.

Variables in Wol start with a $, and can store text, numbers, booleans (true or false values), or null. If you try and access a variable that hasnt been set, youll get the value null, which represents “no value”. Adding Some Content

Add some new dialogue. Add the following text to the end of the node:

Ship: Anything else I can help with?

-> No, thanks.
    Ship: Aw, ok!
-> I'm good.
    Ship: Let me know!

Ship: Bye!

Shortcut Options

The -> items that we just added are called shortcut options. Shortcut options let you put choices in your node without having to create new nodes, which you link to through the [[Option]] syntax. They exist in-line with the rest of your node.

To use a shortcut option, you write a ->, followed by the text that you want to display. Then, on the next lines, indent the code a few spaces (it doesnt matter how many, as long as youre consistent.) The indented lines will run if the option theyre attached to is selected. Shortcut options can be nested, which means you can put a group of shortcut options inside another. You can put any kind of code inside a shortcut options lines.

Because shortcut options dont require you to create new nodes, theyre really good for situations where you want to offer the player some kind of choice that doesnt significantly change the flow of the story.

Save the file, and go back to the game. Play the game again, and talk to the Ship. At the end of the conversation, youll see new dialogue.

Where Next

The example game is set up so that when you talk to Sally, the node Sally is run, and when you talk to the Ship, the node Ship is run. With this in mind, change the story so that after you get told off by Sally, she asks you to go and fix a problem with the Ship.

You can also read the Syntax Reference for Yarn.

Documentation

Wol

Inherits from Node

Node for all interaction with Wol.

Description

Godot's Nodes as building blocks work really well. That's why this plugin gives you access to a simple node that does all the heavy lifting for you. It has several properties that you can change either in-editor or using GDScript (or any other compatible language) and signals you can use to listen to events coming from your dialogue.

Properties

Type Property Default value
String path ''
String starting_node 'Start'
bool auto_start false
bool auto_show_options false
bool auto_substitute true
Dictionary variable_storage {}

Methods

Return value Method name
void start ( String starting_node = 'Start' )
void pause ( )
void resume ( )
void select_option ( int id )

Signals

  • started ( )

    Emitted when the dialogue is started.

  • finished ( )

    Emitted when the dialogue is came to a stop, either through running out of dialogue or by using the <<stop>> command.

  • node_started ( String node )

    Emitted when a dialogue node is started. Has the node name as a parameter so you can see which node was started.

  • node_finished ( String node )

    Emitted when a dialogue node is started. Has the node name as a parameter so you can see which node was started.

  • line ( Line line )

    Emitted when a Line is emitted from the dialogue. line holds relevant information.

  • options ( Array options )

    Emitted when the dialogue runs into a set of options. Is emitted with an Array of Options.

  • command ( String command )

    Emitted when the dialogue executes a command. Use this signal to provide interactivity with your game world.

Property Descriptions

  • String path

    Default ''

    The path to your .yarn or .wol file. Must be a valid Yarn file otherwise the compiler will throw an error.

  • String starting_node

    Default 'Start'

    The node that is the starting point of the dialogue. Will automatically be the default for the start() function as well. The string should be a valid name for a Yarn node and be available in the file or an error will be thrown. You can always start from a different node by calling start('OtherStartingNode') for instance.

  • bool auto_start

    Default false

    If enabled, will automatically start the dialogue using the starting_node as the entrypoint.

  • bool auto_show_options

    Default false

    If enabled, will automatically show you options when they're available, rather than waiting for the player to resume to the line that has options.

  • bool auto_substitude

    Default false

    If enabled, will automatically substitute format functions and inline expressions for you. It's recommended to leave enabled, but if you want to manually do this for whatever reason, you can turn it off.

  • Dictionary variable_storage

    Default {}

    A Dictionary that holds all of the variables of your of your dialogue. All of the entries of this dictionary are accesible in your dialogue with a $ prefix. (e.g a_variable would be $a_variable). If you set a variable from within your dialogue, this dictionary will also be updated.

    In the future there'll be a signal added for when the variable_storage is updated.

Method Descriptions

  • start ( String starting_node = 'Start')

    Starts the dialogue at the starting_node (defaults to the value of self.starting_node which is Start) When the dialogue comes to a full stop through reaching the end or reaching a <<stop> command, you need to explicitly call this function instead of resume ( ).

  • pause ( )

    Pauses the dialogue until resume ( ) is called.

  • resume ( )

    Resumes the dialogue. Won't work when the dialogue comes to a full stop by reaching the end or reaching a <<stop>> command. You need to call start ( starting_node ) instead.

  • select_option ( int id )

    When getting an option from the options signal, use this function to let Wol node which option you want to select. Use Option.id for the id parameter.

Line

Inherits from Object

An object holding all information related to a line in your dialogue.

Description

The Line object is the object that you're gonna be interacting with the most. This object holds all of the information of the actual lines of dialogue. The most important property is text, but it has some additional properties you can make use of for debugging or holding of metadata (no support for that yet however).

Properties

Type Property
String text
String node_name
String file_name
Array substitutions
Array meta

Property Descriptions

  • String text

    A line of dialogue that's been processed by Wol. You can use this to set a Label in a text bubble above your character, add to a RichTextLabel for more dynamic stuff (Wol fully supports bbcode). Look at this repository's Dialogue.tscn and Dialogue.gd for some inspiration ;)

  • String node_name

    The name of the dialogue node this piece of dialogue came from.

  • String file_name

    The filename of the file where this piece of dialogue came from.

  • Array substitutions

    An Array of Strings that the result of Wol proccessing statements. Use this array if you disabled auto_substitutions and want to manually substitute your dialogue.

  • Array meta

    Currently unimplemented.

Option

Inherits from Object

An object holding information of an option in your dialogue.

Description

The Option object is anoter object that you're gonna be interacting with a lot. This object holds the information of a choice in your dialogue. It has a reference to a Line with it's line property so you can show the appropriate text to your player!

Properties

Type Property
int id
Line line
String destination

Property Descriptions

  • int id

    A unique identifier that you can use to communicate your option choice with select_option ( id ).

  • Line line

    A line of dialogue that's been processed by Wol. See Line for more details.

  • String destination

    The node that you will jump to when this option is selected. (Only relevant for jump questions, not inline ones).