I'm currently making a game with bunch of quests...so I thought that I'll be needing a Quest Engine that agnostically treats all events that will bump/trigger pending quests...so it should work in any game.
I want my code design where I can modify the quest parameters and stuff from an external data source (XML, database, plist, etc).
Here's the process I've thought:
- Each action will correspond to a certain unique event id.
- Game will send the event id to the Quest Engine
- Quest engine will have an algorithm to check if a quest will respond to the event id...if it matches, it'll bump the quest
So it's like the Quest engine will always listen to events from the game. Now my problem is how to generate these unique event ID's. For example, "Give potion to the merchant". The code should be able to know that I was giving potion to a certain npc and generate an ID from there. So if I'm going to give an antidote instead of a potion or give the potion to a different npc, it'll have a different ID and the quest will not be bumped.
Can you give me ideas for the algorithm of generating event ids? Or if this approach is impractical, can you suggest a better one?
Ideas on Quest Engine?
Started by Sylpheed, Sep 22 2011 12:29 PM
7 replies to this topic
#1
Posted 22 September 2011 - 12:29 PM
#2
Posted 22 September 2011 - 05:07 PM
Instead of an id, how about just using an event with parameters? You could have a GiveItem event whose parameters are a pointer to the item given and the NPC receiving the item. The quest can listen for GiveItem events, check to see if the parameters match those it's looking for and ignore if not.
reedbeta.com - developer blog, OpenGL demos, and other projects
#3
Posted 22 September 2011 - 05:31 PM
Wait...I think I'm getting something from your statement. The game I'm working on is for iOS (Objective C). If I'm not wrong event is the same as "NSNotification"...I could pass an object (quest data) with that. This might work, I'll try it tomorrow.
Also, they require me that the quests should be configurable through an external data source (remotely tuned). I hope I'll be able to get the data structure ready.
I'm just new to game development (work and hobby) so my knowledge is not yet enough to make big games.
Anyway, thanks for the suggestion. I'm still open for ideas though so keep posting XD
Okay I got the events (NSNotification) planned. Theoretically, I can make this work. Only thing left is having an XML/plist to define these specific events. Here are the events that will surely be needed in the game:
- BuyItem (params: itemId, itemType)
- GiveItem (params: itemId, itemType, receiverId)
- LevelUp (params: level)
- InteractWithItem (params: itemId, itemType)
- InteractWithNPC (params: npcId)
As you can see they have different parameters (will be wrapped in an object so I can point to it). How should I design the data structure that will accomodate all types of events? I don't know if it's possible to wrap these all up in one XML/plist...how does MMO games (very quest-oriented) handle these?
#4
Posted 23 September 2011 - 04:06 PM
You could always transform any kind of data to the string of bytes (words/dwords) with dynamic length. Personally I prefer this approach when working with complex ID.
For working with text files you could store ID in readable text form:
For working with text files you could store ID in readable text form:
<eventHandler ID="GiveItem 6345 weapon NPC1423">...</eventHandler>
Sorry my broken english!
#5
Posted 23 September 2011 - 04:57 PM
It sounds like there's a relatively small set of possible params. You could just make an object that has all the possible params, and an event type (enum containing BuyItem, GiveItem, etc. as values). You'd just ignore the params that weren't relevant for the given event type.
reedbeta.com - developer blog, OpenGL demos, and other projects
#6
Posted 26 September 2011 - 03:31 AM
@Reedbeta
The requirement will not allow me to do that. I currently have these fields:
I doubt these fields will be able to meet future requirements. I was planning to create a class for every type of event and dump all the required fields in there. With that, my Quest class doesn't even need to know what event it needs to trigger, the event will just tell the Quest object that it was triggered.
But the problem with the structure of the external data source still persists. Is it practical that my data structure is not consistent? By consistency, the structure for each tree varies per event. I think I'm confused since I've been using consistent data structure up to now.
Let me know if this is a good approach.
@Smile
Hmmm...that seems convincing. I'll consider that but I'll have to ask the Web department since they'll be the ones who will generate the data source for me.
The requirement will not allow me to do that. I currently have these fields:
@interface Quest : NSObject {
// Global Data
int questId; /** ID of the quest. Equivalent to the key in plist. */
int clientId; /** ID of the client or who gave the quest. Set to 0 if there's no client. */
NSString *title; /** Quest name/title */
int levelRequired; /** Level required to unlock the quest */
QuestHierarchy hierarchy; /** Parent quest or child quest */
QuestStatus status; /** Status of the quest. */
// Main Quest Fields
NSMutableArray *prerequisites; /** Array of quest ID's needed before the quest gets unlocked */
NSMutableArray *tasks; /** Array of tasks (quests) needed to complete the quest */
// Timed Events
float timeRemaining; /** Time remaining before the quest expires */
float timeLimit; /** Time limit before the quest expires. Set to 0 for no limit. */
// Progress
int numProgress; /** Incremental quest progress */
int numRequired; /** Number of times needed to repeat the quest */
id <QuestDelegate> delegate; /** Quest delegate. */
}
I doubt these fields will be able to meet future requirements. I was planning to create a class for every type of event and dump all the required fields in there. With that, my Quest class doesn't even need to know what event it needs to trigger, the event will just tell the Quest object that it was triggered.
But the problem with the structure of the external data source still persists. Is it practical that my data structure is not consistent? By consistency, the structure for each tree varies per event. I think I'm confused since I've been using consistent data structure up to now.
- BuyItem (params: itemId, itemType) - GiveItem (params: itemId, itemType, receiverId) - LevelUp (params: level) - InteractWithItem (params: itemId, itemType) - InteractWithNPC (params: npcId)
Let me know if this is a good approach.
@Smile
Hmmm...that seems convincing. I'll consider that but I'll have to ask the Web department since they'll be the ones who will generate the data source for me.
#7
Posted 26 September 2011 - 04:12 AM
It looks like you're using Objective-C; I'm not familiar with that, but in C++ what I might do is make a base Event class that contains nothing but an event type (maybe a few other general things like a timestamp or whatever), then make derived classes for each type of event, containing the appropriate parameters. You'd have to do some casting based on the event type to the appropriate derived type. Something like:
Maybe you can do something similar in Objective-C.
enum EVENTID {
BuyItem,
GiveItem,
// ... other events
};
class Event {
EVENTID m_eventId;
};
class BuyItemEvent : public Event {
Item * m_pItem;
};
class GiveItemEvent : public Event {
Item * m_pItem;
Npc * m_pReceiver;
};
// ... other classes
// Here's some code that looks for a specific event
void ProcessEvent (Event * pEvent) {
if (pEvent->m_eventId != GiveItem)
return;
GiveItemEvent * pGiveItemEvent = static_cast<GiveItemEvent *>(pEvent);
if (pGiveItemEvent->m_pItem != pItemDesired)
return;
if (pGiveItemEvent->m_pReceiver != pReceiverDesired)
return;
// ... do something with the event
}
// Here's some code that handles multiple kinds of events
void ProcessEvent (Event * pEvent) {
switch (pEvent->m_eventid)
{
case BuyItem:
{
BuyItemEvent * pBuyItemEvent = static_cast<BuyItemEvent *>(pEvent);
// ... do something with it
break;
}
case GiveItem:
{
GiveItemEvent * pGiveItemEvent = static_cast<GiveItemEvent *>(pEvent);
// ... do something with it
break;
}
// ... other cases
}
}
Maybe you can do something similar in Objective-C.
reedbeta.com - developer blog, OpenGL demos, and other projects
#8
Posted 26 September 2011 - 05:34 AM
Yeah, I'm developing iPhone games.
Yeah that's what I'm trying. It's perfectly possible..as a matter of fact it's much easier to handle class hierarchy/inheritance in Objective-C. I'm gonna code this now.
For the datasource, I'll use Smile's idea. Thanks. I'm using this format for the QuestEvent.
Good, looks like I'm on the right track. Thanks. I'll post again if ever I encounter problems.
Yeah that's what I'm trying. It's perfectly possible..as a matter of fact it's much easier to handle class hierarchy/inheritance in Objective-C. I'm gonna code this now.
For the datasource, I'll use Smile's idea. Thanks. I'm using this format for the QuestEvent.
event=AcquireItem;itemType=room;itemId=4;repetition=0;time=0Repetition and time may not be included for simplicity.
Good, looks like I'm on the right track. Thanks. I'll post again if ever I encounter problems.
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users











