Reference: QuestDef.txt

Purpose

Stores all quest data. For convenience, they may be stored in multiple files. If a new file is added, add the filename to Packages/QuestPack.txt.

File Format

Resembles INI format with structured blocks.
Comment character: double slash (//)
Each line is generally split at the first "=" symbol.

Block Format

Property Type Description
[ENTRY] N/A Begins a new quest entry.
Requires Integer Optional. The Quest ID of a single prior quest that must be completed in order for this quest to be available to the player.
Profession Integer Optional. If present, this quest can only be accepted by players of this class. Possible values are (1=Knight, 2=Rogue, 3=Mage, 4=Druid). Corresponds to the CreatureDef 'profession' property.
ID Integer The quest ID for this entry. Must be unique.
Title String The name used in the quest journal and display trackers.
BodyText String The text displayed when reading a quest before accepting it. This may span multiple lines in the file. Any following line in the file that does not have a property field token will be appended into this field.
CompleteText String The response text when reading a quest after turning it in. Like BodyText, this may span multiple lines.
Level Integer OR Integer,Integer The minimum level required to accept the quest. Optionally you may supply a second value, separated by a comma, which specifies the maximum level required to accept the quest (like Bounty Boards). The 'Level' or 'Suggested' properties should appear immediately after the BodyText and CompleteText fields.
Suggested Integer The level displayed as the suggested level in the client. The 'Level' or 'Suggested' properties should appear immediately after the BodyText and CompleteText fields.
Exp Integer Experience points given upon completion.
PartySize Integer The recommended party size as displayed in the client. No effect on the server side.
NumRewards Integer If optional reward items are present, this is the exact number of items that must be selected to redeem the quest. Optional items are distinct in that they require the player to select them (the item icons will have a checkbox for the player to decide).
Coin Integer The amount of copper to give upon completion.
Unabandon Bool If set to 1, the player cannot use the quest journal to abandon this quest. Usually only needed for the first starting zone quest.
QuestGiverID Integer The CreatureDef ID of the NPC that gives the quest. Important! The creature's defHints value must have CDEF_HINT_QUEST_GIVER bitmask enabled, or it will not display a quest icon. See CreatureDef defHints for more information.
QuestEnderID Integer The CreatureDef ID of the NPC that redeems the quest (who the player must return to). Important! The creature's defHints value must have CDEF_HINT_QUEST_ENDER bitmask enabled. See CreatureDef defHints for more information.
Repeat Bool If set to 1, this quest may be repeated indefinitely. Important! This is mostly intended for bounty boards, although it could be used for other quests as well. Consider providing a maximum player level in the 'Level' property. Repeatable quests will never be added to the player's list of completed quests.
RepeatDelay String Optional. This is completely distinct from the 'Repeat' property above. This controls a completely separate mechanism in which a completed quest can be moved back into the available list after a certain amount of time. This is developed for use by event quests so that they can be repeated at a later date. Normally if a quest is completed, it cannot be accepted again, which poses a problem where the Quest ID of yearly event quests would need to be changed every year.

Requires a string prefixed with a character denoting a unit of time, followed by a number. The following units are recognized (M=Minute, H=Hour, D=Day) and are not case sensitive. For example, 'M60' is equivalent to 'H1'

sGiver String Specifies the location and zone of where the quest giver NPC may be found. This is a string that must contain 4 numerical values (Float,Float,Float,Integer) separated by commas. The first three (the floats) are the X,Y,Z coordinates of the quest giver. The final value is the ZoneDef ID. This influences the 'available quest' icons in the client minimap/world map.
sEnder String Same format as sGiver, but for the quest ender.
Heroism Integer A new reward not present in the original game. The amount of heroism points granted to the player upon completing quests. Subject to over-level penalties. See the HeroismQuestLevelTolerance and HeroismQuestLevelPenalty properties in ServerConfig.txt.

Note that heroism operates on a scale from 0 to 1000. 1 point of heroism equals 0.5 points of luck.

ScriptAcceptCondition String A list of extended conditions required to accept the quest. See Extended Quest Actions below.
ScriptAcceptAction String A list of extended actions to perform when the quest is accepted. See Extended Quest Actions below.
ScriptCompleteCondition String A list of extended conditions required in order to redeem a quest. See Extended Quest Actions below.
ScriptCompleteAction String A list of extended actions to perform when a quest is redeemed. See Extended Quest Actions below.
[ACT] N/A Begins a new act. Each act must have at least 1 objective (maximum 3 objectives). Objectives within an act may be completed in any order. Once all objectives within the act are completed, the player proceeds to the next act. For example, one act may require the player to kill a number of mobs, and the final act is to return to the quest giver NPC. Quests may have an arbitrary number of acts. All objective sub-properties use an Obj.X prefix where X is a number (0, 1, or 2) identifying the objective index.
Act.BodyText String This is the description text present for the current act when a player views the quest journal of a quest in progress. Like BodyText and CompleteText, it can span multiple lines in the file.
Obj.0.type
Obj.1.type
Obj.2.type
String The objective type. Acceptable values are (none, kill, travel, activate, gather, talk, emote). The acceptable values in the 'data1' and 'data2' fields will vary depending on the type. See the Objective Type Table below for a full list of types and examples.
Obj.0.data1 Integer [,Integer...] A list of integers, separated by commas. Usage varies depending on the objective type.
Obj.0.data2 Integer A single integer. Usage varies depending on the objective type.
Obj.0.ActivateTime Integer For 'activate' and 'gather' quests, this is the number of milliseconds required to interact with the object. Typical gather quests use a value of 2000 (2 seconds).
Obj.0.ActivateText String For 'activate' and 'gather' quests, this is the text displayed in the timer bar in the client when the player is interacting with the object.
Obj.0.description String The objective text as it appears in the quest tracker overlay in the client screen.
Obj.0.complete Bool Not required in quest definitions. Leave as zero.
Obj.0.myCreatureDefID Integer Used only for 'talk' objective types, this is the CreatureDef ID of the NPC to return to. Should be identical to QuestEnderID.
Obj.0.myItemID Integer Used in the quest briefing and journal screens, this is the ItemDef mID to use. This allows the item icon to be used in the objective panels. For example, a gather quest might have a quest item entry with a flower icon. In the official item table, these entries usually start around ID 500001.
Obj.0.completeText String The initial status of a particular objective, displayed in parenthesis in the quest tracker. For example (0 of 10).
Obj.0.markerLocations String Similar to the sGiver and sEnder fields (x,y,z,zoneID;) format. This string has 4 values separated by commas. The first 3 are floats, the last an integer. Typically has a semicolon at the end. For example: Obj.0.markerLocations=39110.0,236.412,51319.0,9;
RewardItem.0
RewardItem.1
RewardItem.2
RewardItem.3
String These control the items displayed in the reward slot. A maximum of 4 items are allowed. Takes 3 properties, separated by commas (ItemDefID,ItemCount,Required). The ItemDef ID is the item for that particular reward. ItemCount is the number of items to give. Should be just 1 unless stacked items like potions are offered instead. If Required is left at 0, the player must select between the available rewards (see the NumRewards field). If set to 1, the item will always be granted to the player.

Objective Types

Objective Type Description Example
none Server default for an improper quest objective. Should not be used. N/A
kill The player must kill a certain number of acceptable creatures.

data1: The list of CreatureDef IDs whos kills apply toward the kill count.

data2: The total number of kills to reach.

Note that completeText should be initially set to reflect the starting progress.

Obj.0.type=kill
Obj.0.data1=362,363,364
Obj.0.data2=10
Obj.0.description=Collect 10 Unikorn Horns
Obj.0.complete=0
Obj.0.myCreatureDefID=
Obj.0.myItemID=500037
Obj.0.completeText=0 of 10
Obj.0.markerLocations=40559.0,195.788,52296.0,9;
travel The player must travel within a certain radius of a coordinate location within a specific zone.

data1: x,y,z,ZoneID of the target location.

data2: Trigger range, in game units (10 units = 1 meter) that the player must stand within. Locations are usually scanned every few movement steps by players, so the general area should be large enough so that the player can see the objective while still being able to walk into the location at a brisk pace (like with Bounder Dash activated).

Obj.0.type=travel
Obj.0.data1=47333,373,45735,9
Obj.0.data2=300
Obj.0.description=Travel to the Roc nesting grounds
Obj.0.complete=0
Obj.0.myCreatureDefID=
Obj.0.myItemID=
Obj.0.completeText=
Obj.0.markerLocations=47333.9,373.709,45735.0,9;
gather

-OR-

activate

Both of these behave in the same way except for one small difference. Activate will leave the object in place, but gather will remove the item and require a respawn (Practical use: activate a device, but gather flowers).

data1: a list of CreatureDef IDs that count toward the total required activations for that objective.

data2: Number of objects that must be activated.

Note that ActivateTime and ActivateText are also used for these objective types.

Obj.0.type=gather
Obj.0.data1=467
Obj.0.data2=12
Obj.0.description=Gather 12 Jali Blooms
Obj.0.complete=0
Obj.0.myCreatureDefID=
Obj.0.myItemID=500057
Obj.0.completeText=0 of 12
Obj.0.markerLocations=37261.6,184.14,54898.0,9;
Obj.0.ActivateTime=2000
Obj.0.ActivateText=Gathering Jali Bloom...
talk The player must speak to an NPC. This is typically the final act of a quest to redeem the quest.

data1: Unused.

data2: Unused

Note: myCreatureDefID is used instead of the data properties. This value should be the CreatureDef ID of the NPC to return to. Note that QuestEnderID should be the same value. The CreatureDef entry itself should also have the CDEF_HINT_QUEST_ENDER bitmask enabled to see the quest redeem icon, and to allow the player to click on it.

Usually the marker location and sEnder fields should be the same, too.

QuestEnderID=2208
sEnder=39113.0,236.0,51324.0,9

Obj.0.type=talk
Obj.0.data1=0
Obj.0.data2=0
Obj.0.description=Travel to Karee Windtail
Obj.0.complete=0
Obj.0.myCreatureDefID=2208
Obj.0.myItemID=
Obj.0.completeText=
Obj.0.markerLocations=39110.0,236.412,51319.0,9;

emote The player must perform an emote within a specific location. data1 and data2 operate the same way as the travel objective.

data1: x,y,z,ZoneID of the target location.

data2: Range, in game units (10 units = 1 meter) that the player must emote within.

ActivateText: this field is used to identify the /emote that must be performed (case sensitive).

Obj.0.type=emote
Obj.0.data1=69024,630,34362,9
Obj.0.data2=30
Obj.0.description=Worship at the Flame near the Temple
Obj.0.complete=0
Obj.0.myCreatureDefID=
Obj.0.myItemID=
Obj.0.completeText=
Obj.0.markerLocations=69024.0,630.686,34362.0,9;
Obj.0.ActivateText=Worship

Extended Quest Actions

These operate as a form of mini script. All statements must be on a single line. Each statement is separated by a semicolon (;) and each token is separated by a space.

Here are some examples:
ScriptAcceptCondition=heroism >= 400;has_item 7066 1 ScriptAcceptAction=change_heroism -400 ScriptCompleteCondition=has_item 7066 1 ScriptCompleteAction=remove_item 7066 1

For conditions, a quest cannot be accepted or redeemed unless all conditions in the line are met.

Statement Type / Description / Example
heroism (comparator) (amount) Condition.
The player must have a certain amount of heroism.
Valid comparators: { =, !=, >, >=, <, <= }
heroism >= 400
has_item (Item ID) (amount) Condition.
The player must have a certain amount of items in their backpack inventory. The Item ID must correspond to an ItemDef mID.
has_item 7066 1
change_heroism (amount) Action.
Changes the player's heroism. Use a negative value for loss. The resulting heroism will not be less than zero or greater than 1000.
change_heroism -400
remove_item (Item ID) (amount) Action.
Removes a certain number of a player's items from their backpack inventory. The Item ID must correspond to an ItemDef mID.
remove_item 7066 1
send_text "text" Action.
Sends an information message (yellow text) that will appear on screen. The text should be enclosed in quotation marks.
send_text "You have upgraded your ring!"
play_sound "package|effect" Action.
Plays a sound effect. The sound string should be enclosed in quotation marks. There is a pipe (|) in the sound name that indicates to the client how to load the sound. It requires both a package name (archive) and effect (of the .ogg file format) to play.
play_sound Sound-ModSound|Sound-ExampleEffect.ogg

Other Notes

Each quest is is divided into any number of acts. Each of those acts can have up to 3 individual objectives which may be accomplished in any order. Once all objectives within an act are finished, the quest proceeds to the next act. Quests are usually finalized with an act containing a single talk objective, the NPC where the quest is redeemed.

The best way to create new quests is to find a quest that behaves similarly, then copy and paste it as a new entry, updating all the fields as appropriate. Make sure it has a unique ID. Copying acts with similar objectives is also helpful.

For simple talk-only quests, the official quests typically offer half the experience and coin rewards as other quests.

Some examples of item rewards:

A bounty board offers a single item that is always given to the player. NumRewards is left at zero since that field is for choice rewards only, and they cannot opt out of this reward. The RewardItem's last property (the 'Required' property) is set to 1 to always give that item. NumRewards=0 RewardItem.0=21337,1,1

In this quest, the player is presented with a choice between two items. NumRewards is set to 1 because they must choose exactly 1 item from the available 2 rewards. The 'Required' property is set to zero on both items since they are both optional. NumRewards=1 RewardItem.0=5329,1,0 RewardItem.1=5328,1,0