🕹️Setting up the quest in-game

🎮 Unreal Setup (Gameplay Logic)

The Unreal side of an ODK Quest handles how the player interacts with and completes tasks, and ensures that quest progress reflects the player's on-chain token balance. The system uses BP_ODK_TaskFlow actors, Quest-specific task executors, and wallet integration to create a fully synced experience.

For the creation of the Quest token see Creating a Quest token


🔹 1. Add a BP_ODK_TaskFlow Actor to the Level and create a Task PDA

The Task Flow documentation outlines exactly how to set this up

In your new PDA_ODK_TaskFlow:

  • Add a new item to the Tasks array

  • Derive each Complete Task Triggersfrom BP_ODKTaskFlow_QuestTaskBase(described below) — these define what in-game conditions complete the task (e.g. jumping, running)


🔹 2. Use the Correct Base Class: BP_ODKTaskFlow_QuestTaskBase

For quests, each task must derive from BP_ODKTaskFlow_QuestTaskBase.

This subclass is essential because:

  • It handles sending the token to the user when a task is completed

  • Unlike standard tasks, it does not automatically progress

  • Instead, it waits for the player to receive the token, then:

    • Reinitializes the flow trigger

    • Uses the user’s token balance as the task index

This means:

  • Token ownership becomes the single source of truth for progress

  • You don’t risk out-of-sync task flow states

  • Tasks remain paused until the player actually holds the correct number of tokens

All derived tasks should still call:

Trigger Execution Complete

...once the task’s completion criteria has been met.


🔹 3. Getting Quest Token IDs in Tasks

To associate tasks with the correct Token ID, you need a way to retrieve the ID. This can be done per task — but that quickly becomes repetitive.

Instead, use the built-in system based on BP_GetTokenIDBase, which has two helpful options:

  • BP_GetTokenIDFromCustomDetails

  • BP_GetTokenIDFromLiveConfig

Recommended: BP_GetTokenIDFromCustomDetails

  • Each task checks the custom details of the Data Asset

  • You define a single source of truth inside the asset, and all tasks reference it

You'll need to define a custom detail entry in the Quest Data Asset to use this.

This means less setup repetition and centralized management.

Alternate: BP_GetTokenIDFromLiveConfig

  • Allows dynamically retrieving token IDs from a live config

  • Useful for centralized overrides or managing IDs per environment


🔹 4. Activating a Quest

Quests are only activated when the player receives the first token.

This should be granted as part of your experience — how you do this is project-specific.

The easiest way is via:

BPFL_ODK_WalletHelpers → GrantTokenToWallet

In the ODK sample, tokens are granted by Interacting with an NPC. This opens a web overlay with available quests.


🔹 5. Granting the Achievement (Reward Tokens)

If your Quest Token includes a rewards array (tokens to grant upon completion), you can automate this via:

BP_TaskFlowAction_GrantAchievementFromAttachedToken

We recommend this is assigned to the TaskCompleteActions of the final task, but could also be assigned to FlowFinishedActions.

Why? Because technically the flow never completes in the traditional sense — it’s driven by token sync, and the player could hold the final token before the system registers a full flow completion event. Adding it to the final task will speed up execution.

This approach ensures:

  • Rewards are reliably granted

  • The grant is tied to the token logic, not just the internal task flow state

🔹 6. Displaying Quest notifications

By default, the player's BPMC_ODK_WalletComponent, found on BPM_ODK_PlayerCharacterBase, contains a TokenHandlers map.

This map listens for changes to tokens and routes behavior accordingly.

Out of the box, the wallet includes:

  • "achievement" handler

  • "quest" handler

The map’s key must match the type field in the token metadata — for quests, this is "quest".

When a token is added, removed, or updated:

  • The appropriate handler is triggered

  • You can use this to:

    • Display UI

    • Fire off effects

    • Trigger game logic

If you need additional behaviour, you can subclass the default handler and override its logic.

Last updated