Quests and Dialogues System

Purpose and Scope

The Quests and Dialogues system controls story progression, side activities and narrative interactions in RPG Engine v6. It is built on top of data‑driven quest definitions, modular quest components on player and NPCs, and a unified dialogue pipeline that also connects to trading and combat reactions.

This document explains the quest data model, runtime components, dialogue structure, and how all of these pieces work together.

Quest Data Model (DT_Quests and S_QuestContainerData)

All quests are defined in a single data table DT_Quests. Each row uses the S_QuestContainerData structure.

General Data

General Data (S_QuestGeneralData) stores the basic information and dialogue hooks for a quest:

  • Name (Text)
    Display name of the quest in the journal and UI.

  • Description (Text)
    Description shown to the player when viewing quest details.

  • UniqueID (int)
    Numeric unique identifier of the quest. Used to reference the quest from code and components.

  • Complexity (E_Complexity: Easy, Medium, Hard)
    Visual complexity marker for UI and sorting. Does not affect gameplay logic directly.

  • ApproximateTime (Timecode)
    Approximate time required to complete the quest, used for presentation.

  • Visual Tip (Texture2D)
    Visual hint that helps the player understand what to look for or where to go.

Dialogue hooks:

  • Give Quest Dialogue (Soft DataTable)
    Dialogue table used when the quest is first offered by an NPC.

  • Give Quest Dialogue Stop And Talk (bool)
    If true, player input is blocked and the character is repositioned/locked for the duration of the quest‑giving dialogue.

  • End Quest Dialogue (Soft DataTable)
    Dialogue table used when the quest is turned in to the NPC.

  • End Quest Dialogue Stop And Talk (bool)
    If true, the player is stopped and control is disabled during the completion dialogue.

  • Quest not Finished Dialogue (Soft DataTable)
    Dialogue table used when the player talks to the quest‑giver before finishing the quest.

  • Quest not Finished Dialogue Stop And Talk (bool)
    If true, the player is stopped and control is disabled for the “quest not finished yet” dialogue.

Category

Category (S_QuestCategory) defines the high‑level type of the quest:

  • Category (E_QuestCategories)
    • Main Quest
    • Side Quest

This is primarily used for grouping and UI.

Conditions

Conditions (S_QuestConditions) define when the quest becomes available:

  • MinimalLevel (int)
    Minimum player level required to start this quest.

  • Finished Quests Unique ID (int[])
    List of UniqueIDs of other quests that must be completed before this quest can be started.

These conditions are evaluated by the quest component and/or quest selection UI before allowing the quest to start.

Stages

Stages (S_QuestStages) describes the full internal structure of a quest as a sequence of stages.

  • Stages (array of S_QuestStage)
    Each S_QuestStage is one step in the quest flow.

Fields of S_QuestStage:

  • StageType (E_StageTypes)
    Defines what the player must do at this stage. Current values:

    • FindItem
    • ReachZone
    • Go back to NPC
  • Name (Text)
    Stage name, used for UI and debugging.

  • Description (Text)
    Description of what the player must do at this stage.

FindItem Stage Data

For StageType = FindItem, the stage uses Required Quantity Of Specified Item With Tag (S_ReqItemCustomTag):

  • Actor (Soft Actor reference)
    Actor class of the item that must be found/collected.

  • Quantity (int)
    How many such items must be collected.

  • Tag (Gameplay Tag)
    Tag that the actor must have to be counted for this stage.

  • DynamicQuantity (int, runtime)
    How many required items the player has already collected for this stage (progress tracking).

  • SpawnTransform (Transform)
    World transform where the quest actor is spawned when the stage is active.

ReachZone Stage Data

For StageType = ReachZone, the stage uses Required tagged zone achievement (S_ReqZone):

  • Tag (Gameplay Tag)
    Tag of the zone actor the player must reach.

  • SpawnTransform (Transform)
    World transform where the zone actor will be spawned.

  • BP QuestZone (Soft Actor reference)
    Actor class of the zone object that is spawned and used for detection.

Go back to NPC Stage

For StageType = Go back to NPC, the stage does not use S_ReqItemCustomTag or S_ReqZone. The requirement is simply that the player returns to the NPC who gave the quest and completes the dialogue or interaction that finalizes the quest.

Stage Visual Tips

  • Visual Tip (Texture2D)
    Optional per‑stage visual hint that helps the player understand how to complete the current stage.

Reward

Reward (S_QuestReward) defines what the player receives when the quest is completed:

  • ItemData/Quantity (Map<Soft Object reference, int>)
    Map of item data assets (for example, rows from DT_ItemData) to quantities given as quest reward.

  • Experience (int)
    Amount of XP awarded on completion.

  • ItemsName/Quantity
    Separate reward channel that stores item identifiers and quantities by name.
    ItemsName corresponds to row names in DT_ItemData. This can be used by UI or logic that resolves items via data table names rather than direct asset references.

ExtraData

  • ExtraData (Map<Name, int>)
    Generic integer map used to store lightweight numeric metadata related to rewards or quest configuration without loading full reward data into memory during quest selection.

QuestEngineData

QuestEngineData (S_QuestEngineData) is used by the quest runtime as an engine‑oriented metadata block:

  • Finished (bool)
    Whether this quest is considered finished in the player’s runtime copy of quest data.

  • By NPC (bool)
    Whether the quest was given by an NPC (as opposed to being started by UI or script).

  • NPC Tag (Name)
    Tag of the NPC who gave this quest.

Note: these fields are not modified in the DT_Quests asset at runtime. Instead, they are updated in the player’s quest component copy and persisted in save data.

Quest Runtime Components

BP_QuestComponent (Player)

BP_QuestComponent is attached to the player and owns the full runtime state of all quests.

Responsibilities:

  • On game start:
    • Initializes its internal Quests array with a copy of all rows from DT_Quests.
  • At runtime:
    • Tracks progress across all quests:
      • current stage per quest;
      • DynamicQuantity for item collection stages;
      • QuestEngineData flags such as Finished, By NPC, NPC Tag.
    • Spawns and manages quest actors for FindItem and ReachZone stages based on S_ReqItemCustomTag and S_ReqZone.
    • Handles high‑level quest events:
      • StartNewQuest (from NPC or quest selection menu);
      • TryToFinishQuestStage(QuestID);
      • FinishQuest(QuestID) and Get Reward Finished Quest.
    • Integrates with the save system by providing a serialized snapshot of the Quests array.

Starting a Quest

There are two main ways to start a quest:

  1. From an NPC dialogue
    • The player talks to an NPC.
    • The dialogue ends with DialogueFinishedResult = GiveQuest.
    • The mediator calls BPI MM StartNewQuestNPC(Client) with a reference to the NPC.
    • The quest component (via NPC and mediator) reads the NPC’s ActualQuest or next available quest and calls its StartNewQuest logic.
  2. From the quest selection menu
    • The player opens the quest selection panel.
    • When the player presses Start on a selected quest, the UI passes the corresponding quest structure or UniqueID to StartNewQuest on BP_QuestComponent.
    • The component validates conditions (level, prerequisites) and activates the quest.

BP_QuestComponent determines which quest stages should become active and may spawn any associated quest actors (items, zones) according to the data in Stages.

Progressing and Finishing Stages

  • When the player performs relevant actions (collect items, reach zones, return to NPC), corresponding gameplay logic calls TryToFinishQuestStage(QuestID).
  • This function checks whether the current stage’s conditions are fully satisfied:
    • For FindItem stages: DynamicQuantity >= Quantity.
    • For ReachZone stages: the quest zone actor has registered that the player entered the zone.
    • For Go back to NPC stages: the player has talked to the correct NPC and completed the necessary dialogue.

If the current stage is completed, the component either:

  • Advances to the next stage, or
  • If this was the last stage, calls FinishQuest(QuestID).

Finishing a Quest and Rewards

FinishQuest(QuestID):

  • Marks the quest as finished in the component’s internal Quests array (for example, QuestEngineData.Finished = true).
  • Calls Get Reward Finished Quest, which:
    • applies rewards from S_QuestReward:
      • adds items to the inventory using item data and ItemData/Quantity or ItemsName/Quantity;
      • adds XP from Experience;
    • may trigger UI updates (quest complete messages, reward widgets).

The exact reward application logic is encapsulated inside BP_QuestComponent and cooperating systems such as inventory, stats and UI.

BP_QuestComponentNPC (NPC)

BP_QuestComponentNPC is attached to NPCs that can give quests.

Key fields:

  • Quests (array of DataTableRowHandle)
    List of quests from DT_Quests that this NPC can offer to the player.
    The list order defines priority: lower index means higher priority.

  • MovePlayerToSpeakerPosition (bool)
    If true, during dialogue the player is moved to the NPC’s SpeakerPosition (a billboard or socket) so that the dialogue camera can frame both characters correctly.

  • ActualQuest (DataTableRowHandle)
    The quest that this NPC is currently discussing or offering to the player.
    This state is local and not replicated across clients, so each player can have a different active quest with the same NPC.

Runtime behaviour:

  • When StartNewQuestNPC(Client) is called on the mediator for a given NPC, the system:
    • selects the next appropriate quest from the NPC’s Quests list based on index priority and conditions;
    • sets ActualQuest to that quest;
    • calls StartNewQuest on the player’s BP_QuestComponent with the corresponding quest data.

Save and Load (BP_GM_SaveComponent)

BP_GM_SaveComponent is attached to BP_GameMode and coordinates saving and loading of global and player‑specific data.

Quest integration:

  • When the player wants to create a save slot and confirms it in WB_SaveSlot, the widget calls:
    • GetGameModeGetComponentByClass(BP_GM_SaveComponent)Save Game to Custom Slot.
  • Inside Save Game to Custom Slot, among other logic, the component calls Formate Save Player Quest Data:
    • This function requests the current quest state from the target player’s BP_QuestComponent.
    • It reads the component’s Quests array (the runtime copy initialized from DT_Quests and updated during play).
    • The formatted quest data is then written into the save game.

On load:

  • The save system restores the quest data chunk and passes the saved Quests array back to BP_QuestComponent.
  • The component replaces its internal Quests array with the loaded data, restoring quest states, stage progress, and QuestEngineData.

DT_Quests itself remains unchanged at all times. Only the component’s runtime copy and save data are modified.

Dialogue System

Dialogue Data (FDialogueContainer and S_DialogueRow)

Each dialogue is stored in a separate DataTable, but all dialogue tables share the same row structure: FDialogueContainer.

FDialogueContainer fields:

  • Dialogue (S_DialogueRow)
    Main data block for a single dialogue node.

  • DialogueFinishedResult (enum)
    High‑level outcome when this dialogue sequence finishes:

    • None
    • AI Attack – the NPC attacks the player (used, for example, with guard‑type NPCs such as BP_Bot_MeleeGuard).
    • GiveQuest – the player accepts the discussed quest from the NPC.
    • GiveReward – the player receives the reward for a completed quest.
    • StartTrading – the trading UI is opened after the dialogue.
    • DeclineQuestRequest – the player declines the quest.
  • Visuals (S_VisualEffectDialogue)
    Controls camera behaviour during the dialogue:

    • ChangeCamera (bool) – whether to switch to a dedicated dialogue camera.
    • AttachCameraToCustomSocket (bool) – whether to attach the dialogue camera to a specific socket on the speaking character.
    • CustomSocket (Name) – the socket name used if AttachCameraToCustomSocket is true.

S_DialogueRow fields:

  • Phrase (S_PhraseWithOwner)
    The actual spoken line and visual data:
    • DialogueSide (E_DialogueSide: Player, NPC)
      Who is currently speaking.
    • Text (Text)
      Dialogue text for the line.
    • Hint (Text)
      Additional hint or sub‑caption.
    • Delay (float)
      Time to wait before switching to the next side or allowing input.
    • Voice (SoundBase)
      Optional voice audio for this line.
    • Face Animation (AnimMontage)
      Face animation montage played when this line is active (if not empty).
    • Body Animation (AnimMontage)
      Body animation montage played when this line is active (if not empty).
    • PhraseResult (E_PhraseFinishedResult)
      Special action after the phrase finishes, for example:
      • None
      • ShowRewardData – show quest reward data in the dialogue GUI.
    • Text Alternatives (Name[])
      Alternative text identifiers for this line; one of them can be chosen randomly to add variation.
  • Answers (array of DataTableRowHandle)
    List of possible answers / next lines offered to the player.
    If this array is empty, the dialogue ends at this node.

BP_DialoguesComponent and UI

BP_DialoguesComponent is the runtime controller for dialogues on the character. All dialogues pass through this component and a common UI pipeline.

UI widgets:

  • WB_DialogueOverlay
    • Master container for dialogue widgets.
    • Function NewDialogueIteration(DataTableRowHandle) initializes a new phrase based on the selected row in the dialogue DataTable.
    • Contains a vertical container SelectablePhrasesContainer that holds a fixed pool (for example, 8) of pre‑created WB_DialogueSelectablePhrase widgets.
    • These widgets are initially hidden. During the dialogue, visibility and displayed data are updated instead of creating and destroying widgets at runtime.
  • WB_DialogueSelectablePhrase
    • Displays a single selectable phrase (answer) for the player.
    • The player can click or select it to choose a response and advance the dialogue.
  • WB_QuestRewardData_Slot
    • Widget that shows the quest reward details (items, XP).
    • Displayed when PhraseResult == ShowRewardData on the current phrase.

Face and body animation:

  • When a new phrase is activated, BP_DialoguesComponent checks the Face Animation and Body Animation fields.
  • If they are not empty, it plays the corresponding montages on the speaking character.
  • This keeps all face/body animation logic data‑driven through the dialogue rows.

Integration: Quests, Dialogues, Trading and States

Dialogue State and Finish Flow

Dialogue runtime is integrated with the global State System via a dedicated state such as CharacterStates.UnusualSkills.Dialogue.

The typical end‑of‑dialogue flow is:

  1. The dialogue sequence reaches a terminal node (no Answers) or a predefined end condition.
  2. On the mediator for the player, BPI MM DC Finish Dialogue is called.
  3. The mediator calls BPI DC Finish Dialogue on BP_DialoguesComponent.
  4. The component reads DialogueFinishedResult from the current dialogue data and writes it into a variable (for example, Dialogue Action After).
  5. The mediator deactivates the dialogue state (CharacterStates.UnusualSkills.Dialogue).
  6. In the dialogue state’s DeactivateStateSolver, the system inspects Dialogue Action After and performs the corresponding action, such as:
    • GiveQuest – call BPI MM StartNewQuestNPC(Client) on the mediator with a reference to the NPC, then let BP_QuestComponentNPC and BP_QuestComponent coordinate the actual quest start.
    • GiveReward – trigger quest completion logic, which ends with FinishQuest(QuestID) and Get Reward Finished Quest.
    • StartTrading – open the vendor UI for that NPC (same flow as described in the trading and vendors documentation).
    • AI Attack – order the NPC to attack the player.
    • DeclineQuestRequest – no quest is started, and the system just returns to normal gameplay.

This design keeps all high‑level narrative actions data‑driven in dialogue tables, while the mediator and components execute the correct gameplay logic.

Trading via Dialogue

The trading system uses the same interaction and dialogue pipeline:

  • The player interacts with a vendor NPC via BP_InteractComponent.
  • Interaction triggers dialogue under the dialogue state.
  • At the end of the relevant dialogue node, DialogueFinishedResult = StartTrading.
  • After finishing the dialogue state, the solver detects StartTrading and opens the vendor UI for that NPC.

The details of trading logic and vendor state persistence are documented in the trading and vendors system, but quests, dialogues and trading all share the same interaction and state flow.

Typical Flows

Taking a Quest from an NPC

  1. The player approaches an NPC with BP_QuestComponentNPC and interacts via IAInteract.
  2. BP_InteractComponent and the mediator activate the dialogue state and open the dialogue UI.
  3. The dialogue runs using the configured dialogue DataTable (for example, from Give Quest Dialogue in the quest’s general data).
  4. At the end of the conversation, DialogueFinishedResult = GiveQuest.
  5. After the dialogue finishes:
    • BPI MM DC Finish Dialogue and BPI DC Finish Dialogue run.
    • Dialogue Action After is set to GiveQuest.
    • The dialogue state is deactivated, and DeactivateStateSolver sees GiveQuest.
    • The mediator calls BPI MM StartNewQuestNPC(Client) with the NPC reference.
    • The NPC’s BP_QuestComponentNPC selects ActualQuest from its Quests list and passes it to the player’s BP_QuestComponent.
    • BP_QuestComponent calls StartNewQuest with the selected quest structure.

Completing a Quest

  1. As the player plays, BP_QuestComponent tracks stage progress using TryToFinishQuestStage(QuestID) on relevant events (item pickup, zone reached, NPC interaction).
  2. When the final stage is complete, TryToFinishQuestStage calls FinishQuest(QuestID).
  3. FinishQuest:
    • updates the runtime quest data (for example, sets QuestEngineData.Finished = true);
    • calls Get Reward Finished Quest to:
      • grant items from ItemData/Quantity / ItemsName/Quantity;
      • grant XP from Experience;
      • update UI with completion and reward information.
  4. If the quest is designed to also have a completion dialogue (for example, End Quest Dialogue), that dialogue can run and use DialogueFinishedResult = GiveReward to visually frame the completion.

Saving and Loading with Active Quests

  1. The player opens the save UI and selects a slot in WB_SaveSlot.
  2. The widget calls Save Game to Custom Slot on BP_GM_SaveComponent.
  3. The save component:
    • calls Formate Save Player Quest Data on the target player;
    • reads the player’s Quests array from BP_QuestComponent;
    • writes the quest data into the save game.
  4. Later, when loading:
    • the save system restores the saved quest data;
    • the restored Quests array is assigned back to BP_QuestComponent;
    • quest and stage progress continues exactly where it left off.
  • ./character-modules/character-modules.md
  • ./state-system/state-system.md
  • ./interaction-and-items.md
  • ./trading-and-vendors.md
  • ./abilities-and-unusual-skills.md
  • ./save-load-system.md