   php / mySQL quest system tutorial?
  I was wondering if anyone knows of a great online tutorial or example of a quest system.I am wanting something that is able to be broken up into various steps and can track the progress.  I am using php and mySQL.As an example, I would like to do something like this...1. Kill x number of monsters.2. Return to the npc that gave it to you.meta: this quest is repeatable.1. Collect a part for the contraption.2. Collect a second part for the contraption.3. Go to the contraption.4. Combine the parts with the contraption.5. Bring the quest giver the results.meta: this quest is not repeatable and can only be give to users which meet various prerequisites.It would be cool to use a similar 'yellow bang' system like you see in most games, where the NPC has a visual indicator that they have a quest to give.Off the top of my head, I am guessing it would look something like:quest_stepid // auto inc notnull.user_id // id of the user this quest is for.quest_id // reference to the quest this step belongs to.step_text // visual description the user sees.flag // 0 not ready. 1 in progress. 2 complete.questid // auto inc notnullzone_id // used for 'getting' quests in current arealong_text // the long description of what the quest is.short_text // the short description(title) of the quest.repeatable // true/falseprereqsid // auto inc notnullquest_id // reference to the quest this prereq belongs to.req // category this requirement is (level, class, other quest id, etc)value // value of the requirement (10, fighter, 5, etc)Ok so I imagine as part of the 'zone in' script:$result = SELECT * FROM quest WHERE zone_id = $_SESSION['zone_id']$row = mysql_fetch_row($result);// I don't know the exact script, but// for each $row, get the prereqs, and for each prereq use a switch to check// that the users[req] == the value.// if true, show the quest symbol.I don't know, maybe I'm making this harder than it needs to be.  I also wanted to track other things too, like how many times different monsters were killed, or how many times they users an ability, etc. so I could have achievements or titles.It would be nice to see what others have done. :(   
  My advice is simply this: - store the stuff that is indisputably standard across all quests in a quest table. - hardcode the rest, based around a few generic functions that can apply to many different types of quest.Quests are interesting when they are unique and memorable. This almost means that the more interesting your quests are, the harder it will be to code a generic system for it. And you want interesting quests, right?I would set out some basic building blocks. Each quest should have a unique name or ID so that conditions and database rows can be linked to it, so that you can remember which ones a player has completed, which ones he's on, etc. It probably needs a description so that the player can see a list of current quests.On top of that, you must typically meet some conditions to get a quest, then you must meet some conditions to complete the quest. So you need conditions, and these typically come in 2 kinds: things that 'are', and things that 'were'.Things that 'are', you implement with simple queries:  - quest to retrieve the Holy Grail -> query inventory for grail - raise 1000 gold pieces to pay for rebuilding of adventurers guild -> query character for amount of money - shed all worldly goods to gain access to monastery -> ensure size of inventory is zeroThese are simple enough. Write the query functions so that each condition is a simple one-liner.Things that 'were', are a bit more complex. You can't store the state of the world at all times in the past, so instead you need to track and remember significant events - sometimes only after the quest begins - but once the data is stored, you can again query it as if it was current data (as above).  - slay 10 goblins -> when quest is accepted, start tracking a player's goblin kills (eg. a (playerID, questID, counterID, quantity) row in a quest_counter table). Check value of relevant counter to see if quest is complete.  - deliver a message to Jim in Oldtown -> whenever someone talks to Jim, check to see if they're on this quest, and if they are, insert a row into the achievements table with the playerID and a unique 'talked to Jim' value.  - destroy One Ring in Mount Doom -> whenever an item is thrown into Mount Doom, check to see if it's the One Ring, and if so, insert a row into the achievements table with the playerID and a unique 'destroyed One Ring' value. Check achievements table to see if quest is complete.As you can see, you'll need a few hooks in your game code at key events, eg. when you talk to people, when you collect items, when you destroy items, when you kill monsters, etc. Pass in the relevant data (eg. player ID, npc ID or item ID) and you can check them in future.Each quest then becomes a few short snippets of code: - a function to check conditions to see if you're eligible to start the quest, and if met, display the initial offer text, etc. - a function to actually start the quest, adding a row into the user's current quests table, creating any new counters for NPCs to kill, herbs to collect, etc. - extra code in the event hooks to increment counters or add achievements to track your progress through quests. - a function to check if this particular quest has been completed, which you either call at opportune intervals or when you return to the quest-giver, depending on your design. And if completed, it issues rewards, marks it as completed for that player, and clears off any unnecessary counters/achievements.You might also want another function that returns a player's progress or a hint, by looking at which of the conditions are still unmet. (eg. if (!hasRing) then return "Talk to Elrond" else if (hasRing) && !(atMordor) return "Take the ring to Mordor.")Attach lists of quest ids to NPCs, and you can easily compare that list with a player's completed quest list to see if the "yellow bang" needs showing.With a little thought I'm sure you can see ways to make the system above more generic but my advice is to just hardcode things to begin with and only when you find yourself repeating yourself is it worth trying to build a generic system from it.(EDIT: typos.)[Edited by - Kylotan on January 26, 2010 11:35:04 AM];  Thanks a lot Kylotan!  You are helping me a lot these last weeks. ;)I've read your post and will re-read it several more times until I am able to understand it and apply the concepts.Thank you again for all your help in this post and the others you have responded to.   