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 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 |
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 |
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 |
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