Yarnspinnex (yarnspinnex v0.3.0)

Copy Markdown View Source

Parses Yarn Spinner dialogue into a Yarnspinnex.Script (plain data, safe to cache) and runs it one event at a time: step/3 returns the next line, command, or option group along with an updated Yarnspinnex.Cursor, and choose/4 answers an option group. Nothing blocks.

A script reads two collections of values. vars live in the cursor, are written by <<set>>, and persist with it. context is live host state passed to each step/3 call and never persisted - it is where structs, repos, and anything a game system owns belong. A name found in both resolves to context; declare the context names at compile time to make that a hard error instead of a surprise. In both, $player in a script and player: in Elixir are one name.

Summary

Functions

Whether cursor can be resumed against script: its node is unchanged since the cursor was made and it points at a real position in it. Call this on a cursor loaded from storage to decide between resuming and restarting; step/3 performs the same check and raises instead.

Answers the option group step/3 returned by picking the option at index.

Parses and validates Yarn source into a Yarnspinnex.Script.

A cursor at the node titled title holding vars.

Titles of every node in script.

A cursor at the start node ("Start" if present, else the first node) holding vars.

Advances to the next event: a line, a command, an option group, or the end of the dialogue.

Types

compile_option()

@type compile_option() ::
  {:functions, module()}
  | {:context, [atom() | String.t()]}
  | {:variables, [atom() | String.t()]}
  | {:strict, boolean()}

Functions

check_cursor(script, cursor)

Whether cursor can be resumed against script: its node is unchanged since the cursor was made and it points at a real position in it. Call this on a cursor loaded from storage to decide between resuming and restarting; step/3 performs the same check and raises instead.

choose(script, cursor, index, context \\ %{})

Answers the option group step/3 returned by picking the option at index.

compile_string(source, opts \\ [])

@spec compile_string(String.t(), [compile_option()]) ::
  {:ok, Yarnspinnex.Script.t()} | {:error, Yarnspinnex.CompileError.t()}

Parses and validates Yarn source into a Yarnspinnex.Script.

Options:

  • :functions - a Yarnspinnex.HostFunctions module; every call in the script is checked against its declared/0, by name and arity.
  • :context - the names the host supplies as context at run time. Assigning to one is rejected here rather than silently losing to context later.
  • :variables - names the host provides as vars (set by other scripts, or persisted), for :strict.
  • :strict - when true, every $name the script reads must be assigned somewhere in it or be listed under :context or :variables, so a misspelled name is a compile error instead of a nil.

enter(script, title, vars \\ %{})

@spec enter(Yarnspinnex.Script.t(), String.t(), Yarnspinnex.Vars.vars()) ::
  {:ok, Yarnspinnex.Cursor.t()} | {:error, :unknown_node}

A cursor at the node titled title holding vars.

node_titles(script)

@spec node_titles(Yarnspinnex.Script.t()) :: [String.t()]

Titles of every node in script.

start(script, vars \\ %{})

A cursor at the start node ("Start" if present, else the first node) holding vars.

step(script, cursor, context \\ %{})

Advances to the next event: a line, a command, an option group, or the end of the dialogue.

context is host state the script can read but not write; it is handed to Yarnspinnex.HostFunctions.call/3 untouched. Raises Yarnspinnex.RuntimeError, located at the offending statement, when a statement cannot run or the cursor does not fit the script.