[C++] Quest system implementation ideas

Good day, community!

Currently I’m working on making quest system for Unreal Engine. So maybe someone done it earlier and can share ideas and patterns for making this?
For myself I worked a long time ago on quest system in small minigame in Unity and here is the main concept of this: In level I have “MissionManager” singleton, which have array of all quests and an ID of current quest. When some actions is happends (pick money, kill monster, etc) script of monster/money calls function “UpdateMission” of “MissionManager” singleton with some parameters. Main idea that “UpdateMission” of “Money” script have integer parameter and “UpdateMission” of “Monster” have bool parameter. So “MissionManager” can distinguish update mission one from another.

But as time passes, I came to idea that it’s not a good pattern at all! It’s very complex, not re-usable and each mission type have many unused virtual functions ('cause every mission type have one parent class).

I can’t find any good articles about that in Google, so, let’s discuss about best concept of implementation quest systems! What ideas do you have?

Hey,

i recently tried to make Questsystem, so far its working well and it can be used for designers and modders to create their own quest.
My concept is similar in terms of using a QuestManager holding ActiveQuests in an Array, Starts, Ends or Updates them.
Each quest consists of States represented by a script. There is only one State active inside a running quest. When a State was activated it Starts the Script (f.e. MoveTo, TalkTo or even AI_DoSomething, PlayConversation)
There is a table where those scripts are stored and when one Script ends it has information about what state comes next out of that table. It refers to DFA (Deterministic Finite Automat) and its working very well so far.

I would recommend taking a look at this page:
http://gameprogrammingpatterns.com/

He explains about an Achievement system, and suggests the use of the Observer design pattern!

The observer pattern is nice to use when events and listeners are needed, which enabled you very good loose coupling.

It can be used within a questsystem i think, so for things like when specific actors needs to be notified that something happened. But this would require you to write specific logic for these cases, and since Quests are similar but not the same, i feel you end up catching special cases. This is just an assumption though.

But the book is indeed a good starting point, maybe you also have a look into the “State”-Pattern, which is what i have done.

Thank you all for this great answers!

Great book, thank you! Why I didn’t found it earlier?
Observer design pattern are pretty interesting and supplies system, which I needed. But in that article, author noticed that it can be futher developed with event system. Since Unreal Engine 4 does have Delegates (Unfortunately, wich I’m not so familiar, but I’m gonna learn it in this week!), so it can be developed with them? Has someone done this before?

I’m going to check this pattern too! Thank you!

I did an EventSystem.

The guys McShaffry and Graham wrote a really nice Book, where they also introduced a well-explained usage of an EventSystem. Though they used
fastdelegate lib for delegates and went for an templating approach my Event System uses interfaces.

Means, there are IEventListener and IEvent and the EventManager deals with those. The main idea is that someone (really everywhere in your code) one can create an Event (fills it with info) and sends those
to the EventManager. The Manager holds a queue of those Events and iterates it via “First come first served” (you can add priorities of course too). The Manager also has a List of Listeners for each EventType and during an iteration he will
notify each Listener with the Event and its data.

For a listener to receive Events of a specific type he needs to register for it first via EventManager.

Thanks for the book, I’m gonna check it up!

So, I guess, is no build-in EventManager inside Unreal Engine 4? Unity had one there, unfortunately that Unreal doesn’t have it

No you got me wrong.
Unreal already provides you decoupled communication (Function Pointer, Event Dispatcher). Though as far as i have worked with Unreal, it seems that in most cases one side always needs to know about the other. I dont know if there really is an Event-System Pattern Approach available.

After a short google i found this one here: A new, community-hosted Unreal Engine Wiki - Announcements - Epic Developer Community Forums

Just to get an idea of that pattern

Here is something to start with from the Wiki: https://wiki.unrealengine.com/Quest_Framework. But it seems a lot of implementations suggest an evented state machine and track progress via an observer. But some suggestions from the docs is to perhaps have the GameState and PlayerState class implementations track quest state.

Some thoughts of mine about this:

  • The idea to make the Quest AActor as base isnt very wise to choose. I assume it is because BeginPlay and Tick which is also not a good idea fmpov. But every quest has many things from actor it will probably never need (like a Transform, InputComponent a.s.o)

  • One good thing with an event driven system is that you can have less Tick functions. In his example the tick function is obsolete too.

  • instead of BeginPlay i would assume to have custom Start/Update/End functions.

  • the next thing is that even Objectives are actors, which he spawns on BeginPlay. Usually you process through a quest from Objective to Objective, there is probably no need to have all of them “Spawned” at the same time. Well it really depends if a quest is considered as a whole or there might be a Quest holding an array of Subquests each with own objectives…

  • I would use UObject as a base, so a baseclass with minimal overhead. And maybe the gameinstance to keep quests alive during Level transition. Since he spawns his quests in a world means, as soon as he switches to another level will probably lead to problems.

  • in the end the idea is always the same: A quest has conditions and is alive until we succeeded or failed them. But what are conditions exactly? Maybe a condition is “TalkTo_Cthulhu”, when this condition gets activated by the quest, how do you notify your quest system about the update? Well, one way might be to have somekind of callback you register when the player talks to someone and check if its “Cthulhu”. If it is, mark this condition as solved and maybe activate another which was dependent of the previous.

Kind regards

Hey. My Quest implementation (the one I created after this wiki article) follows along similiar to what you have state you would do. I had a UObject base class that was call UMission that was merely a collection of UObjectives (where they were also UObjects, marked with a Within UCLASS specifier to exist within only a UMission, while have type safe access to it’s outer’s interface). From there each UMission had UReward objects to support adding a reward system. Each of my UMission objects implemented BeginPlay, Activate, EndPlay, Deactivate, GetWorld, GetLifetimeReplicatedProps, ReplicateSubobject (to replicate UObjective and UReward Collections and children UMission Objects). From there, I added an entirely evented system as well. I also implemented several UObjectives for common event handling. Such things were Time Trials using the TimerManager and custom Notifications received from various Actors in the Game.

However, from there, to support networking, you would also need to get some kind of interface for the UMission to interact with the world. These interfaces could be something as making it a Subobject of an AActorComponent to make easily plug and play into your game. Another way would be to make it a Subobject of an AActor class (which supports subobject replication without hassle and RPC) such as AGameState (Server Only) or APlayerState (Replicated to all Clients).

Couple things to mention about your argument against using AActor. It is not just for BeginPlay and Tick. It is because of the fact that they support the replication of subobjects out of the box, they support RPC out of the box, AInfo does not have a Transform within the world, it is the whole point of the class, to have an Actor that does not have a position within the world - just information. AActor does not have to have any Components and perhaps the use of components would be an easy way to extend the AQuest object.

However, the most painful part of the whole Quest thing within UE4 is that most system that are for sale fail on multiple accounts due to being data driven. This leads to generic, flat, and uninspired quests. The best quest system would be able to be dynamically created, that is why UObjects are best, AActors should be used for ease of use / prototyping, and custom implementations do not require a lot of overhead. Finally, the hardest part would be implementing a good design UI for your quests.

In a closing note, using AActors would be easier for a beginner, as UObjects require a lot of work and integration if it is to be a multiplayer game. On top of that understanding how instancing and DataAssets work would be more overhead as well. But, there are always a hundred ways to do the same thing when it comes to programming.

Final Remarks: " in the end the idea is always the same: A quest has conditions and is alive until we succeeded or failed them." - I find this the crux that quest systems lack robustness. Would it not be better to implement quests more like a dumb weight based AI system that selects the result of a quest completion test? I find that questing does not have to be/is not binary in nature.