Where to Store Market Orders for NPC Market and NPC Quests for the Quest Log

I’m creating a general job board/market board in my RPG where all quests are stored. Quests can be a bunch of different things from killing an enemy to going to a place to buying an item(s) for a special price. The way it works is there are quest sub-objects for all kinds of tasks you can complete in the game. For example there might be a quest posting for an NPC shop where the player can accept the “quest” and then go pay a specified amount for an item in an NPC Shop inventory.

My question is - what storage architecture is generally best for these types of quest boards? The NPC will have a bunch of functionality that needs to be triggered.

  1. It issues the quest to the board where the player can see it when it has the relevant item
  2. It stores the inventory item in its inventory component until the player goes to the NPC
  3. It can retract the quest after a certain amount of time
  4. If the NPC dies or loses the item for some reason ( or something else - i.e. game progresses and the area isn’t accessible) it will automatically retract the quest from the board etc.

The question is - how should I set up the reference to the NPC and its quest to trigger these things?

  1. I could make the NPC ignorant of it’s own quests and store all the data in the quest on a quest board manager - the quest object would likely have to regularly check the NPC inventory to ensure the item was still there or check the target location to kill an enemy to make sure it was still available etc.

  2. I could have the NPC quest giver track the quest - and regularly check its inventory and availability to see if it should take the quest down or post a different one. In the killing case it would have to track the monster’s alive status and whether the player killed it

  3. I could store the quest in the target - ex the monster needing killing or the inventory item to buy (this might be weird because my items are structure data when in inventory) will check its status and modify the quest.

  4. some combination of these

Not sure how people regularly handle this - maybe event dispatchers in the object like “on change inventory” runs a function in the quest object?

This kind of issue is confusing to me in several areas of development - so a best practice would be appreciated.

Hey @behastie!

I would say… An actor component, attached to the player.

But that’s just me! You could put it so many places! Especially considering it would just be a bunch of variables. You could put it in the Game State, Game Instance…

I’d use one actor that’s your quest board, then when a quest is accepted it moves that over to your player’s actor component (Something like AC_Quests) and have that store all of the data for accepted/completed quests!

Hope that helps! :slight_smile:

1 Like

Heya @behastie!

Did you figure out how you’re going to do it? What design did you end up going with? Did you use tutorials etc etc. Let us know for future answer seekers!

Yes, I ended up creating the following structure where a central board manager manages and filters all quests and the quest object manages all quest functions like incrementing goals, sending rewards, keeps track of issuer and accepting actor so that the actors themselves never need to have a reference to the quest object.

ACTOR_BOARD_MANAGER - with an array of OBJ_QUESTs, can CRUD quest list and return data to other actors through functions
ACTOR_NPC - with an inventory component, can ask the BOARD_MANAGER to do things
OBJ_QUEST - contains all variables and functions related to an order and event dispatchers that get called (ex. OnOrderFilled) including the issuing and accepting actor, reward etc.
PAWN_PLAYER - can accept orders/quests

ACTOR_NPC has inventory, desires, quirks etc., anything I want to code normally for my game. The ACTOR_NPC tells the ACTOR_BOARD_MANAGER to create an OBJ_QUEST to store whatever it wants on the BOARD_MANAGER actor, which acts like a singleton database in a streaming level (would use GameInstance if I wasn’t using a persistent streaming level), with the SELLER marked in the IssuingActor variable. Seller does not keep track of its own postings, the board manager will return postings with a specific variable filtered.

So, If the PLAYER or any NPC accepts the order, the BOARD just adds their actor to the “AcceptingActor” variable. Then if the player wants all their quests quests in their UI, for example, the Player UI just asks MISSION_BOARD to give it all quests with where AcceptingActor = PAWN_PLAYER and posts the returned data in the UI.

So, If I want to create some arbitrary quest sub-type where the AcceptingActor say needs to add 10 orbs to a florb, I write the Add Orb to Florb function in the Actor, then every time the Orb function is called in the actor it gets the mission board and asks it to increment all quests where QuestType = OrbInFlorb and AcceptingActor = Self. When the quest has incremented 10 times OBJ_QUEST calls OnQuestFulfilled, distributes rewards to the AcceptingActor, takes the inventory from the IssuingActor etc. BOARD_MANAGER is bound to the OnQuestFulfilled dispatch and removes the quest from the array.

This way NPCs, Players etc. never need to know what the quest object is, they just talk to the board manager and ingest the data it sends back as a snapshot. So an NPC on an Orb Florb quest would just know from the board manager that the most valuable thing it could do is search for orbs, while the player can see a list of quests without their player pawn needing to mess with the object itself.

1 Like