I doubt there is such a thing as a universal “best way” when it comes to game design questions. I have found that trying to uphold the OOP principles is a good idea. Especially quests are obviously single objects in the game world, so I contend that the OOP way is a very good way.
Abstract your quests. Have a class for the most abstract notion of a Quest
. Determine what behavior and data each quest shares, then put that in the Quest
class. Notce, that you will be handling all quests as this class, so unless it in here, you won’t have direct access to it. You could make it something like
public abstract class Quest{
protected static List<Quest> questList = new ...;
public static List<Quest> GetQuests(){ return new List<Quest>(questList); }
/*
The abstract keyword requires the extending class
to provide an implementation.
*/
//gives the rewards
public abstract bool FinishQuest();
//Returns the quest giver's description
public abstract string GetDescription();
//returns the current objective
public abstract string GetObjective();
}
Then move on to each sub type of Quest: you could have “FetchQuest
”, “TalkQuest
” etc. Each of these classes will extend Quest
.
Notice, in the Quest
class, there is no BeginQuest(). That is because each sub type of Quest will have their own static constructor.
public class FetchQuest : Quest{
private string description;
private string objective;
public override bool FinishQuest(){ /*give rewards*/}
public override string GetDescription(){ return description; }
//every abstract method must be implemented here
private FetchQuest(string newDescription, string newObjective){
description = newDescription;
objective = newObjective;
}
public static FetchQuest GetApplesFromStore(){
objective = "Walk into the store and get Apples."
description = "I'm so hungry and need some apples. You look like a strong warrior, fetch me some apples from the nearby store.";
questList.Add(new FetchQuest(description, objective));
}
}
Now all you need to do to begin and store the quest is to call FetchQuest.GetApplesFromStore();
from your quest giver code. When you ever feel the need to see what quests are currently active, you cain gain acces to (a copy of; to prevent accidental changes) the quest list with Quest.GetQuests();
Someone could argue that this design is in violation of the Single Responsibility Principle, which states that an object should do only one thing. My Quest class obviously maintains the quest list and represents a quest. If you feel the need to abide by the SOLID principles, then by all means, use a singleton QuestManager
which maintains all the ‘administrative’ quest stuff. You’ll also need a Factory to create the quests, because creating a new quest and representing one are two different behaviors, right? This all would add levels of complexity so I felt it better not to include it in these examples.