Quest system, how do people do it?

Started by
7 comments, last by ddn3 15 years, 3 months ago
I've been working on a quest system, and it was suggested to me to use XML to store the quest data. I have never used XML before, but after reading a few tutorials and seeing a few working examples, I have the basics figured out. So now my question is, how do most games handle their quest data? I was thinking of storing every potential quest in an xml file, and then starting each user with a blank xml quest file. As the user gains new quests, I would basically copy the quest element from the main list to the individuals quest list. In the past I have just used object.toSource to convert the quest object to a string, and then eval() the data back into an instantiated object, but I guess this isn't the best way to do it, so I am trying to switch to an XML system. Here is a basic setup of what I have so far:

<MasterQuestList>
  <quest key="kill_10_rats">
    <title>Kill 10 Rats</title> 
    <description>You have been asked by the local guards to kill 10 rats.</description> 
  </quest>
  <quest key="collect_5_ratPelts">
    <title>Collect 5 Rat Pelts</title> 
    <description>Xander has asked you to collect 5 Rat Pelts. If you collect these for him, he will give you some Rat Pelt Gloves.</description> 
  </quest>
</MasterQuestList>
Of course this is just very basic and needs to be fleshed out with type, triggers, rewards, steps, etc. As you can see, this is the 'MQL.xml' file, the master quest list. I was thinking when a user starts, they would just get an empty questJournal xml, and when they get the 'kill_10_rats' quest, I would just copy that quest over to their questJournal. I would want an attribute for things like 'repeatable = "false"' and probably some kind of 'requrement' elements that I would have to check, like minLevel or previous quests completed, etc, but I don't know the best structure for all of this in the XML file. Is this how other people have done it? So far I have only made a 'viewer' where when you load the MQL.xml it will populate a drop down box with the quest 'key' attributes, and then flesh out a 'title' and 'description' text objects, but I really need to see some examples of how other people have done it.
Advertisement
I can't answer the "Is this how it's done" question because that's not really a question that can be answered. I assume the answer to a question like that would be "Depends.. if it works for them".. So I'll give you that same answer...

Go with what works for you. No two people do the same task the same way. I will say, however, that XML is a great way to represent textual data.

I may suggest you do something like this..

MasterQuestList.xml

<MasterQuestList>
<Quest id="3" repeatable="false">
<title>Kill 10 Rats</title>
<description>The locals have asked you to kill 10 rats</description>
<Requirements>
<min_level>1</min_level>
<max_level>10</max_level>

<quest id="1" />
<quest id="2" />
</Requirements>
</Quest>
</MasterQuestList>

In the user file, you could keep track of their quests by having an XML that looks something like this...

PlayerQuests.xml

<PlayerQuests>
<Quest id="1" completed="true" active="false" />
<Quest id="2" completed="true" active="false" />
<Quest id="3" completed="false" active="true" />
</PlayerQuests>

Hope that helps!
Yes it does! I have been looking at the Dungeon Runners character XML sheet, to get an idea of how other people do this sort of thing. I also had thought of putting the repeatable as an attribute in the quest, it seemed like a natural spot. I like how you did the requirements as an element, with other elements.

I have a couple other questions, perhaps you, or someone else could help.

This XML file, am I supposed to be pulling data right from it, or am I supposed to be reading it in, then instantiating several 'quest' obejects from the data, and then be pulling data from my instantiated array or linked list of quest objects?

As I have been investigating XML, I really like what it is and what you can do with it, but because I am still just starting to understand it, I am not familiar with the functionality of where and when it should be accessed.

I am mainly working on a single player game, but I am trying to make it scaleable into a multi-user game with as little re-work as needed.

In a 'normal' situation, I would probably scan in the list of quests and instantiate the master quest list object as a linked list or map object. Then when I wanted data from it, I would access the quest list object, and not the direct data file itself.

With XML, it seems like you 'could' access the raw, uninstantiated data itself, like a database, so I am not sure what is the standard way to handle it.

Thanks a lot for your help Jaylach, I have been coming to check every now and again, and I was glad to see some friendly help.
My quest system is scritp driven. The player instance stores a list of "flags", variables with a certain value. For example, when you talk to NPC X, it can add a flag, lets say MissionX, with value yes. That mission is to kill NPC N. Every action (talk, kill, etc) triggers scripts which can access and modify player flags.
I use a database driven quest system. As a DB backend i simply us SQLite. XML is just a form of data representation thus u have to implement all your query functionality yourself - unless u use some form of xml store that supports queries. Afaik lots of RPG's including WoW use a DB driven system. If your game uses scripts for in-game events, most script languages also have DB connectors and SQL bindings, so its easy to integrate. Last but not least, everything u need for using that technology has been around for ages already - u dnt have to code it yourself - which means its working and stable and there's tons of resources out there on DB queries.
You are most welcome, BUnzaga :)

As for weather you should access the XML directly or create a series of objects is, for the most part, personal preference. However, if you were writing something like WoW which probably already has hundreds of objects already instantiated, you probably would read the XML directly.. or, better yet, use a database driven system.

However, since this is a single player RPG you could probably get away with reading the XML into an object for each quest. As some post state, you could use a DB driven approach as well. But, for me, I much prefer XML because it's easier for me to work with. Some prefer databases *shrug* .. all personal preference :)

May I ask what language you're writing your game in? If it's C# (Xna, WPF, Silverlight, MDX, etc) then you may be served by using XML Serialization. What this will do is it will take an object and write to disk in XML format. You can then read the XML back in and will have the objects created for you. This gets you around the "reading and creating the objects" step as the .NET language will do it for you.

The way I typically code, reading the XML file directly is, while plausible, not feasible. I much prefer create a set of objects from the XML. Then again, I code mainly in C# so I use serialization for all that :D

The thing to keep in mind is that XML is text, so reading it on the fly is like reading any other text file.. however much more complicated cause of the node structure. If you have a rather large XML file then seeking through it every time you get a new quest may not be feasible.

There are, of course, ways around this. The DOM structure in .NET will let you work with streaming XML files pretty easily. There is also XPath and XQuery, which will let you query your XML file much like you would in a database (although a lot less sophisticated).

In the master quest list above, you could use XPath to do something like this...

/MasterQuestList/quest[@id='1']

... which would select the quest from the MasterQuestList that has the id attribute that equals 1.

You can read more on XPath by going to http://www.w3schools.com/XPath/default.asp.

I'd like to help more on XQuery but I'm not as familiar with that, sorry!

Edit: My XPath code may not be 100% correct.. Not feeling well today and working from memory from the last time I had to use it :D
I'm using &#106avascript, the engine I use has &#106avascript as the main scripting language, they also have built in XML functions for searching and such.<br><br>I also found that ability to search by attribute:<br><br><pre><br>var test1 = xmlRoot.selectSingle("quest[@key = 'kill_10_rats']"); <br>print(test1.selectSingle("title").text);<br></pre><br><br>Ok, so you parse the XML into objects, I can see the advantage of this. As I was writing out the quest viewer, it really seemed like an extra step, but there is a major difference between viewing it, and actually using it. :p<br><br>@rogerdv<br>I use a similar apprach, &#111;nly I call them 'handlers' I have a map of sorts with different keys which are 'handlers' inside each of these is a list of what do to when the event takes place.<br><br>When the user gets the 'kill 10 rats' quest, I first check to see if there is a handler already in the handler list for killing rats, if there is, I add the script to update the number of rats killed for the quest. If there is no handler, I create the handler, then add the update for the quest. When there is no longer a need for the killed_a_rat handler, I remove it from the handler map.<br><br>It has worked out really well for dynamically adding/removing things to 'listen' for. I never thought to carry it over for NPCs and other things.<br><br>I guess it makes sense to use XML for a lot of other things, not just quests. :p Now that I am starting to understand it a bit more, I can see all of these places where it would come in handy.<br><br>Thanks for the tips and advice guys. I am still just taking baby steps with regards to game programming, and I appreciate all the advice you can give.
I guess the way I typically do it (games and otherwise) is I don't even really use XML other then storage on disk. I use objects and then, to store those, I serialize them to XML. My code doesn't deal with XML at all really, other then serializing and deserializing.

For example, I'm currently working on a Silverlight game. While I don't have quests, I do have a pretty complex crafting system working. The crafting parts are split into a few objects in my code - Plan, Component, Part, and Material.

A Plan contains one or more components, a component contains one or more parts. Materials are applied later and not stored as part of the plan object, so pretty much not relevant here.

I then take that Plan object and serialize it. In this case, I'm serializing it to JSON (just easier with Silverlight that way). I then compress that JSON string and store it in the database with some basic information about the plan (ID, Name, Description).

When a player wants to use that Plan I pull it out of the database using it's ID. I get the JSON string, decompress it, and deserialize it into my Plan object. From there I can get further information about the plan and modify it as needed, without effecting the "base plan" that's stored in the database. This includes things like adding materials to the different parts, etc.

I don't know if any of that is helpful for your quest system, but thought I'd throw it out there I'm using objects represented as strings in my project :) (weather it be XML or JSON or something else).
XML ususally is an intermediary format used becuase it's protable across programs and is well defined. Internally the data gets converted into a much more convient data structure, ie array or table or object, when handled with the scripts.

You can create a quest generator which takes raw xml quest setup data and pumps out a quest object ( which is a script side stateful object which can track the quester and quest items ).

A more common format I've seen is xls, the Excel spreadsheet format. Most quests, items, etc.. in RPGs can be fit into a simplfiied table view, which allows for easier maniuplation and management. The format is simple enough to export/import and it's more convient to view than XML data.

Good Luck!

-ddn

This topic is closed to new replies.

Advertisement