Modified by on Friday, January 4, 2008 - 06:13
Mon, 08/27/2007 - 09:18 — SteelclawQuests: Things to do. You have probably started several and completed at least one. How do they work? How are they constructed? Read on.
Steelclaw says:
I recently had an opportunity to sit down and talk with Amon and discuss the quest system in Horizons. Below is my understanding of what was explained to me, as well as some guessing based on what I've seen. I will ask him to verify the content here. Untill then, don't take it as fact!
A quest is a series of steps. Each step has two main parts: a condition and a list of actions. A condition is a check that the player must satisfy before the action may take place. The action is something that the quest system performs on the player (or the player's quest status).
A quest may be given to a player by an NPC, triggered by some external event, or by a quest that is already in progress. Quest constraints can be applied so that the quest can not be started unless the constraints are satisfied.
As mentioned before, a quest step has three major parts: conditions, actions and dependencies. In addition, a step may have flags.
Branching is possible, however, it is not directly supported. The effect of branching is accomplished through the use of conditions and sub-quests or dependencies.
These are the commonly used conditions. Only one may be applied to a given step.
get item |
The player receives [item]. |
give item |
The character gives [item]. |
go to location |
The player reaches [waypoint] |
item created |
The player creates [item]. |
item deconstructed |
The player deconstructs [item]. |
item gathered |
The player gathers [item]. |
item used |
The player uses [item|ability|spell]. |
kill keyword |
The player kills an entity with keyword [keyword]. |
kill monster |
The player kills a monster of type [monster]. |
loot item |
The player loots [item]. |
player death |
The player dies. |
quest progress |
The player completes [some step] of [some other quest]. |
talk |
The player greets [name | list of NPCs]. |
talk keyword |
The player greets an entity with keyword [keyword]. |
timeout |
The player has waited for [some time period]. |
These are the commonly used actions. Any number of these can be performed on a step.
coin award |
Give player [some coin amount]. |
delete item |
Remove [item] from player. |
destroy quest |
Destroy this quest from the player's quest log. |
feedback msg |
Send the player a quest feedback message. |
give item |
Give the player [item]. |
give item if new |
Give the player [item] if they do not have it. |
give quest if new |
Give the player [quest] if they do not have it. |
give script if new |
Run [script] on player. |
give stat mod |
Give the player a stat modification. |
join school |
(forcefully) Have the player join [school]. |
leave school |
(forcefully) Have the player leave [school]. |
npc action |
Have [npc] execute a raw emote or one from its racial .def file. |
quest complete |
Mark the quest as complete in the completed quest list. (you want to do this at the end of the quest, otherwise it lingers in the active quest list) |
spawn monster |
Spawn [monster]. |
talk |
[npc] sends a /tell, /shout or /say |
teleport pad add/remove |
Attunes/de-attunes the player to [destination] |
treasure award |
Gives the player an item from [treasure group] (like looting) |
xp award |
Gives the player XP in [(adventure | craft) school]. |
Dependencies are applied to individual quest steps and list other steps that must or must not be completed before the step it is applied to becomes available. Only a single type of dependency may be applied, although any number of steps may be included in that dependency. Every step needs to have some dependency set, otherwise it will be 'active' the moment the quest is given.
A step may also have flags set.
The most useful of these is the “repeatable†flag. Without it, once the step's condition is met and action takes place, the step is completed and the quest journal moves to the next step. With the repeatable flag, the quest step may be repeated over and over. This is useful for giving the player progress aids, such as having an NPC respond with hints if it is greeted and a certain step has not yet been completed.
Another useful flag is an “invisible†flag. This prevents the step from showing up in the quest journal, even if it is active.
Dependency types:
include |
Step is not shown, but activated and visible in [step list] are complete |
include in visible |
Step is greyed out initially, but activated if all steps in [step list] are complete. |
exclude |
Step is not shown, but activated and visible if all steps in [step list] are incomplete. |
exclude in visible |
Step is greyed out initially, but activated if all steps in |
It is possible to define a series of checks a character must pass before it is given a quest. These are constraints. Note that it is not possible to apply constraints to sub-quests – those that are given as an action of some other quest. These constraints only apply to quests started by greeting an NPC. “AND†as well as “OR†logic is supported.
These are the commonly used constraints:
ability |
Character has [ability]. |
character_age |
Character is at least [age] old. |
coin |
Character has at least [coin]. |
curlevel |
Character's current [adv | craft | both] level is [level] or above. |
curlevelunder |
Character's current [adv | craft | both] level is [level] or less. |
curschoollevel |
Character has [school] as their current school and it is at |
gender |
Character is [gender]. |
highestlevel |
Character's highest [adv | craft | both ] is [level]. |
highestlevelunder |
Character's highest [adv | craft | both ] is [level] or under. |
itemexists |
Character has [item]. |
item_fewer_than |
Character has less than [count] of [item]. |
notcurschool |
Character does not have [school] as their current school. |
or |
Allows you to choose more than one of the regular constraints. |
quest_complete |
Character has completed [quest] |
quest_incomplete |
Character has not completed [quest] |
quest_keyword_missing |
Character does not have a quest with [quest keyword] active. |
quest_keyword_exists |
Character has a quest with [quest keyword] active. |
race |
Character is [race]. |
schoollevel |
Character has [school] with at least [level]. |
skill_current |
Character has [skill] with current level [level] or higher. |
stat (attribute) |
Character has [attribute] with value [value] or higher. |
stat (skill) |
Character has [skill] with base level [level] or higher. |
There is an action called “give scriptâ€, leading you to wonder what a script is. It is best thought of as a series of actions (like the ones defined above) to execute quickly on the server. It runs within the quest system and thus, has the same limitations.
Branching, as mentioned before, is not directly supported. You can not say “If condition A is met, go to step 3, if condition B is met, go to step 10â€. The quest system does not have the semantics to do that. Instead, you must rely on the dependencies and sub-quests and progress checks for this effect.
Examples are a good way of learning. An example of each is provided below. Please ignore the quality of these examples, focus on the semantics and format.
In this example, a loop is created between steps 2 and 3 using the “repeatable†flag set on step 3. The dependencies are used to “turn off†step 3, “turn on†step 4, and effectively branch out of the loop.
Each time the player greets LazyNPC
while step 2 is incomplete, they will be berated.
Quest Description: LazyNPC wants 500 sandstone slabs to finish leveling.
Step 1: Begin quest
Dependency: none
Flags: none
Condition: none
Actions:
Talk LazyNPC: “%n%!! I'm out of sandstone! I can't make spells to level my craft without spell shards, and I need bricks for that, which takes... oh you get it. Anyway, dig up 500 sandstone slabs for me and I'll make it worth your time.â€
Step 2: Gather 500 sandstone slabs
Dependencies: include, step 1
Flags: none
Condition: Gather(sandstone slab) x500
Actions:
Feedback: “You count the 500th slab and exclaim 'I deem it good enough!'â€
Step 3: [invisible]
Dependencies: exclude, step 4
Flags: invisible, repeatable
Condition: Talk LazyNPC
Actions:
Talk LazyNPC: “No, no, I want five hundred sandstone slabs! Don't come back unless you have them!â€
Step 4: Return the slabs to LazyNPC
Dependencies: include step 2
Flags: none
Condition: Talk LazyNPC
Actions:
Talk LazyNPC: “Aha! Thank you! Just let me take those...â€
Delete Item: sandstone slab x500
Talk LazyNPC: “There we go. Five hundred exactly. Here's your reward, these are worth about 1c per four, right?â€
Coin reward: 125c
Feedback: “You try to act polite as you nod your head and leave, gritting your teeth.â€
Step 5: End quest
Dependencies: include step 4
Flags: invisible
Condition: none
Actions:
Destroy quest
Quest complete
Uhm. I need to find out a few more
things before I can make an example.