Documentation menu

Build a multi-objective quest

Description: Introduce several objectives at once, wait for all of them, and let a dialogue choice decide the ending.

This walkthrough follows Build a quest. That first quest has one objective and one ending; this one has three jobs the player can finish in any order, a conversation that returns a result to the quest, and both a successful and a failed ending.

Follow along: download the project this walkthrough starts from. The zip also contains create_multi_objective_quest_final, the completed project, for comparison.

The case: a storm has trapped Detective Rowan Hale at Blackthorn Manor with a body, a witness, and two plausible suspects. Rowan must inspect the crime scene, recover the missing ledger, and question the witness before naming an accused. Accusing either suspect closes the case. Accusing the witness is technically a choice too, but it earns Rowan a reprimand and fails the quest.

The finished flow looks like this:

Main flow
Quest
  -> Start Dialogue: At the Crime Scene
  -> Inspect the scene
  -> Recover the missing ledger
  -> Question the witness
  -> Gate: all three are complete
  -> Start Dialogue: Make an accusation
  -> Hub: who was accused?
       -> either suspect -> Complete Quest (Success)
       -> witness -> reprimand dialogue -> Complete Quest (Failure)

Parallel listener bodies
InspectedScene flag   -> Update "Inspect the scene"          -> Return
RecoveredLedger flag  -> Update "Recover the missing ledger" -> Return
QuestionedWitness flag -> Update "Question the witness"       -> Return

Set up the cast

Create five Character entities. The Add a character walkthrough covers the mechanics, so this time you only need their names and roles:

Character External ID Role in this walkthrough Stock portrait
Detective Rowan Hale DetectiveRowanHale Player character; set Role to Protagonist male-5.png
Lord Ambrose Blackthorn LordAmbroseBlackthorn The murder victim male-2.png
Ada Finch AdaFinch The witness female-2.png
Lady Beatrice Blackthorn LadyBeatriceBlackthorn Suspect female-6.png
Julian Blackthorn JulianBlackthorn Suspect male-7.png

The victim does not need to speak, but keeping them as a character still makes the case easy to expand later. The two suspects and the witness will be useful as dialogue speakers, so give them distinct names now.

As described in Add a character, you can select several images in the Stock Image picker and import them together. Assign the portraits in the table above so each speaker is immediately recognizable on a dialogue node.

The five murder-mystery characters in the Characters and Items tree

Make the quest and its progress variables

In Quests & Dialogues, add a Quest named BlackthornMurder. Give it the player-facing title Murder at Blackthorn Manor and a short description such as "Find the evidence and name the killer before the storm passes."

Then add these four variables in the Variables view. The first three are boolean progress flags, all with a default value of false. Your game sets them when the player completes the corresponding world activity.

Name Type Default Set by your game when
BlackthornMurder_InspectedScene boolean false The player inspects the study.
BlackthornMurder_RecoveredLedger boolean false The player recovers the ledger.
BlackthornMurder_QuestionedWitness boolean false The player finishes questioning Ada.
BlackthornMurder_Accused string empty The accusation dialogue records the player's choice.

The boolean flags describe work happening in your game. BlackthornMurder_Accused is different: Narratyr writes it itself, and the quest reads it after the dialogue returns.

The three boolean progress flags and empty string accusation result

Open at the crime scene

Before introducing the objectives, give the quest a short opening conversation. Add a Dialogue named BlackthornCrimeScene with the player-facing title At the Crime Scene. Lady Beatrice and Julian are already in the study with the detective, so two lines are enough to establish both the body and the missing evidence:

Lady Beatrice: Detective, we found Lord Blackthorn here in the study. Neither of us touched the body.

Julian: His ledger is missing. I suppose that makes both of us look rather bad.

End the conversation after Julian's line. Return to BlackthornMurder, add a Start Dialogue after the Quest node, and choose the entry node of BlackthornCrimeScene. The quest will resume from that Start Dialogue node as soon as the conversation ends.

The short opening dialogue with both suspects present at the crime scene

Introduce all three objectives

Starting at the opening Start Dialogue node, add three Objective nodes in a row. An objective only introduces itself and immediately continues, so this sequence makes all three visible to the player before the quest waits for any of them.

Configure them as follows:

Name Objective Type Fields
Inspect the scene Generic None. This is a world action your game understands.
Recover the missing ledger Fetch Set itemTypeId to missing_ledger and count to 1.
Question the witness TalkTo Set targetId to Ada Finch's external ID, AdaFinch.

Leave Optional and Hidden off for each. The objective type tells your game what it needs to watch; it does not make Narratyr perform the action. In particular, Generic is useful when the action has no standard Fetch, Kill, or TalkTo shape.

Three connected objective nodes for inspecting, fetching, and talking

Wait until every lead is resolved

After the third objective, add a Gate and choose Wait on Expression. Set its condition to:

(
  BlackthornMurder_InspectedScene
  && BlackthornMurder_RecoveredLedger
  && BlackthornMurder_QuestionedWitness
)

The gate opens only when all three flags are true. They can become true in any order: the player may interview Ada before finding the ledger, for example. This is the useful distinction between introducing objectives in sequence and requiring them in sequence — the graph does the first, while the single combined condition controls the second.

When an expression contains more than one condition, wrap the whole expression in parentheses and start each && or || clause on a new line. This keeps the Gate node narrow enough to scan without hiding how its conditions are grouped.

The Gate node waiting on an expression containing all three progress flags

Complete each objective as its flag changes

The Gate controls when the main path may continue, but it should not delay the quest log. Add three Event Listener nodes in empty canvas space, separate from the main path. Give each listener a condition and a short body:

Listener condition Update Objective target
BlackthornMurder_InspectedScene Inspect the scene
BlackthornMurder_RecoveredLedger Recover the missing ledger
BlackthornMurder_QuestionedWitness Question the witness

From each Event Listener, connect an Update Objective node. Point it at the matching objective and leave Completion Status set to Completed. Finish each listener body with a Return node. Leave Async off: these bodies are short, do not pause, and should return immediately to whatever the quest was doing when the flag changed.

An Event Listener fires when its condition changes from false to true. That means finding the ledger completes Recover the missing ledger immediately, even if the other two flags are still false and the main flow is still waiting at the Gate. The Return node then resumes that waiting flow. The three listener bodies are independent, so the player can complete the objectives in any order.

This is the same pattern used by 006 Parallel Multi-Objective Any Order Quest in EngineTest.ntproj: listeners keep individual objective state current, while one combined Gate decides when every prerequisite has been satisfied.

Three Event Listener bodies independently completing objectives and returning

Build the accusation dialogue

Add a Dialogue named BlackthornAccusation. Its entry line can be very short; set Rowan Hale as the speaker and write:

I have heard enough. One of you killed Lord Blackthorn.

Add a second Dialogue Node with Rowan as its speaker, leave its line empty, and add three choices:

  • Accuse Lady Beatrice.
  • Accuse Julian.
  • Accuse Ada, the witness.

The choices belong on Rowan's node because the player is choosing Rowan's words. For each choice, add an Instruction node, then an End Conversation node. Name the instruction after the choice and set its instruction text to one of these assignments:

The accusation dialogue branching into three player choices

BlackthornMurder_Accused = "LadyBeatrice"
BlackthornMurder_Accused = "Julian"
BlackthornMurder_Accused = "Ada"

All three instructions can connect to the same End Conversation node. An instruction changes shared state without pausing. Once the conversation ends, the quest that started it resumes at the node after its Start Dialogue node.

An accusation choice flowing through an Instruction node that stores Ada

Start the dialogue and branch on its result

Return to BlackthornMurder. After the Gate, add Start Dialogue and choose the entry node of BlackthornAccusation as its target. The quest pauses while the dialogue is on screen, then continues after the player makes a choice.

Add a Hub Node after Start Dialogue. Give it three outputs and set their conditions to:

BlackthornMurder_Accused == "LadyBeatrice"
BlackthornMurder_Accused == "Julian"
BlackthornMurder_Accused == "Ada"

The Hub does not wait: it immediately takes the output whose condition is true. This is the companion to a Gate. The Gate waited for the investigation to be ready; the Hub reads the choice that is already known.

The quest starting the accusation dialogue and branching through a Hub

End the case

Connect the Lady Beatrice and Julian outputs to Complete Quest nodes with status Success. The tutorial is about the graph shape rather than solving a fair mystery, so either suspect is a successful case conclusion.

For the Ada output, add a short Dialogue named WitnessReprimand, then start it from the Hub's Ada branch. A line from Lady Beatrice is enough:

Lady Beatrice: Detective, she is the witness. Please stop accusing the only person who called for help.

End that dialogue and connect back to a Complete Quest node with status Failure. The three terminal nodes make the outcomes explicit to your game: the two suspect branches succeed, while the joke accusation fails after its small narrative payoff.

Lady Beatrice reprimanding the detective for accusing the witness

The Hub's successful suspect branches and failed witness branch

Read the finished graph

Use Auto Arrange to lay out the quest. Its main path should read left to right from the three introductions through the gate and accusation dialogue. The Hub's two successful branches end at their success nodes, while the witness branch drops to the reprimand and failure node. The three Event Listener bodies sit outside that main spine, each flowing through its matching objective update to a Return node.

The complete arranged multi-objective murder quest

This pattern scales well: add another objective by introducing it, add an Event Listener that completes it when its flag changes, and include one more clause in the final Gate expression. The listener keeps that objective current on its own; the Gate remains the single place that defines when the investigation as a whole may continue.