DialogueScriptExport.h header

#include <ew/app/DialogueScriptExport.h>

Namespace ew::app

DialogueScriptNote struct

struct ew::app::DialogueScriptNote

One thing the target language cannot say, named with the node it came from.

Reported rather than silently dropped. A studio adopting an exporter reads the output once and then trusts it, so an option that quietly stopped being offered, or a requirement that quietly stopped being enforced, becomes a bug found in playtesting months later with no trail back to the export. Anything this cannot carry is said out loud, in the author's own terms.

Members

ew::core::foundation::ContentId ew::app::publishing::DialogueScriptNote::sceneId

The scene the problem is in.

ew::core::foundation::BranchNodeId ew::app::publishing::DialogueScriptNote::nodeId

The node it came from; null for a note about the scene or the project as a whole.

QString ew::app::publishing::DialogueScriptNote::message

What could not be represented, in a sentence an author can act on.

DialogueScriptResult struct

struct ew::app::DialogueScriptResult

A generated script and everything the target language could not carry.

Members

QString ew::app::publishing::DialogueScriptResult::source

The emitted source: a complete .ink or .yarn file.

std::vector<DialogueScriptNote> ew::app::publishing::DialogueScriptResult::notes

Empty when the export is lossless.

Functions

DialogueScriptResult ew::app::publishing::exportInk(const ew::core::project::Project &project)

Compiles project's branching scenes to ink source.

Why an exporter at all. The engine export is a proprietary versioned contract, so a studio already running ink would have to abandon its runtime to adopt Ordfoss. It will not. ink and Yarn are documented, open and stable, with first-party Unity integrations and Godot support, so emitting them reaches every engine those runtimes reach without writing a single engine plugin.

The mapping.

  • Each scene becomes a knot, each node a stitch inside it, named from its text so the output is readable rather than a wall of ids. Cross-scene jumps become -> knot.stitch.
  • A Line's and a Hub's text is emitted as prose. A Condition's and a Jump's text is emitted as a comment, because it is the author's label for a fork a reader never sees – putting it in the flow would have a shipped game narrate its own stage directions. Nothing is lost: the words are in the file, where a reader of the script can see them.
  • A Choice node's ways onward become sticky choices (+), because Ordfoss does not model an option as once-only and * would silently make every option vanish after one use.
  • A Condition becomes ink's { test: -> a - else: -> b }.
  • Variables become VAR declarations, effects become ~ assignments, and a link's condition becomes the {...} guard on its choice.
  • The speaker (2.10) becomes a # speaker: tag, which is how ink carries out-of-band line data, and delivery becomes # delivery:.

What it will not do is guess. The expression language shared by conditions is far larger than either target's – it has aggregate, text and math functions – so an expression using anything outside AND OR NOT, the comparisons, arithmetic, names and literals is reported and its guard omitted rather than approximated. An approximation that is right nine times out of ten is the worst possible outcome here.

DialogueScriptResult ew::app::publishing::exportInkScene(const ew::core::project::Project &project, const ew::core::branching::BranchScene &scene)

Compiles a single scene of project to ink source; see exportInk for the mapping.

The project is still needed: variables, cross-scene jump targets and speaker names all live there, and a scene exported without them would emit undeclared names.

DialogueScriptResult ew::app::publishing::exportYarn(const ew::core::project::Project &project)

Compiles project's branching scenes to Yarn Spinner source.

The mapping, which differs from ink's in one structural way: Yarn has no sub-node label, so each Ordfoss node becomes its own Yarn node rather than a stitch, and every way onward is a <<jump>>. A Start node is emitted first, declaring the variables and jumping to the first scene's start, because a Yarn project needs a node to begin at and variables must be declared before they are set.

  • Text becomes a line, with the speaker in Yarn's own Speaker: text convention – the one thing Yarn models natively that ink does not.
  • A Choice node's ways onward become -> options, each with its own <<jump>>, and a link's condition becomes the option's <<if>>.
  • A Condition becomes <<if>> / <<else>> / <<endif>> around two jumps.
  • Effects become <<set>>; variables become <<declare>>. Everything said about not guessing at expressions applies here too.

DialogueScriptResult ew::app::publishing::exportYarnScene(const ew::core::project::Project &project, const ew::core::branching::BranchScene &scene)

Compiles a single scene of project to Yarn source; see exportYarn for the mapping.