Documentation menu

Build a quest

Description: Introduce an objective, wait for the player to finish it, and end the quest.

A quest is a graph like a dialogue, but where a dialogue models a conversation, a quest models progress: which objectives exist, when they are introduced, what finishes them, and what happens once they are done. This walkthrough builds the smallest quest that still has all of those parts — one objective, one thing to wait for, one ending.

Follow along: download the project this walkthrough starts from. The zip holds two projects — create_quest, where the walkthrough begins, and create_quest_final, where it ends up if you want to compare.

The quest: Mira Thorne has lost her ledger somewhere on the mountain road. The player is told to find it, the quest waits until they do, and then it records the objective as done and closes with a success.

Open the Quests & Dialogues view

Quests and dialogues are both graphs, and they live together in the Quests & Dialogues view. Click its icon in the left sidebar, or press 2.

The Quests & Dialogues view, with the sidebar icon highlighted

The left panel lists the project's graphs, the middle is the canvas, and the right panel shows the properties of whatever is selected. Quests lean on that right panel much more than dialogues do: most quest nodes are configured there rather than typed into on the canvas.

Add a quest and name it

Click Add in the toolbar and choose Quest.

The Add menu open, showing Dialogue, Quest and Quest Fragment

The new graph appears in the tree with its name ready to edit. Type a name and press Enter.

The new graph in the tree, its name being edited

This name is how your game's code refers to the quest, so it has to be a valid identifier — letters, digits and underscores, no spaces. This walkthrough uses LostLedger.

Quest Fragment, the third entry in that menu, is a quest graph you call into from another quest — a way to split a long quest across several graphs. A quest this size does not need one.

Give it a title and a description

With nothing on the canvas selected, the properties panel edits the graph itself. Fill in the Title and Description.

The graph's properties, with the title filled in

  • Name is the identifier. It is not meant to be shown to players.
  • Title is player-facing — the quest name a journal would print.
  • Description is the summary that goes with it.

The pale green node on the canvas is the Quest node — where the quest starts, created with the graph and not removable. It displays the graph's title, so it fills in as soon as you set one.

Across the top of the canvas is a warning that this quest has no Complete Quest node. It stays until you add one at the end; a quest without one can still run off the end of its graph, but it does so silently, with no success or failure for your game to react to.

Introduce the objective

Drag from the round handle on the right edge of the Quest node and let go over empty canvas. Releasing a connection with nowhere to land opens the insert menu, and whatever you pick arrives already wired up to the handle you dragged from. Choose Objective.

The insert menu, opened by dropping a connection on empty canvas

Every node type also has a single-key shortcut — O for an objective, G for a gate, U for an update, F for the finish — which drops that node wherever the pointer is. Right-clicking the canvas offers the same list as a menu.

Click the new node to select it, and fill it in from the properties panel.

The objective's properties, with the type, name and fields filled in

  • Objective Type is what kind of step this is — Fetch, Kill, GoToLocation, TalkTo, and whatever else your project has defined. Choosing one links the objective to the matching type and brings its fields with it: a Fetch objective asks which item and how many.
  • Name is what the player's quest log shows.
  • The fields underneath (here itemTypeId and count) describe the objective to your game, which is what actually watches the world and decides the step is done. Narratyr does not check them itself.
  • Optional marks a step that enriches the quest but never blocks it, and Hidden keeps it out of the quest log until something reveals it. Both stay off here.

The important thing about this node: it introduces the objective and moves on immediately. Declaring an objective and finishing it are two separate moments in the graph, which is what the next two nodes are for.

The flag your game will set

The quest runtime has to wait for something, or else the quest would simply complete immediately, and that something is shared state both sides can see. Open the Variables view, click Add Variable, and name it.

The Add Variable popover, with the new name typed in

Everything before the last underscore is a namespace, so naming a quest's own state <QuestName>_<Flag> groups it under that quest in the table — and, in a project saved as a folder, keeps it in its own file. This one is LostLedger_HasLedger.

A new variable starts as an integer. Click its Type cell twice — once to select it, once to open the editor — and choose boolean, then do the same on Default Value and set it to false.

The new boolean variable in the variables table

Nothing in Narratyr sets this flag. Your game does, when the player picks the ledger up — see Variables for how that shared state works.

Wait for it

Back on the quest, drag from the objective's output onto empty canvas and add a Gate. A gate blocks the flow until its condition is true, then carries on by itself.

Click the gate to edit it, and it offers three things to wait on.

The gate node, offering Wait on Variable, Wait on Objective and Wait on Expression

  • Wait on Variable — pick one or more true/false variables; the gate opens when they are all true. This is the usual shape when your game reports progress by setting a flag.
  • Wait on Objective — pick an objective and the state it has to reach (Completed, Failed, and so on). Use this when something else decides that objective's fate: another branch of the same quest, or a game that marks objectives resolved through the runtime directly. The advantage of this approach is that it saves on a variable definition, but the disadvantage is it's slightly more complicated to setup in the game runtime (one needs to know the id of the objective to mark -- which can be found on the objective node in the properties panel.)
  • Wait on Expression — anything the condition language can express, for when a flag is not enough: Gold >= 10 && !HasMap.

They are three ways of writing the same thing. A gate is a condition either way, and the runtime re-checks it whenever the state it reads changes, so a quest parked on a gate wakes up on its own.

Choose Wait on Variable and pick LostLedger_HasLedger. The gate shows what it is waiting on.

The gate waiting on the LostLedger_HasLedger variable

Mark the objective done

Past the gate, the ledger is in the player's hands — but the objective is still open, because nothing has said otherwise. Drag from the gate's output and add an Update Objective, then point it at the objective and leave the status on Completed.

The Update Objective node, targeting the objective with status Completed

This node applies a patch, and every field it does not set is left alone — that's what Leave unchanged means on the two below. The same node can reveal a hidden objective, make one optional, mark it failed, or re-open one that was already finished; completing it is just the common case.

End the quest

Drag from the update's output one last time and add a Complete Quest node. Its status decides how the quest ends.

The Complete Quest node, with status Success

This is a quest's terminal node: reaching one ends the quest with that outcome and tells your game about it. Quests often have several — one per distinct ending — but a success is enough here. The warning across the top of the canvas is gone now that the graph has one.

See the whole thing

The button in the top-right corner of the canvas hides the tree and properties panels and gives the window over to the graph; the same button brings them back. That is the easiest way to look at a finished quest.

The finished quest before arranging, with the arrange button highlighted

Placing nodes by hand as you go rarely leaves them evenly spaced. The last button on the bottom-left toolbar arranges the whole graph — it is also on the canvas right-click menu as Auto Arrange, and on A. The button above it frames everything in the window.

The arranged quest, from the quest node to the completion

It now reads as it plays: the quest starts, the objective is introduced, the gate holds until the game says the ledger is found, the objective is marked complete, and the quest ends in success.

Press S to write your work to disk. A * next to the project name in the title bar means there is unsaved work.

Next

This quest waits on one flag and ends one way. The pieces that grow it are in Quests: a Hub to branch on the state of the world, a Fork for objectives that run at once, an Event Listener for an optional step that must not hold up the rest, and Start Dialogue to hand off to a conversation and pick up where it left off.

Variables and conditions covers the state a gate reads, and Build a dialogue builds the other half of the model — a conversation that can set the very flag this quest is waiting for.