Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411673 Posts in 69399 Topics- by 58452 Members - Latest Member: homina

May 16, 2024, 11:27:14 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)best way to implement quests
Pages: [1]
Print
Author Topic: best way to implement quests  (Read 3030 times)
chudchud
Level 0
**


View Profile
« on: April 24, 2012, 08:24:19 AM »

i posted this question on http://www.reddit.com/r/gamedev but wanted to get the forum's opinion on this:

i'm designing levels for my iOS game built in cocos2d and i want to implement different "missions" for a level (collect x objects, destroy x objects, obtain x points, etc). what's the best way to design this into my code? i want to avoid uniquely coding specific objectives, rather just define mission conditions in a file that gets parsed and processed at runtime. if theres a better approach, i'd love to hear it. any help would be greatly appreciated!

i've tried searching for resources online related to how to implement this but haven't had any luck. And direction you could point me in would be great, especially working examples!
Logged
Fallsburg
Level 10
*****


Fear the CircleCat


View Profile
« Reply #1 on: April 24, 2012, 08:37:10 AM »

Well, I think you sort of laid it out yourself.

You have some sort of data structure like:

Code:
<Mission>
   <Collect count="10" type="berry">
</Mission>
<Mission>
   <Destroy count="5" type="goblin">
</Mission>

And then you have some sort of way of connecting your type identifier with in game objects.
Logged
chudchud
Level 0
**


View Profile
« Reply #2 on: April 24, 2012, 09:00:51 AM »

i'm good on setting up the data, i was looking for a solution to implement it into code. whats been suggested elsewhere was using FSMs and possibly wrapping that with a decorator pattern. as someone new to gamedev, is there a best practice for this situation? i mean, its in everything, theres gotta be, right!
Logged
Dacke
Level 10
*****



View Profile
« Reply #3 on: April 24, 2012, 09:08:04 AM »

I'm not exactly sure what you are asking for (I don't know what FSM or decorator patterns are)

But you could pick a standard mark-up language like xml, json or yaml. (Fallsburg's example looks like xml). There are lots of easy-to-use libraries for parsing such files, so you'll just have to take a pick.

edit: In Python, you can do stuff like:
Code:
from xml.dom import minidom
quests = minidom.parse('FallsburgQuests.xml')
print quests.childNodes[0].toxml()

Which would output: <Collect count="10" type="berry">
« Last Edit: April 24, 2012, 09:23:23 AM by Dacke » Logged

programming • free software
animal liberation • veganism
anarcho-communism • intersectionality • feminism
chudchud
Level 0
**


View Profile
« Reply #4 on: April 24, 2012, 09:20:42 AM »

@Dacke i was going to use .plist for the sake of iOS development, but those other choices aren't bad. In all honesty, i think people tend to use what they are most confortable with.

Finite State Machines (FSM) can be used to control flow from one state to another, the wikipedia article spells it out pretty well (http://en.wikipedia.org/wiki/Finite-state_machine).
The Decorator Pattern is a Gang of Four structural design pattern that allows you to add and change methods of existing objects (http://en.wikipedia.org/wiki/Decorator_pattern).

I guess what i'm asking is how to structure my classes and designs to best implement a "quest" system? i'm looking more for the abstractions of it all.
Logged
Dacke
Level 10
*****



View Profile
« Reply #5 on: April 24, 2012, 09:32:42 AM »

Ah, Finite State Machines, I didn't recognize the acronym. I've also never heard the name Decorator Patterns before, but I have come in contact with the concept. Thank you for clarifying  Gentleman

But I don't see how FSMs and Decorator Patterns are applicable here? If your goal is to manually write a number of quests, it sounds more reasonable to follow Fallsburg's suggestion.

Also, I'm still not sure what you are asking for:
i'm good on setting up the data, i was looking for a solution to implement it into code.
I guess what i'm asking is how to structure my classes and designs to best implement a "quest" system?

Could you perhaps break it down a bit for us. What do you want to achieve and what do you want help with?
Logged

programming • free software
animal liberation • veganism
anarcho-communism • intersectionality • feminism
EdgeOfProphecy
Level 2
**



View Profile WWW
« Reply #6 on: April 24, 2012, 09:41:50 AM »

It does depend on how complex a quest you want these systems to represent, now and in the present.

Personally, I think a component based architecture would work well.  What I'll propose is kind of similar to the decorator pattern.

Let's say you define a class called Quest.  Quest more or less exists to act as glue, binding together the actual parts of the quest.  These parts are individual objects that perform some sort of quest-y task, like.

VictoryCondition
QuestProgress
QuestReward
QuestDescription

So on and so forth.  Depending on the complexity of your quests, you could have a lot more of these.

The idea is that these components would be totally independent of each other.  You could mix in any dialogue, any reward, any victory condition, etc together.  Some of these classes could be kept pretty general (like QuestDescription, or QuestReward), but ones that could conceivably require more specific behaviors (VictoryCondition maybe) could be subclassed.

If you wanted your quests to be really flexible, you could add in a special QuestProcessor class to control the logic of executing the quest.  The intent behind this class is to handle the problem of having a bunch of different possible components that may not all be present in the same time.  The QuestProcessor would assume that the Quest object had components of certain types and orchestrate the processing of them.

Then, in your XML/Plist/whatever, you define the structure of the quest by describing the components that it has, and the initialization data for those components.  Have a function that will parse the input file, instantiate the appropriate components, add them to the Quest object, and return the whole thing when it's done.
Logged
Fallsburg
Level 10
*****


Fear the CircleCat


View Profile
« Reply #7 on: April 24, 2012, 09:44:53 AM »

Yeah, I'm really not sure what you are asking.  I mean, you don't really need FSM's or anything else.  

All that's required is you have some sort of polling system or event system in place (either works, it just comes down to preferences really [i.e. it's unlikely to be a bottleneck in your code if you choose the wrong one]).  Then you either check every so often to see if a criteria has been achieved (polling) or you wait for an appropriate event to fire off.

I'd suggest the event driven system with some sort of message dispatcher.

Here's how it would work:
A quest is created and registers with the message dispatcher.  It says that it is interested in reports of goblins being killed.  Whenever a goblin is killed, it creates a message saying that a goblin has been killed.  The quest gets the message and increments a counter.  It then checks if the counter has passed its threshold, if it has, the quest is completed.

Anyway, that's how I would do it.  If that isn't what you are talking about, then you are going to have to be more specific.
Logged
chudchud
Level 0
**


View Profile
« Reply #8 on: April 24, 2012, 10:15:28 AM »

Could you perhaps break it down a bit for us. What do you want to achieve and what do you want help with?

i'm looking for a way to set up my classes. i think i'm starting to get a handle on how to do it, especially the more i get asked for clarification on what i actually need, ha!

whats the best way to abstract this (or similar) data structure:
Code:
<Mission>
   <Collect count="10" type="berry">
</Mission>
<Mission>
   <Destroy count="5" type="goblin">
</Mission>

into a class, and whats the best way to implement that into a game? let's say i have a bunch of instances of the Mission class, should i use a MissionManager singleton to keep track of incomplete/complete/active/inactive missions? i think im starting to answer my own question...
Logged
Richard Kain
Level 10
*****



View Profile WWW
« Reply #9 on: April 24, 2012, 10:26:37 AM »

Like all programming problems, you just need to "break it down." The first question to ask is...what information is needed for each quest. The second question would be...how does the program interact with these quests?

Personally, I would create a QuestManager class, and a Quest class. It might also be advisable to create a QuestObjective class, depending on how flexible you want your quest system to be. The QuestManager class would handle sorting and displaying Quest instances. The Quest class would contain the individual properties for each quest. Actions in the game world would access the QuestManager class in order to pass status updates for the Quest instances. If you only have one player to worry about, you could make most of the QuestManager class static in order to make access to it easier.
Logged
Revk
Level 0
**



View Profile WWW
« Reply #10 on: April 24, 2012, 10:27:07 AM »

I don't know if you ever modded one of Bethesda's game (Elder Scrolls or Fallout 3/NV). But their quest system is pretty nice. If you never did, this is how it is (well, how I recall it is, not modded since Morrowind) :

Each Quest is in fact a list of Quest Stages. Each Stage is given a ID number between 0 and 100; 0 being the quest beginning (the quest is set to stage 0 when you got it), 100 being the quest ending(removed from quest journal). You can define any number of stages (well, between 1 and 101 I guess), but you are not limited to one quest ending. For each stage, you can define its description, objectives, and resulting actions to take, like a script.

We can then imagine a stage 10 where you need to save some damsel, then, depending of the outcome of this objective, you set the stage to 20 if the player failed, or 30 if he succeeded. If stage 20 is reached, you can tell the player he is lame and give him no reward, then set the stage to 100 (quest finished and removed from the game/questlog). If stage 30 is reached, you congratulate the player and make him marry the damsel and gain lands from her father the king, then set the stage to 100...


As Fallsburg pointed out, the best possible way to do this is an event system. You should have some sort of QuestSystem structure recording all current/done/failed quests, and accepting incoming event messages. When some events arise, a message is created and sent to this QuestSystem.



In the test quest above, imagine the player in the evil lord castle. If he talks to the princess to set her free, a message is sent to the QuestSystem, saying that this particular dialog line has been told. The QuestSystem then check that the evil lord is dead(the QuestSystem should know his reference ID or something); if it is true, the stage is set to 30, and the princess can respond that she is happy and she should be excorted home; if it is false, the stage could be set to something like 15, where the dialog availables with the princess are modified (ie : "The evil lord is not dead, moron. Go slain him!"). If the player kills the princess, the stage is set to 20, with all resulting script instructions.
Logged
chudchud
Level 0
**


View Profile
« Reply #11 on: April 24, 2012, 10:28:19 AM »

@EdgeOfProphecy i like the idea of using a component system for this, it makes the missions much more customizable. it would be easy to mix and match. thanks for the input!

@Fallsburg using an event dispatcher would definitely be the way to go, thanks!
Logged
ThemsAllTook
Administrator
Level 10
******



View Profile WWW
« Reply #12 on: April 24, 2012, 11:10:56 AM »

For this sort of design problem, I usually like to write a messy implementation first just to get something working, and take what I learned from that and refactor it into something clean afterward. It's hard to know exactly what you need ahead of time, so there's really no harm in just diving in and doing it the easiest way, however hackish it might be. In some cases, the quick hack solution will be all you need; if not, it'll give you a clear idea of what you need to do for a complete solution. Trying to thoroughly design something like this up front tends to make you either overengineer it or build something that doesn't actually do what you want.
Logged

st33d
Guest
« Reply #13 on: April 24, 2012, 11:55:29 AM »

Quests are actually pretty simple when you consider all the possible variations of quests:

Visit X.
Collect X.
Kill X.
Talk to X (a variation being the FedEx quest - but the implementation is the same)

Essentially what these are are checkpoints. A quest simply wants to to visit a sequence of checkpoints to fullfil it.

For collectables, killables, conversations and locations you will need a quest flag. When you encounter a quest flag, you then refer to your look up table (or XML as other's have suggested) for what quest is here and what quest the player is undertaking.
Logged
ஒழுக்கின்மை (Paul Eres)
Level 10
*****


Also known as रिंकू.


View Profile WWW
« Reply #14 on: April 24, 2012, 12:08:35 PM »

unless you are going to have a huge number of quests, or have quests be user-editable, i don't see the problem with coding each one directly. be wary of spending more time on time-saving devices than you get back from time saved from it
Logged

chudchud
Level 0
**


View Profile
« Reply #15 on: April 24, 2012, 07:05:56 PM »

thanks for all the input!
Logged
Flynn1179
Level 0
**


View Profile
« Reply #16 on: April 25, 2012, 01:29:38 AM »

One thing I'd recommend: However you handle quest objectives, it might be worth making it hierarchical. Many quests often involve sub-quests. A quest to clear an area might involve clearing all mobs, and collecting all items, each of which can be further broken down.

You might not use sub-quests for many quests, but it's nice to have the option there for scalability.
Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic