Hello y’all,
TLDR: In UE, how can I make my current quest system more lightweight and discard the current heavy references and includes I currently use with the delegate approach?
Problem: I have made a functioning and modular Quest\task system built in C++. It works perfectly and accounts for any possible objective that can be given. However, some of the objectives have includes of the PLAYER CONTROLLER!! They have these includes because they use the ue delegate system to listen for objective updates (player added item to inventory, player built specific structure, player picked up currency, etc.) Everything works but I would like this system to work without the references to player within the objectives as I want to make the system as lightweight as possible. In UE, how can I make this system more efficient and how can I handle updating objectives and sub objectives in potentially hundreds of quests without referencing the player?
Quests - A container of linked objectives.
Objective - Usually simple logic that waits for a specific event to fire and then checks if a certain requirement has been met. (ex: Has collected 200 gold, has traveled to HyperSweden)
Event - This is less defined. Sometimes an objective is just bound to a trigger box. Other times, I use the ue delegate system on the quest and listen for things the player does.
The quest system is very simple. It is a quest actor, AQuestBase, with an arbitrary number of objectives, UObjectiveBase, than can have and can implement any arbitrary completion structure (linear objectives, multiple objectives, timed objectives). An actor component on the controller simply holds onto a map of incomplete quests and complete quests and handles all the logic around them.
-
My first thought to fix this heaviness was on each event (pick up money, go to location, build a structure,etc) to iterate over each quest and get each active objective and see if we have satisfied it’s requirements. However, this would scale very poorly and would be ridiculous when given a hundred quests and many hundred more objectives.
-
Another thought was to have different arrays of objectives the player has that would be searched through on each event. However, this would mean dozens of unique arrays and would be difficult to manage.
-
Another would be to leverage a world event system plugin I bought from the marketplace but this would require weird roundabout connections and would obfuscate bugfixing as the event system only works with actors.
Is there some special hidden secret ultra rare functionality I have overlooked in UE? It’s a big engine so I wouldn’t be surprised if I overlooked a simple solution.
I would like the objectives to function in some generic way so that it can work equally with my currency system, building system, and state machine system. At the moment I have only been to do this with hard references to the player using the delegate system.
Edit 1: The global event system (observer pattern) option may be a good approach. Have the player simply broadcast to the event with any payload. The quest actor (that is listening for that event) then takes the payload and sends that to it’s objective [Ex: EnterStateObjective->CheckEnteredState(StateEnumPassedByEventObject)]. We still have a reference to an outside object. However, this is a relatively lightweight object (especially compared to the monstrosity that is the player controller and its components.) This also would require a little more code and a partial change to the way the objective class functions. ~also the plugin occasionally causes crashes ~