Ultimate Quests and Achievements Component

Documentation

Features

  • Unlimited quests and achievements  - create as many quests and achievements as you need using data tables.
  • Timed quests - timed quests have to be finished in a given amount of time. When time runs out they will be marked as failed.
  • Chained quests - quests that automatically activate one after another.
  • Repeatable and restorable quests - quests can be repeated the desired number of times. At any time you can "restore" it so it can be repeated again (ie. MMOs daily quests).
  • Quests requirements - determine which quests have to be finished in order to make particular quest enabled (can be expanded by level, items etc. functionality).
  • Quests unlocking - sometimes it may be needed that quest will be enabled in several different ways and choosing one of them will unlock the quest. (eg. we have battleground quest which is enabled after one of the faction quests is finished, we have 3 different factions and they cannot accept quests which do not belong to their side so finishing either of them will unlock that battleground quest).
  • Quest indicators - add floating indicators to your NPC, world objects and enemies.
  • Quest tracker - display desired quests progress in the handy window.
  • Limited or infinite space in quest log - determine how many ongoing quests player can have.
  • Single objective-oriented achievements - each achievement have only one objective although there can be many achievements that require the same objective to progress.
  • Achievements progression - make one achievement visible when other is finished to keep progress consistent and not overwhelming to a player (eg. we have 5 "tiers" of achievement with the objective "Accumulate Gold", each of them requires more gold than the previous one, so you may want to display to a player only the one currently active and once it is finished new one will show up in achievements window).
  • Quests and achievements rewards - fully customizable rewards for both systems.

Implementation


Once components are added to the blueprint you will need to initialize them. To do this use two function InitializeQuestsManager and InitializeAchievementManager. Remember to call them after all widgets are created because they also will assign proper references.

Important: for multiplayer games, these functions have to be called on the server side.
Check demo player controller blueprint for example set up.

To implement quests system to your game just add AC_UQC_QuestsManager to your Player Controller or Character blueprint.

Steps to do:
Open blueprint actor that you want to add quests system to.
Navigate to its Components tab.
Click the green +AddComponent button and from the dropdown list choose AC_UQC_QuestsManager.
Click on newly added AC_UQC_QuestsManager and navigate to Details tab.
Find Config category and set up default data.
  • MaxOngoingQuestsAmount - how many quests can be active at a time.
  • WidgetsUpdateFrequency - used to control how often quests data is sent from server to client to update the widgets. Eg. The quest requires from a player to kill a specific monster. Each time the player kills that monster objective progress is updated on the server and sends info to the client, so it is proper progress count displayed in widgets (ie. quest tracker). However, if the player kills 10 monsters with a single hit we do not want the server to send info to client 10 times. So we set WidgetsUpdateFrequency to 1 second, it means data will be sent to the client once every second (including all quests that have been progressed during that time). INFO: For single player games it can be set to 0.0 so widgets will be updated instantly.
  • DebugEnabled will toggle printing of all debug messages from QuestsManager component.

To implement achievements system to your game you need to take exactly the same steps as you did to implement quests system.

Steps to do:
Open blueprint actor that you want to add achievements system to.
Navigate to its Components tab.
Click the green +AddComponent button and from the dropdown list choose AC_UQC_AchievementsManager.
Click on newly added AC_UIC_AchievementsManager and navigate to Details tab.
Achievements component doesn't require additional configuration.

Creating new quests

All quests added to the game are stored in DT_UQC_Quest data table. You can edit existing quests there or create new ones. If you wish to extend quest data you can edit S_UQC_QuestStatic structure.

Each quest data consists of:
  • ID - unique quest ID used in the system functionality. IMPORTANT: ID must be the same as the name of the row in the data table.
  • DisplayName - the name of the quest displayed to players (ie. in widgets).
  • Description - the description of the quest displayed to the player (ie. in widgets).
  • Type - used to organize quests into groups. More quest types can be added to the E_UQC_QuestType enumeration asset.
  • MaxRepeats - how many times the quest can be repeated. 0 means indefinitely.
  • RequiredFinishedQuests - list of quests player has to finish before this quest can be accepted.
  • Objectives - quest objectives structure. Each objective consists of an ID, text to display to a player and its required amount (progress).
  • FinishAutomaticallyOnObjectivesCompleted - determines whether quest should be finished automatically once all objectives are completed.
  • FinishQuestInfo - text that will be displayed instead of the list of objectives when all objectives are fulfilled (ie. in quest tracker window). Leave empty if you still want to display the objectives list.
  • AcceptNewQuestsOnFinished - what quests will be "granted" to a player and accepted automatically when this quest is finished. INFO: These quests still need to meet requirements to be accepted.
  • UnlockQuestsOnFinished - list of quests that should be "unlocked" when a particular quest is finished. INFO: Some quests may require finishing other quests to be enabled, other time it may be needed that quest will be enabled in several different ways but choosing one of them will unlock the quest and it is not necessary to finish all of them. (eg. we have battleground quest which is enabled after one of the faction quests is finished, we have 3 different factions and they cannot accept quests which do not belong to their faction so finishing either of them will unlock that battleground quest).
  • UnlockedByDefault - determines whether quest should be "unlocked" by default and visible to players (of course as long as requirements are met).
  • Removable - determines whether quest can be aborted.
  • AutoAbortWhenFailed - determines whether quest should be aborted automatically on its failure.
  • AutoTrackWhenAccepted - determines whether quest should be automatically added to the tracker when it is accepted.
  • Reward - rewards that a player will receive when the quest is finished.
  • TimeToComplete - time to complete the quest. When time runs out quest will be marked as failed. If you set it to 0.0 quest won't be timed.

Quests management


Quests management consists of 2 parts:
A. Functions called on the server side and executed on the server side, they should never be implemented to be called on the client side (of course if it is a single player it doesn't matter because there is no server-client relation). These functions are:
  • AcceptQuest - adds a quest to player quest log.
  • AddQuestObjectiveProgress - increases the progress of given objective of all ongoing quests.
  • FinishQuest - finishes given quest.
  • AbortQuest - removes given quest from quest log.
  • FailQuest - makes given quest failed.
  • ResetQuestProgress - set the progress of all objectives of given quest to 0.
  • RestoreQuest-  makes quest acceptable again, like it wasn't finished previously.

B. Events called from client to execute the corresponding function on the server like client let the server know that he wants to accept a quest displayed in a pop-up window (again if it is a single player game they just will be executed normally on the player side because there is no server-client relation). Usually, they are tied up to specific buttons in widgets so a player can make a request. These events are:
  • AcceptDisplayedQuest_SERVER - accepts the quest that is currently displayed in Quest Popup Window.
  • FinishDisplayedQuest_SERVER - finishes the quest that is currently displayed in Quest Popup Window.
  • ProceedDisplayedObjective_SERVER - adds progress of particular objective displayed in Objective Popup Window to all ongoing quests. It can be used with dialogue lines as well, ie. when specific dialogue is performed or selected by a player you may want to increase objective progress.
  • AbortQuest_SERVER - aborts given quest on player request.
  • TrackQuest_SERVER - tracks or stops tracking given quest on player request.


To prevent modifying the system by players first three events called from the client don't have input variable and you cannot specify what quest should be accepted and finished or which objective should be progressed. Instead, you should set QuestID to the corresponding variable in QuestManager component (there is one name type variable for each event: DisplayedQuestToAccept, DisplayedQuestDisplayedToFinish and DisplayedObjectiveToProgress). Events will read QuestID from these variables and perform functionality basing on them.  There is an example set up in demo controller blueprint.

Quest indicators

The system provides support for displaying floating quest indicators commonly used in RPGs. You can customize what happens and how the indicator looks:
  • when NPC has a quest to accept or finish
  • when objective can be interacted (ie. for gathering quests)
  • when a particular enemy is required o finish quest
  • and all these similar situations.
You can also tie indicator behavior to specific quest parts (ie. different color for story, side, and repeatable quests).

To implement indicator functionality to an actor open its blueprint and add AC_UQC_QuestIndicatorComponent. You will get access to a special event (right click on the newly added component, hover over the AddEvent option and select OnIndicatorStateChanged). Use this event to implement custom behavior for each indicator state. You can check example set up in demo NPC blueprint.


You can also determine the order in which "quest states" are displayed. The default order is:
  1. QuestCanBeFinished
  2. ObjectiveCanBeProgressed
  3. QuestCanBeAccepted
  4. N/A.

It means that if NPC has a new quest to accept but also has one quest can be finished at him it will display the indicator assigned to quest finishing (also if we talk to him the first option that pops in will be quest finishing), once quest is finished indicator will turn its state to "AcceptQuest". "N/A" state is activated when there are no quests to accept or finish and there are no objectives to progress. You can edit indicator priority in AC_UQC_Indicator component (variable QuestIndicatorDisplayPriority).

Creating new achievements

All achievements added to the game are stored in DT_UQC_Achievments data table. You can edit existing achievements there or create new ones. If you wish to extend achievement data you can edit S_UQC_AchievementStatic structure.

Each achievement data consists of:
  • ID - unique achievement ID used in the system functionality. IMPORTANT: ID must be the same as the name of the row in the data table.
  • DisplayName - the name of the achievement displayed to players (ie. in widgets).
  • Description - the description of the achievement displayed to the player (ie. in widgets).
  • ObjectiveType - objective assigned to the achievements (each achievement can have only single objective assigned but multiple achievements can share the same objective). More objective types can be added to the E_UQC_AchievementObjective enumeration asset.
  • RequiredProgress - progress amount required to complete the achievement.
  • Reward - rewards that a player will receive when achievement is completed.
  • VisibleByDefault - determines whether achievement should be displayed in the achievements window by default (or does it need to be toggled from other sources ie. completing previous tier achievement).
  • AchievementsToShowOnFinished - list of achievements that will be shown in the achievements window when particular achievement is completed.

Achievements progression


To increase progress of specific achievement objective use AddAchievementsProgress function. It will add given amount to all achievements sharing the same objective. Achievements will be automatically finished (and grant reward) when progress reaches required amount.

NOTE: In multiplayer games always call this function on server side.

Rewards

Quests and achievements rewards are highly tied to what game offers, they can be commonly met experience points, in-game currency, items. Players can also be rewarded with very specific rewards like a new character or skill. Since rewards vary on game type and other systems implementation there are blank functions provided in quests and achievements system where you can implement you rewards functionality. Look for functions: ReceiveQuestReward and ReceiveAchievementReward. You can also easily extend rewards data by editing S_UQC_QuestReward and S_UQC_AchievementReward structures.

Updating widgets data

Data displayed in widgets is mostly updated by two interfaces:
  • BPI_UQC_QuestsUpdater - for quest related data
  • BPI_UQC_AchievementsUpdater - for achievements related data.

Add proper interface to a widget so it will receive events whenever quests or achievements data changes. Implement quests related logic in the widget using the following events:
  • SetQuestsManagerReference - executed on Quests Manager initialization, used to assign to widgets proper Quest Manager component.
  • AddQuestToQuestLog - executed when a player accepts quests and it is added to ongoing quests list.
  • RemoveQuestFromQuestLog - executed when a quest is removed from ongoing quests list (either by player request or on quest failure).
  • MarkQuestTrackedStatusInQuestLog - executed when quest starts or stops being tracked.
  • UpdateObjectivesProgressionInQuestLog - executed whenever objectives progress changes.
  • MarkQuestFailedStatusInQuestLog - executed when quest fails (ie. when time runs out).
  • UpdateDisplayedQuestTime - executed when a quest time changes (can be used for updating quest time in quest tracker and in quest log at once).
  • ShowQuestInfo - executed when a player requests to see quest details (ie. by pressing on given quest slot, what results in displaying quest details).

Implement achievements related logic in the widget using the following events:
  • AddAchievementToWindow - executed when new achievement is added to ongoing achievements list (generally all achievements are added upon component initialization).
  • UpdateAchievementsProgressInWindow - executed  when achievement progress changes.
  • SetAchievementVisibilityInWindow - executed when given achievement visibility state changes. (ie. player completed the achievement of tier 1 and now it should display tier 2 in achievements window).

By default, all widgets with implemented QuestsUpdater or AchievementsUpdater interfaces will be updated. However, there is a special function to limit the scope of updated widgets. Both QuestsManager and AchievementsManager have AddWidgetsToRefresh function. Just pin array of desired widgets and system will update only these specific widgets.


You can check detailed communication set up in premade widgets: WBP_UQC_QuestLog, WBP_UQC_AchievementWindow and WBP_UQC_TrackerWindow.

Save and load

Both QuestsManager and AchievementsManager component have their own function that handles saving and loading functionality.

Although they are very similar save functions and respectively named SaveQuestsData and SaveAchievementsData, they all have the same two inputs:
SaveName - how save file will be named, remember to use different names for different actors, unless you want to overwrite the data.
SaveToGameInstance - determines whether the game should be saved to the game instance or to separate save file on a device.

Data saved to the game instance will be stored only during a single game session and it will be wiped after the game is closed. Use it to temporarily store data, ie. when changing levels. Data saved to file (using standard SaveGame object) will be stored on a device even when the game was closed. It can be accessed each time the game is started to load stats data. Depending on your needs you may use a single method or mix them.

Components data can be loaded in an analogous way, calling one of these functions: LoadQuestsData and LoadAchievementsData. They have two inputs as well:
SaveName - name of the save file to load stats data from or a name of a key of map variable stored in the game instance.
LoadFromGameInstance - determines if stats data should be loaded from a game instance or from save file stored on a device.

If you call these functions during the initialization process (ie. just after a new level was loaded) put them at the very end, so all widgets are already created and components are initialized.

To ensure smooth implementation of the saving system to your game project without overriding any of your data use BPI_UQC_SaveCommunication blueprint interface, which can be found in Blueprints>Interfaces folder. Open your custom game instance blueprints, navigate to ClassSettings and on details tab you will find the option to add interface and compile blueprint. Open BP_DemoUQC_GI_Custom blueprint located in Demo Blueprints folder and copy or recreate its functions and variables.
If you don't use the custom game instance, but you still want to use save system with game instance you can use the one which is used in demo content (or a copy of it). It has the saving system already implemented.

Important: Remember that this save functionality is created primarily for single player games because of multiplayer games rather store data externally.