4
\$\begingroup\$

I am working on an fantasy RPG and I would like to get some ideas about how I am implementing Quests.

Quests in my game are very generic. The quest goal can be almost anything in the game. The goal can be: press a GUI button; pick up a certain object; kill a creature; steal an object; collect 10 items; walk to a certain location; etc. Therefor, quests need to be somehow tied to many other objects in my game.

I've been flirting with the Observer design pattern, but I'm not sure if this is the best approach.

Currently, my Quest Manager singleton is an observer, and it registers itself with many subjects. For example, I have a menu class with GUI buttons that has an EventHandler, and the Quest Manager registers with the menu class to have its own function called when a certain button is pressed. When the function gets called, the Quest Manager checks to see if the "Press the button" quest is in progress, and if it is, then that Quest becomes "Completed"!

Is this a good design or are there other design patterns that I should consider?

\$\endgroup\$

closed as too broad by Vaughan Hilts, Maximus Minimus, Jari Komppa, MrCranky, Anko May 19 '14 at 16:08

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 1
    \$\begingroup\$ Hi, generally questions that have multiple loosed ended outcomes will end up closed here. Could you perhaps narrow down your request? \$\endgroup\$ – Vaughan Hilts May 18 '14 at 23:10
  • \$\begingroup\$ frankly, I understand your drive of wanting to do fancy software engineering and all, its fun to apply patterns, and its fun to design :) however I would tend to philosophize that it is not that important, just code your game on the fly and it'll work. you have something to do, think a bit by yourself, do it. No need to invoke other people generic recipies when you can bake your own and be satisfied as well. Nobody said that patterns are necessarily cleaner for every problem. \$\endgroup\$ – v.oddou May 19 '14 at 0:29
  • \$\begingroup\$ I've pretty much always done "on the fly" programming in the past, and I guess that has worked for me so far. I'm just trying to take a more pro-active approach this time. \$\endgroup\$ – LVBen May 19 '14 at 2:13
  • \$\begingroup\$ I decided to close-vote because I foresee many possible answers and no way to definitely say which is correct, as the "best solution" depends on game, tech stack and development style. This would change if there were a specific problem with your current solution that answers could address. \$\endgroup\$ – Anko May 19 '14 at 16:32
1
\$\begingroup\$

It seems like you're on the right track, but I would change things up a little. Having the QuestManager know about specific quests (checking to see if the "press the button" quest is in progress, marking it as complete, etc), would quickly lead to the QuestManager being a big mess.

Instead, you could derive each quest from an IQuest interface and the QuestManager could contain/manage these quests. Your IQuest interface could have virtual functions like Activate, Update, Deactivate, and IsComplete (just some examples), which the QuestManager would call. In this case you would derive PressButtonQuest from IQuest, and the PressButtonQuest would do the things the QuestManager was responsible for in your example.

\$\endgroup\$
  • \$\begingroup\$ This sounds like a great idea to consider. I currently do have a 'Quest' class, but it doesn't do much more than store the name and current state of the quest. Instead of having the QuestManager be the observer in all cases, I could have each quest be its own observer. \$\endgroup\$ – LVBen May 19 '14 at 1:54
  • \$\begingroup\$ Thinking about this some more, I really like this. It also makes it very simple to register when the quest is started and unregister when the quest is completed, thus eliminating many unnecessary events. \$\endgroup\$ – LVBen May 19 '14 at 2:34
  • \$\begingroup\$ One drawback is that it's hard to share data across tests, eg. "check if X button was pressed" \$\endgroup\$ – ashes999 May 21 '14 at 15:13
3
\$\begingroup\$

You may be interested in this question, which is similar, albeit about an achievement system (which is quite similar to a quest system).

In short:

  • Store the state of your game world, including history, actions undertaken, etc.
  • Iterate through all this history, and find certain conditions that meet your quest requirements
  • Award quest completion accordingly.

In your example, you would have to store when each of these actions occur, as well as details about the events themselves:

  • User presses a GUI button
  • User picks up (certain) object(s)
  • User kills creatures
  • User steals objects
  • User item count (user collects 10 items)
  • Key locations walked to

You are probably already tracking some of this already (eg. items picked, objects stolen); you just now need to store extra info (what was stolen and when?)

If you have a quest like "User walks to the fountain in town X with a gold sword and gold shield," you can implement it by searching for these three events:

  • User gets a gold sword
  • User gets a gold shield
  • User walks to location X (after the above two)

This is a pretty flexible, generic way, but the trade-off is that you're storing a bunch of extra data which, frankly, is a lot, and may not be useful outside of quests.

\$\endgroup\$
  • \$\begingroup\$ Thanks for the info! I see a few potential drawbacks to this method, such as: an infinitely growing history list and having to parse through the entire history every time a new item is added to the history, which sounds like a potential bottleneck. \$\endgroup\$ – LVBen May 19 '14 at 2:22
  • \$\begingroup\$ @LVBen yes, those are legitimate points. You need to decide how much to store, or what is significant enough. I think you can do well by saying "well this is significant and this is not," and only storing what you need. \$\endgroup\$ – ashes999 May 21 '14 at 15:12

Not the answer you're looking for? Browse other questions tagged or ask your own question.