dialogue

package module
v0.0.0-...-6aa2a36 Latest Latest
Warning

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

Go to latest
Published: Nov 26, 2021 License: MIT Imports: 11 Imported by: 0

README

Dialogue Engine

Script Format

A script is a markdown-like collection of dialogue nodes. These nodes are the different sequences of dialogue to be displayed to the user. A node looks like this:

// the first section is the frontmatter. This contains type definitions for external functions.
// These are defined as follows:
extern func1(bool, number, string, null);
extern func2();

// end frontmatter with three backticks.
```

# node1

Here's some text that's going to be displayed to the user.
Just like in HTML, extra whitespace including newlines are
reduced down to render as a single space.

Blocks of text separated by an empty line are displayed to
the user as separate chunks of text, so the user will see
the above paragraph, then this one.

[node2](Markdown links instruct the engine to transition to another node)

# node2

Nodes can be transitioned by links and by giving an option.
Links don't give an option - they just display some text and
the transition.

The following shows what an option looks like. In markdown terms,
it is just an unordered list of links.

- [node1] (This goes to node1)
- [node2] (This repeats node2)
- [node3] (An empty line will terminate the list, as it does paragraphs and links)

# node3

Paragraph text can have inline code interleaved with the plain text.
This is useful to print out the value of a variable like so: `variable1`.
Just use the markdown inline code element. It can also have simple expressions
like so: `3 + 3`

```
// You can also have code blocks.
// These are Markdown fenced code blocks.
// They are a block-level element like a paragraph, link, or option list.
// The language in the code blocks is a simple C-like language.
// Comments are like C single-line comments
// You can assign variables

variable1 = 32 * variable2;

// If statements  and if-else statements are in there as well
if variable1 > 12 {
  // You can call functions that the vm exposes
  function1(variable1 == variable2);
}

// There's loops
while variable1 > 12 {
  // preincrement and predecrement are expressions and don't reassign the referenced variable
  variable1 = --variable1
}

// you can transition to other nodes
goto node4;

// you can call the external functions
func1(false, 5, "abc", null);

```

# node4

The first node in the script is the dialogue's starting point.
Ending a node without a link or choice will terminate the script.

Todo List

  • unit test the parser
  • unit test the parse tree -> ast translation
  • unit test type checking
  • implement constant folding
  • unit test constant folding
  • implement test dead node elimination
  • unit test dead node elimination
  • 100% unit test coverage everywhere (internal + user-facing)
  • add if with elided else code generation
  • add naked if with reverse logic when consequent is empty
  • add unary minus operator
  • add != operator
  • add modulo operator
  • make infinite loop AST node when while(true){...}
  • add extern func declarations
  • add optional front matter code block
  • implement parent package/public interface
  • implement compiler CLI
  • implement vm cli
  • make link text support inline expressions
  • implement asm deflate/inflate for binary format
  • (stretch goal) Multi-file script linker
  • (stretch goal) break and continue
  • (stretch goal) variable scopes / differentiating extern and in-script variables
  • (stretch goal) add typed variable declarations
  • (stretch goal) add builtin function calls (EndDialog, PushOption, ShowOption, ShowLine, EnterNode, ExitNode)

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Compile

func Compile(options ...CompileArg) error

Compile tranlates a Script from text into its executable form. Any reads errors, syntax errors, semantic errors, or write errors will result in an error being returned.

func NoCodeFolding

func NoCodeFolding(ca *CompileArgs)

func NoDeadCodeElimination

func NoDeadCodeElimination(ca *CompileArgs)

Types

type CompileArg

type CompileArg func(*CompileArgs)

func CompilerInput

func CompilerInput(r io.Reader) CompileArg

func CompilerOutput

func CompilerOutput(w io.Writer) CompileArg

type CompileArgs

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

type EndScript

type EndScript struct {
}

type EnterNode

type EnterNode struct {
	NodeEntered string
}

type ExecutionType

type ExecutionType vm.ExecutionType

ExecutionType as a handler's return value is a signal to the Process whether or not to carry on executing once a callback is handled.

const (
	// Returning Pause will cause the Process to suspend until its
	// Continue() method is invoked.
	Pause ExecutionType = ExecutionType(vm.PauseExecution)
	// Returning Continue will cause the Process to continue executing
	// and will not stop until either the dialogue ends, an option is
	// shown, or one of the other ScriptHandler methods returns Pause
	Continue ExecutionType = ExecutionType(vm.ContinueExecution)
)

type ExitNode

type ExitNode struct {
	NodeExited string
}

type FunctionCall

type FunctionCall struct {
	Name string
	Args []interface{}
}

type Handler

type Handler interface {
	Handle(m Message) ExecutionType
}

Handler is the Process's interface to the rest of the program. This method is used to handle messages coming from the process.

type HandlerFunc

type HandlerFunc func(m Message) ExecutionType

func (HandlerFunc) Handle

func (h HandlerFunc) Handle(m Message) ExecutionType

type MessageType

type MessageType int
const (
	EndScriptType MessageType = iota
	ShowLineType
	EnterNodeType
	ExitNodeType
	ShowChoiceType
	FunctionCallType
)

type Process

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

Process is an instance of a script to execute. Run the script by invoking the Start() method.

func (*Process) ChooseAndResume

func (p *Process) ChooseAndResume(choice int) error

ChooseAndResume continues a Process which is waiting for user input. Calling this on a Process which isn't waiting for user input will result in an error.

func (*Process) Resume

func (p *Process) Resume() error

Resume continues execution of a suspended Process. Calling this on a Process which isn't suspended, or is waiting for user input, will result in an error.

func (*Process) Start

func (p *Process) Start() error

Start begins execution on a script. Calling this on an in-progress Process, even if it's suspended, results in an error.

type Script

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

Script is a compiled script. Running this spawns a Process, which will run the dialogue logic.

func FromReader

func FromReader(opts ...ScriptOption) (*Script, error)

FromReader loads a compiled script from a file or other reader.

func (*Script) New

func (s *Script) New(h Handler) (*Process, error)

New spawns a new Process which runs this particular script. The Process interacts with the rest of the program by invoking various callbacks supplied by the ScriptHandler. A new Process is created for each invocation of New.

type ScriptOption

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

func IsUncompressed

func IsUncompressed() ScriptOption

func ScriptInput

func ScriptInput(r io.Reader) ScriptOption

type ShowChoice

type ShowChoice struct {
	Options []string
}

type ShowLine

type ShowLine struct {
	Line string
}

Directories

Path Synopsis
internal
vm

Jump to

Keyboard shortcuts

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