• Advertisement
Sign in to follow this  

Designing a "quest" system for top down 2d rpg

This topic is 1432 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello.

Currently i was kinda stuck on designing how i will handle quests in game.

I started designing quests to make my world feel rewarding and to give it some meaning but i never actually done a indept queset system that could handle infinite amount of types of quests, i alwais hardcoded it.

 

So what i though of would be good:

I started with 3 tipes : "Kill", "Gather", "Explor"

Kill quest example:
 

class Quest
{
public:
Quest();
void Loop();
void Finish()
};
//H
class QuestKillUnit : public Quest
{
public:
QuestKillUnit();
int killType;
int killAmount;;
Reward reward;
};

//Cpp
QuestKillUnit::QuestKillUnit()
{
killType = en::UnitType::Boar;
killAmount = 7;
reward = Reward(Item(en::ItemType::WoodenSword);
};

But i have issues, how do i have a class that will handle all types of quests i give to it?

 

I will flesh out a delivery quest type

class QuestDeliverItem : public Quest
{
public:
QuestDeliverItem();
Unit* unitDeliver;
int radius;
Reward reward;
};

QuestDeliverItem::QuestDeliverItem()
{
unitDeliver = &UnitHolder.unitList[FindJackSomehow  ];
radius = 32/2 + 32/2 + 20;//20 pixels away from the target to trigger the quest
reward = Reward(Gold(1));
}

And how eventualy i sould fit it togeder

//H
void QuestHolder
{
public:
void Loop();
void AddQuest(QuestKillUnit & quest);
void AddQuest(QuestDeliverItem & quest);
std::vector<std::unique_ptr<Quest>> QuestList;//This part i am not sure it will stay like this, it depends on issues without having avalibility to get data from it
};

//Cpp
void QuestHolder::AddQuest(QuestKillUnit & quest)
{
UnitHolder.AddUnitDeathEvent(quest.killType);//I will need this to report somehow back to the quest to increment +1 to kill count if killer is the "unit holding the quest"
QuestList.push_back(std::unique_ptr<QuestKillUnit>( new quest));//Not sure if it is correct  
}
//...

My issues are:
I do not know how i will handle incrementing kill count for for "QuestUnitKill" when a unit is killed.

How will i pull out data from "QuestHolder::QuestList" vector so i can display "Kill Wolves 5 / 7"

And allot more that i cannot thing of top of my head right now.

 

Is there any indept tutorial on "Quest system" out there for c++? googling and searching this forum gave me none.

Also your ideas and sugestions are welcome!happy.png

Edited by BaneTrapper

Share this post


Link to post
Share on other sites
Advertisement

In your unit class, I would probably have it send a message to your quest engine every time something dies that includes the type of the deceased unit.  The quest engine could then iterate through the QuestKillUnits until it found a match for the type of unit and increment the count by one.  Your QuestKillUnits class needs a variable to hold how many units have been killed.  When that variable is updated, it can send a message to your screen showing something like, "killed 5/6 werewolves".

Share this post


Link to post
Share on other sites

May want to learn Python or Lua after you get the hard coding done because then you can go back and make a system that has infinite quests. Scripting, if done correctly, can also open your game to having a modding community and prolong your game's playability. You could make it so players can add their own quests (could also be extended to weapons and such, but that is going above the initial problem.

Share this post


Link to post
Share on other sites

Thank you on responses.

 

May want to learn Python or Lua after you get the hard coding done because then you can go back and make a system that has infinite quests. Scripting, if done correctly, can also open your game to having a modding community and prolong your game's playability. You could make it so players can add their own quests (could also be extended to weapons and such, but that is going above the initial problem.

 

I spend last day/night learning lua watching tutorials and to be honest it is pretty not safe... allot of things could go wrong, and knowing me smile.png oh well.

So i decided for currect project to keep lua out, at least until i get to know it allot better.

 

 

I'd probably just have AddUnitQuestEvent to take a Quest pointer so that it can call a virtual function such as OnQuestSubtaskComplete which each quest child class can handle as it sees fit (e.g. calling Quest::Finish when enough enemies have been killed).


You can abstract a bit further. Every single thing that can happen gameplay-wise should have a corresponding event fired into a global event dispatcher. These would be used for logging, quests, achievements, and so on. Get an item, fire an event. Lose an item, fire an event. Kill something, fire an event. Step into a trigger zone, fire an event. Etc. Global systems like the logger or the quest system can subscribe to these global events. The quest system forwards events to any active quests. Each quest can have a serious of steps, each requiring some specific events (with specific sets of data) to be fired (possibly with a subset of them in a specific sequence or within a specific time frame).

Events should be rich in data. The KillCreature event should have the specific instance id killed, the type of the creature killed, the location it was killed, the weapon id of what killed it, the type of damage that killed it, etc. This will be essential for quests like "kill 10 bats with fire" or achievements like "kill 50 enemies in the Foo Dungeon."

Your dialog system will need some basic criteria and actions besides just text options. Options and responses will need to be able to check if a quest item is completed, give the player items, etc. It also needs to fire events, of course, so quests can have requirements like "talked to Old Man Fluffle" or so on.

You almost certainly don't want your events to have pointers to specific instances. What happens if the player leaves the map and comes back? Or the Npc somehow dies before the event is complete? Use unique IDs or archetype IDs (each unique Npc likely has its own unique archetype).

 

That is a idea i never thought off, i wonder how efficient it would be cpu wise, if done correctly it would make programing really fast which is nice, but i feel for my current project is nearing the end i shouldnt shift allot away from the rest of the code structure.

 

 

In your unit class, I would probably have it send a message to your quest engine every time something dies that includes the type of the deceased unit.  The quest engine could then iterate through the QuestKillUnits until it found a match for the type of unit and increment the count by one.  Your QuestKillUnits class needs a variable to hold how many units have been killed.  When that variable is updated, it can send a message to your screen showing something like, "killed 5/6 werewolves".

That is one way to do it, thankyou.

 

 

I'd probably just have AddUnitQuestEvent to take a Quest pointer so that it can call a virtual function such as OnQuestSubtaskComplete which each quest child class can handle as it sees fit (e.g. calling Quest::Finish when enough enemies have been killed).

Another way to fix the problem thank you sir!

Share this post


Link to post
Share on other sites

-I spend last day/night learning lua watching tutorials and to be honest it is pretty not safe... allot of things could go wrong, and knowing me smile.png oh well.

So i decided for currect project to keep lua out, at least until i get to know it allot better.

 

Just curious. What do you mean it's not safe?

Share this post


Link to post
Share on other sites


I spend last day/night learning lua watching tutorials and to be honest it is pretty not safe... allot of things could go wrong, and knowing me oh well.
So i decided for currect project to keep lua out, at least until i get to know it allot better.

Unsafe? How so? Lua and Python are both widely used scripting languages in games. Ruby and ActionScript are also worth mentioning.

 

Games that use Lua:          http://en.wikipedia.org/wiki/Category:Lua-scripted_video_games

Games that use Python:     https://wiki.python.org/moin/PythonGames (covers other things, but has a section of specific games using python)

Share this post


Link to post
Share on other sites

Well speaking as unexperienced user of lua to say the truth its same as c++ arrays, pointers etc.

Its pretty much dangerous if not used correctly and errors can be made, saying that i dont remember last time i had pointer or arr out of bound access error...

I based that statement on watching 4 videos from "

" skimming the begginings of the lua.

If it was incorrect i did only state the impresion i had from it at the time.

Share this post


Link to post
Share on other sites

Lua is dynamically typed and programmers make mistakes (even the experts), but that is no reason to avoid programming or using a language. Just keep it in mind as you code. 

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement