Spin is a simple library for dialogue trees. It includes a human-readable file format for dialogue trees, and an interpreter for that format.
The reference interpreter is in C# and should work anywhere C# 7 can be used.
Inspired by Yarn, with a focus on easily editing files without having a dedicated editor.
Available on NuGet
- Integration Guide - start here if you want to integrate Spin into your game!
- Spin Language API
# Example Document
> begin hello1
+hello1
Hello, world! This is a quick example of a dialogue system.
+> next hello2
+hello2
This is another piece of dialogue.
+
> opt "Option 1" hello3
> opt "Option 2" hello4
+hello3
You picked option 1!
+
+hello4
You picked option 2!
+
Note: opt
is not a built-in command. Spin lets you define your own commands, and here we assume opt
defines an option for a piece of dialogue.
A more complex example can be found at SpinExample/sequences/example.ths.
- line / dialogue line: A single unit of dialogue. Everything between each set of
+
is a singular line. - document: A file containing dialogue data.
- sequence: The data and document storage for a set of dialogues. This is also the name of the interpreter class.
Spin has a number of places that can be extended.
Spin supports storing and retrieving values in a dialogue sequence. Since you may want to access data outside Spin itself (i.e. data from your game),
you can swap out the storage mechanism that is used in a sequence. The default backend that ships with Spin is a simple Dictionary<string, object>
, but
it can easily be replaced with the IVariableBackend
interface.
The mechanism used to load and parse documents is also replacable via the IDocumentLoader
interface. This is used primarily by the seq
/sequence
command.
Commands, blocks, and functions can all be added to a sequence. Attributes are used to mark methods that Spin can use. See the following classes:
Sequence.ExpressionBlock
andSequenceBlockAttribute
Sequence.ExpressionFunction
andSequenceFunctionAttribute
Sequence.CommandFunction
andSequenceCommandAttribute
Blocks contain further text and are used for things like if statements. Blocks look like this:
{if $foo}
foo is true!
{/}
Functions and commands are similar, except that functions can emit text and commands cannot be natively used in dialogue. Functions look like this:
{{v $foo}} # prints the value of foo
{$foo} # alternate syntax, this echos the value of variable $foo.
Commands are primarly found after each line of dialogue, and can be used to set what the next line of dialogue is.
+hello1
Hello, world!
+> set $foo true
> next hello2
set foo true
and next hello2
are commands here.
You can call commands inside lines of dialogue as well, though generally you shouldn't need to:
+hello1
{{cmd set $foo true}} Hello world!
+
Finally, you can actually use blocks and functions inside commands:
+hello1
Hello, world!
+
> {if $foo}next hello2{/}
> {if $bar}next hello3{/} # the previous two if blocks will actually error unless $foo and $bar were previously set
Since expressions just work with text, you can manipulate commands however you want as long as the result is either just whitespace or a valid command.
Spin was created by Sam Bloomberg.
Spin makes use of ANTLR 4 for parser and lexer generation.