ysgo

package module
v0.0.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 17, 2024 License: MIT Imports: 13 Imported by: 2

README

Ysgo

Go Reference build codecov Go Report Card License

Introduction

Ysgo is a Go library that is able to run YarnSpinner dialogues.

It hasn't reached V1 yet but its public API shouldn't undergo any massive change now.

What's YarnSpinner?

YarnSpinner is an open-source tool for creating interactive dialogue and branching narratives in video games and other interactive media. It allows writers and game designers to create complex branching stories, character interactions, and dialogues, and provides an intuitive visual interface for scripting and organizing the flow of the story. YarnSpinner is often used in the creation of visual novels, adventure games, and other interactive narrative experiences.

Minimal example

Here's a small program that runs a dialogue, printing it to the standard output:

package main

import (
	"fmt"
	"log"
	"strings"

	"github.com/remieven/ysgo"
)

func main() {
	script := `
title: flavors
---
Which flavor do you prefer?
-> Chocolate
	<<set $flavor to "chocolate">>
-> Raspberry
	<<set $flavor to "raspberry">>
Nice! Here, get some {$flavor} icecream!
===`

	logFatalIfErr := func(err error) {
		if err != nil {
			log.Fatalf("error: %v", err)
		}
	}

	// NewDialogueRunner parses the dialogue and creates a runner that can execute it
	dr, err := ysgo.NewDialogueRunner(nil, "", strings.NewReader(script))
	logFatalIfErr(err)

	// Next advances the dialogue to the next step
	dialogueElement, err := dr.Next(0)
	logFatalIfErr(err)
	fmt.Println(dialogueElement.Line.Text) // Which flavor do you prefer?

	dialogueElement, err = dr.Next(0)
	logFatalIfErr(err)
	fmt.Println(dialogueElement.Options[0].Line.Text) // Chocolate
	fmt.Println(dialogueElement.Options[1].Line.Text) // Raspberry

	dialogueElement, err = dr.Next(1) // Nice! Here, get some raspberry icecream!
	logFatalIfErr(err)
	fmt.Println(dialogueElement.Line.Text)
}

Features

YarnSpinner's core features are mostly supported by Ysgo, with the exception of localization (which might be added sometime) and type checking (not currently planned).

In addition to these missing features, there are key differences between Ysgo and YarnSpinner:

  • No compilation: parsing occurs at runtime
  • No built-in integration with any game engines (however, it works well with Ebitengine)
  • Dialogue runners are only in "pull" mode, meaning they won't emit events or control UI components on their own.

Ysgo only handles your dialogues when your game is running, during development you're still encouraged to use the vscode plugin and YarnSpinner-Console.

Ysgo in Action

Despite not having all of YarnSpinner's features, Ysgo still provides enough functionality to recreate sample projects from the YarnSpinner documentation.

Check out the demos:

Source code for all demos is available in the ysgo-examples Github repository.

Getting help

Feel free to open an issue in this repository!

License

Ysgo is licensed under the MIT license (see the LICENSE.txt file).

Credits

Ysgo wouldn't exist if it weren't for all the people behind Yarn Spinner. Big thanks to them.

Also, this article has been super helpful to figure out how to use antlr4 with Go.

Documentation

Overview

Package ysgo defines a DialogueRunner type able to execute dialogues.

Index

Constants

View Source
const ErrWaitingForCommandCompletion errWaitingForCommandCompletion = "waiting for command completion"

ErrWaitingForCommandCompletion is returned when DialogueRunner#Next(...) is called when an ongoing command hasn't ended yet.

Variables

This section is empty.

Functions

This section is empty.

Types

type DialogueElement

type DialogueElement struct {
	Node    string
	Line    *markup.ParseResult
	Options []DialogueOption
}

DialogueElement represents a step of a dialogue as it is presented in a game. Either Line or Options holds a value. Node holds the name of the dialogue node that contains the element.

type DialogueOption

type DialogueOption struct {
	Line     *markup.ParseResult
	Disabled bool
}

DialogueOption holds the data about one possible choice the player is presented with.

type DialogueRunner

type DialogueRunner struct {
	// contains filtered or unexported fields
}

DialogueRunner is able to execute a YarnSpinner dialogue. It keeps track of the current state of the dialogue (variables, current and visited steps). It orchestrates the call of Commands and Functions.

func NewDialogueRunner

func NewDialogueRunner(storer variable.Storer, rngSeed string, readers ...io.Reader) (*DialogueRunner, error)

NewDialogueRunner creates a new runner working on the dialogue that can be parsed from the given readers. The storer argument is optional and if provided, allows to store variables elsewhere than in the default in-memory store. The given rngSeed serves to create deterministic random values. It will be used when eg. the dice(6) function is called in a dialogue.

func (*DialogueRunner) AddCommand

func (dr *DialogueRunner) AddCommand(commandID string, command YarnSpinnerCommand)

AddCommand adds a custom command to the library of commands that can be called from a dialogue.

func (*DialogueRunner) AddFunction

func (dr *DialogueRunner) AddFunction(functionID string, function YarnSpinnerFunction)

AddFunction adds a custom function to the library of functions that can be called from a dialogue.

func (*DialogueRunner) ConvertAndAddCommand

func (dr *DialogueRunner) ConvertAndAddCommand(commandID string, command any) error

ConvertAndAddCommand is a convenience wrapper around AddCommand so that manual conversion to YarnSpinnerCommand isn't needed. Refer to the unit tests of commandStorer to learn more about the limitations on the accepted functions.

func (*DialogueRunner) ConvertAndAddFunction

func (dr *DialogueRunner) ConvertAndAddFunction(functionID string, function any) error

ConvertAndAddFunction is a convenience wrapper around AddFunction so that manual conversion to YarnSpinnerFunction isn't needed. Refer to the unit tests of functionStorer to learn more about the limitations on the accepted functions.

func (*DialogueRunner) Next

func (dr *DialogueRunner) Next(choice int) (*DialogueElement, error)

Next advances the dialogue to the next step. If the previous step was a choice, then the selected option index should be given as an argument, else that argument is ignored. If an ongoing command (eg. <<wait 3>>) from the dialogue is still running, ErrWaitingForCommandCompletion is returned. Else, if no other error is encountered, the next DialogueElement to display is returned. If the Dialogue has ended, then both return values will be nil.

func (*DialogueRunner) RestoreAt added in v0.0.7

func (dr *DialogueRunner) RestoreAt(snapshot *Snapshot) error

RestoreAt uses a snapshot to restore a dialogue runner to a former state.

func (*DialogueRunner) Snapshot added in v0.0.7

func (dr *DialogueRunner) Snapshot() *Snapshot

Snapshot returns the state of the dialogue runner as of the last time a node was entered. It can then be used to later restore the state of the dialogue runner.

type Snapshot added in v0.0.7

type Snapshot struct {
	Variables map[string]variable.Value

	CurrentNode string

	VisitedNodes map[string]int
}

Snapshot holds data that represents the current state of a dialogue, so it can be restored later.

type YarnSpinnerCommand

type YarnSpinnerCommand func([]*variable.Value) <-chan error

YarnSpinnerCommand is a Go function than can be called as a command from a YarnSpinner script. It can take zero, one or more input values, and returns a chan that must return either nil or an error when the command has finished its job.

type YarnSpinnerFunction

type YarnSpinnerFunction func([]*variable.Value) (*variable.Value, error)

YarnSpinnerFunction is a Go function than can be called as a function from a YarnSpinner script. It can take zero, one or more input values, and returns possibly a value and/or an error.

Directories

Path Synopsis
internal
parser
Package parser contains code generated by Antlr based from the Lexer.g4 and Parser.g4 files, using the generateParser.sh file at the root of the git repository of the ysgo module.
Package parser contains code generated by Antlr based from the Lexer.g4 and Parser.g4 files, using the generateParser.sh file at the root of the git repository of the ysgo module.
rng
Package markup contains the code used to parse the markup tags in a line of dialogue, along with markup processors that can be used to eg.
Package markup contains the code used to parse the markup tags in a line of dialogue, along with markup processors that can be used to eg.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL