Orxonox  0.0.5 Codename: Arcturus
Modules | Files | Classes | Enumerations
Questsystem

The Questsystem is a module that enhances Orxonox with Quests. More...

Modules

 Effects
 A QuestEffect is a device for Quests to have side effects.
 

Files

file  GlobalQuest.h
 Definition of the GlobalQuest class.
 
file  LocalQuest.h
 Definition of the LocalQuest class.
 
file  Quest.h
 Definition of the Quest class.
 
file  QuestDescription.h
 Definition of the QuestDescription class.
 
file  QuestEffect.h
 Definition of the QuestEffect class.
 
file  QuestEffectBeacon.h
 Definition of the QuestEffectBeacon class.
 
file  QuestHint.h
 Definition of the QuestHint class.
 
file  QuestItem.h
 Definition of the QuestItem class.
 
file  QuestListener.h
 Definition of the QuestListener class.
 
file  QuestManager.h
 Definition of the QuestManager class.
 

Classes

class  orxonox::GlobalQuest
 GlobalQuests are Quests, that have the same status for all players. More...
 
class  orxonox::LocalQuest
 Handles Quests which have different states for different players. More...
 
class  orxonox::Quest
 Represents a Quest in the game. More...
 
class  orxonox::QuestDescription
 This class is a description of a QuestItem (Quest and QuestHint). More...
 
class  orxonox::QuestEffect
 Handles QuestEffects for Quests. More...
 
class  orxonox::QuestEffectBeacon
 A QuestEffectBeacon is a physical entity in the game which can (under some condition(s)) invoke a number of QuestEffects on players meeting the condition(s). More...
 
class  orxonox::QuestHint
 Represents a hint in the game that gives aid towards completing a Quest. More...
 
class  orxonox::QuestItem
 Functions as a base class for quest classes such as Quest or QuestHint. More...
 
class  orxonox::QuestListener
 Provides a way to react to the starting, completing and failing of Quests. More...
 
class  orxonox::QuestManager
 Is a Singleton and manages Quests, by registering every Quest / QuestHint (through registerX()) and making them globally accessible (through findX()). More...
 

Enumerations

enum  orxonox::QuestEffectBeaconStatus { orxonox::QuestEffectBeaconStatus::Inactive, orxonox::QuestEffectBeaconStatus::Active }
 The status of the QuestEffectBeacon, can be either active or inactive. More...
 
enum  orxonox::QuestHintStatus { orxonox::QuestHintStatus::Inactive, orxonox::QuestHintStatus::Active }
 The state of the QuestHint. More...
 
enum  orxonox::QuestListenerMode { orxonox::QuestListenerMode::All, orxonox::QuestListenerMode::Start, orxonox::QuestListenerMode::Fail, orxonox::QuestListenerMode::Complete }
 The mode of the QuestListener. More...
 
enum  orxonox::QuestStatus { orxonox::QuestStatus::Inactive, orxonox::QuestStatus::Active, orxonox::QuestStatus::Failed, orxonox::QuestStatus::Completed }
 Different states of a Quest. More...
 

Detailed Description

The Questsystem is a module that enhances Orxonox with Quests.

Quests are objects that challenge the player that receives such an object to fulfill some specific task (e.g. Rescue a princess, fetch some rare metal alloy, destroy the evil pirates den, ...). Upon having fulfilled that task the player can be rewarded with some kind of reward. Quests can be hierarchically structured, meaning that to fulfill some Quest you first have to fulfill all (or some, depending on the quest) sub-quests.

Technical details

The Questsystem essentially consists of the Quest entity which is the quest itself (and sub- or helper-entities, such as QuestHint (hints for quests) or QuestDescription (descriptions for quests and hints, to separate content from function)), the QuestEffect and QuestListener entities which are the only tools for quests to have any influence on the game world. By enabling quests to have QuestEffects they are able to (for example) fail or complete other quests, activate hints, give rewards or even add a quest to a player. QuestListeners on the other hand can be used by any object to react to a status change of a quest. The QuestEffectBeacon is the physical entity which finally makes quests available for the player in the game, by being able to invoke a QuestEffect on a player (under some conditions).

questsystem.png

Creating Quests

Creating the Quest-Hierarchy

To start you have to create a Quest-Hierarchy in the XML-Levelfile by hierarchically nesting your quests. There are two types of Quests you can use, the LocalQuest and the GlobalQuest.

LocalQuest

A LocalQuest is a Quest which has different states for each player, that means each LocalQuest can be obtained and completed (or failed) by each player in parallel. A questId is some string that uniquely identifies the quest, this can either be a name or, to ensure uniqueness, you can use a GUID generator (google or you can use this generator). The advantage of GUID is, that you can be quite sure that your id is unique, the drawback is, that it provides less overview and can be quite confusing when looking at the level file. So make your own choice.

Creating a LocalQuest in XML goes as follows:

<LocalQuest id="questId">
<QuestDescription title="Title" description="Description." /> //The description of the quest.
<subquests>
<Quest id ="questId1" /> //A list of n subquest, be aware, each of the <Quest /> tags must have a description and so on and so forth as well.
...
<Quest id="questIdn" />
</subquests>
<hints>
<QuestHint id="hintId1" /> //A list of n QuestHints, see QuestHint for the full XML representation of those.
...
<QuestHint id="hintIdn" />
</hints>
<fail-effects>
<QuestEffect /> //A list of QuestEffects, invoked when the Quest is failed, see QuestEffect for the full XML representation.
...
<QuestEffect />
</fail-effects>
<complete-effects>
<QuestEffect /> //A list of QuestEffects, invoked when the Quest is completed, see QuestEffect for the full XML representation.
...
<QuestEffect />
</complete-effects>
</LocalQuest>

GlobalQuest

GlobalQuests are different, they can be obtained by every player but the changes made to the Quest (e.g. completion of the quest) affect all owners of the quest. A short example: There are 3 Players, A, B and C. Player A obtains the quest, a while later player B obtains the quest and completes it. Since it is a GlobalQuest it is completed for all players having obtained the Quest which means it is also completed for player A. Player C though, never having obtained the quest, can now never complete it.

Creating a GlobalQuest in XML goes as follows:

<GlobalQuest id="questId">
<QuestDescription title="Title" description="Description." /> //The description of the quest.
<subquests>
<Quest id ="questId1" /> //A list of n subquest, be aware, each of the <Quest /> tags must have a description and so on and so forth as well.
...
<Quest id="questIdn" />
</subquests>
<hints>
<QuestHint id="hintId1" /> //A list of n QuestHints, see QuestHint for the full XML representation of those.
...
<QuestHint id="hintIdn" />
</hints>
<fail-effects>
<QuestEffect /> //A list of QuestEffects, invoked on all players possessing this quest, when the Quest is failed, see QuestEffect for the full XML representation.
...
<QuestEffect />
</fail-effects>
<complete-effects>
<QuestEffect /> //A list of QuestEffects, invoked on all players possessing this quest, when the Quest is completed, see QuestEffect for the full XML representation.
...
<QuestEffect />
</complete-effects>
<reward-effects>
<QuestEffect /> //A list of QuestEffects, invoked on the player completing this quest. See QuestEffect for the full XML representation.
...
<QuestEffect />
</reward-effects>
</GlobalQuest>

As you may see that another difference between a GlobalQuest and a LocalQuest is, that with a GlobalQuest having RewardEffects, the RewardEffects are only executed on the player completing the quest. Additionally CompleteEffects are executed on all players having obtained the quest before it was completed, when it is completed., while with a LocalQuest each player that completes a quest, completes it for himself alone, but also gets the reward, regardless whether another player completed the quest before him.

QuestHint

QuestHints can be used to give a player useful information for Quests he is working on completing. QuestHints cannot have any side effects, but also have an identifier which follows the same form as in the Quests.

Creating a QuestHint in XML goes as follows:

<QuestHint id="hintId">
<QuestDesctription title="" description="" />
</QuestHint>

QuestDescription

Each Quest (and also each QuestHint) must have a QuestDescription consisting of a title and description, and for Quests also messages for the event the quest is either failed or completed. Of course these are (as is the title and the description) optional.

Creating a QuestDescription in XML goes as follows:

<QuestDescription title="Title" description="Description Text" failMessage="You fail." completeMessage="You win!" />

Creating side effects

Quests can have side effects, in fact that is mostly what they are about. This means that they can have an influence on the game world. Quests do that through two distinct devices, QuestEffects (active) and QuestListeners (passive).

QuestEffect

A QuestEffect is the first (and probably most important) device for Quests to have side effects. There are two entities that can have QuestEffects: Quests and QuestEffectBeacons (which will be explained later on). QuestEffects, for example, can start a Quest for a player, complete/fail Quests for a player, add a QuestHint or a Reward to a player, and potentially much, much more.

These QuestEffects are implemented so far, but feel free to contact me if you have suggestions for new QuestEffects or if you need help implementing a new one yourself.

AddQuest

This QuestEffect adds (respectively starts) a Quest (identified by the given questId) to the player.

<AddQuest questId="id" /> //Where id identifies the Quest that should be added.

FailQuest

This QuestEffect fails a Quest (identified by the given questId) for the player.

<FailQuest questId="id" /> //Where id identifies the Quest that should be added.

CompleteQuest

This QuestEffect completes a Quest (identified by the given questId) for the player.

<CompleteQuest questId="id" /> //Where id identifies the Quest that should be added.

AddQuestHint

This QuestEffect adds a QuestHint to a Quest (identified by the given questId) of a player.

<AddQuestHint hintId="id" /> //Where id identifies the QuestHint that should be added.

AddReward

This QuestEffect adds a Rewardable (Rewardable is an Interface which can be implemented by an object that its creator thinks should be able to be rewarded a player for completing (or failing for that matter) a Quest) to the player. Pickup Pickups for example wold be good Rewardables.

<AddReward>
<Rewardable /> //A list of Rewardable objects to be rewarded the player, see the specific Rewardables for their respective XML representations.
...
<Rewardable />
</AddReward>

QuestListener

The QuestListener is the second device you can use to create side effects. As opposed to QuestEffects (that are executed (or invoked) either as a result of failing or completing a Quest or by a QuestEffectBeacon), QuestListeners are passive, meaning that they relay information regarding status changes of Quests rather than enforcing status changes. QuestListeners have a certain mode (all, start, complete or fail) and a Quest which they belong to (resp. to which they react). You then can use QuestListeners to make basically any object aware of when the status of the given Quest changes (the way you defined through the mode) and take any action you may think of.

Here is an example of the usage of QuestListeners in XML:

<BaseObject> // The object that should react to the status change of a Quest.
<events>
<function> // Where function is the method of the object that schould be executed. Normally this would be visibility or activity.
<QuestListener questId="someQuestId" mode="someMode" /> // Where someQuestId is the identifier for the Quest the QuestListener is reacting to, and someMode is the kind of status change the QUestListener reacts to (all, start, complete or fail).
</function>
</events>
</BaseObject>

I hope this example has made the usage of QuestListeners a little clearer. The QuestListener actually reacts exactly as any Trigger or EventListener would (although the QuestListener is really neighter the one nor the other) which means you can use it in exactly the same way you would use one of the above, it just reacts to a different thing. Namely to the change in a Quests status.

Putting the Quests in the game world

As of now we know how to create Quests and QuestHints, we have a way for quests to add new quests, or even complete/fail other quests. We also have a way of reacting to a status change in a Quest. In short we know how quests can be created, how they can influence other quests and how we can react to changes in quests. But our Quests have no ties (well, not really at least) to the game world as of yet, meaning, that the game world cannot influence quests. For this we have QuestEffectBeacons.

QuestEffectBeacon

The QuestEffectBeacon is a StaticEntity and has the ability to (when triggered trough some circumstance) invoke a specified list of QuestEffects on the player triggering the QuestEffectBeacon.

Creating a QuestEffectBeacon in XML goes as follows:

<QuestEffectBeacon times=n> //Where 'n' is either a number >= 0, which means the QuestEffectBeacon can be executed n times. Or n = -1, which means the QuestEffectBeacon can be executed an infinite number of times.
<effects>
<QuestEffect /> //A list of QuestEffects, invoked when the QuestEffectBeacon is executed, see QuestEffect for the full XML representation.
...
<QuestEffect />
</effects>
<events>
<execute>
<EventListener event=eventIdString />
</execute>
</events>
<attached>
<PlayerTrigger name=eventIdString /> //A PlayerTrigger triggering the execution of the QuestEffectBeacon.
</attached>
</QuestEffectBeacon>

The QuestEffectBeacon can only be executed a defined number of times (where -1 times stands for an infinite number of times) and the QuestEffects are invoked whenever the method 'execute' is called, which is (indirectly through an EventListener, because I wanted to attach the PlayerTrigger so that its position is always relative to the QuestEffectBeacons position) done by the PlayerTrigger.

A PlayerTrigger is a special sort of Trigger that knows the player that triggered it and therefore can be asked who that was. This allows the QuestEffects to be executed on the right player.

Sample quest

To get your head around all of this and see some of the things mentioned here in action you might want to check out the "The Tale of Princess Aeryn"-Quest (Levelfile: princessAeryn.oxw) in the level-folder.

Enumeration Type Documentation

The status of the QuestEffectBeacon, can be either active or inactive.

Enumerator
Inactive 

The QuestEffectBeacon is inactive.

Active 

The QuestEffectBeacon is active.

The state of the QuestHint.

Enumerator
Inactive 

The QuestHint is inactive.

Active 

The QuestHint is active.

The mode of the QuestListener.

Enumerator
All 

Listens to all events.

Start 

Only listens to events pertaining the starting of Quests.

Fail 

Only listens to events pertaining the failing of Quests.

Complete 

Only listens to events pertaining the completing of Quests.

enum orxonox::QuestStatus
strong

Different states of a Quest.

Enumerator
Inactive 

The Quest is inactive.

Active 

The Quest is active.

Failed 

The Quest has been failed.

Completed 

The Quest has been completed.