Jump to content

  • Log In with Google      Sign In   
  • Create Account


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


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
10 replies to this topic

#1 BaneTrapper   Members   -  Reputation: 1153

Like
1Likes
Like

Posted 16 February 2014 - 05:52 AM

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, 16 February 2014 - 05:54 AM.

Current projects:
The Wanderer, 2d turn based rpg style game

www.gamedev.net/topic/641117-check-up-the-wanderer/


Sponsor:

#2 Sutayh   Members   -  Reputation: 173

Like
2Likes
Like

Posted 16 February 2014 - 10:35 AM

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".



#3 Paradigm Shifter   Crossbones+   -  Reputation: 5237

Like
6Likes
Like

Posted 16 February 2014 - 10:40 AM

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).


"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

#4 SeanMiddleditch   Members   -  Reputation: 4891

Like
5Likes
Like

Posted 16 February 2014 - 02:59 PM

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).

#5 BHXSpecter   Members   -  Reputation: 1280

Like
2Likes
Like

Posted 16 February 2014 - 03:05 PM

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.


"Through vengence I was born.Through war I was trained.Through love I was found. Through death I was released. Through release I was given a purpose."


#6 BaneTrapper   Members   -  Reputation: 1153

Like
0Likes
Like

Posted 17 February 2014 - 04:33 AM

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!


Current projects:
The Wanderer, 2d turn based rpg style game

www.gamedev.net/topic/641117-check-up-the-wanderer/


#7 Shaquil   Members   -  Reputation: 815

Like
1Likes
Like

Posted 17 February 2014 - 08:42 AM

-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?



#8 BHXSpecter   Members   -  Reputation: 1280

Like
0Likes
Like

Posted 17 February 2014 - 12:14 PM


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)


"Through vengence I was born.Through war I was trained.Through love I was found. Through death I was released. Through release I was given a purpose."


#9 BaneTrapper   Members   -  Reputation: 1153

Like
0Likes
Like

Posted 17 February 2014 - 01:03 PM

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 "http://www.youtube.com/watch?v=nk0BsHK_gBA" skimming the begginings of the lua.

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


Current projects:
The Wanderer, 2d turn based rpg style game

www.gamedev.net/topic/641117-check-up-the-wanderer/


#10 BHXSpecter   Members   -  Reputation: 1280

Like
1Likes
Like

Posted 17 February 2014 - 02:49 PM

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. 


"Through vengence I was born.Through war I was trained.Through love I was found. Through death I was released. Through release I was given a purpose."


#11 Eck   Members   -  Reputation: 1873

Like
2Likes
Like

Posted 19 February 2014 - 08:04 AM

I wrote a couple of decent posts about a quest system design in another thread:

http://www.gamedev.net/topic/652095-help-on-how-to-implement-stories-and-quests-on-an-rpg/

 

It might be worth a read to you.

 

- Eck






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS