Custom Quests
The Custom Quests system adds server-defined quests with objectives and rewards, shown in an in-game quest log. It is free and always on. Players open the quest window with the O hotkey.
File Location#
Data/Plugins/Quests/
Each quest is its own .xml file in this folder. An optional Settings.xml in the same folder controls global limits. A _TEMPLATE - Quest Format Reference.xml reference file ships one level up, in Data/Plugins/, and is never loaded as a quest (see below).
Dependencies#
| Depends On | Purpose |
|---|---|
| Item configuration | Item identity for CollectItem objectives and Item rewards (ItemType / ItemIndex) |
| common.dat | MaxLevelUpQuest caps Experience rewards; AccountLevel tiers matched by requirement fields |
How Files Are Loaded#
The folder is scanned for *.xml in alphabetical order at startup.
- The quest id comes from the leading number of the filename, not from anything inside the XML.
015 - The Kundun Contract.xmlbecomes quest id 15.7 - Foo.xmlbecomes quest id 7. - Valid id range: 0 to 1023.
- A file whose name does not start with a number is skipped. The shipped
_TEMPLATE ...reference file lives outside this folder anyway, and its leading_would keep it from loading even if copied in. To turn it into a quest, copy it intoData/Plugins/Quests/and rename it toNNN - Some Name.xml. Settings.xmlis reserved and is never treated as a quest.- If two files resolve to the same id, the first one loaded wins and later duplicates are skipped.
Quest Structure#
<Quest>
<General .../>
<Requirements .../>
<Text>
<Summary>...</Summary>
<Description>...</Description>
</Text>
<Objectives>
<Objective .../>
</Objectives>
<Rewards>
<Reward .../>
</Rewards>
</Quest>
The root <Quest> element is required or the file is ignored. Every child section is optional; a missing section uses the defaults below.
General#
Quest identity and repeat policy.
| Attribute | Type | Default | Effect |
|---|---|---|---|
Name | string | "" | Display name in the quest log |
Category | string | Main | Tab / grouping label in the quest log |
Order | int | 0 | Sort order within the category, ascending |
Repeat | enum | OneTime | OneTime, Daily, Weekly, or Cooldown (case-insensitive; unknown falls back to OneTime). Weekly resets for everyone at the same time (WeeklyResetDay + DailyResetHour in Settings.xml); Cooldown with CooldownHours="168" is a rolling 7 days from each player's own turn-in |
CooldownHours | int | 0 | Hours between completions; only used when Repeat="Cooldown" |
PrerequisiteQuestId | int | -1 | Quest id that must be completed first. -1 = no prerequisite |
Enabled | int (0/1) | 1 | 0 = quest still loads but cannot be accepted |
HideWhenCompleted | int (0/1) | 0 | 0 = a finished quest stays in the quest window, listed in the green "completed" colour. 1 = it disappears from the list once the player completes it. Only affects Repeat="OneTime" quests |
AutoAccept | int (0/1) | 0 | 1 = this quest is accepted on its own the moment its PrerequisiteQuestId quest is turned in (chain quests). Normal checks still apply (level, class, resets, free quest slot). If one fails, the player accepts it by hand later |
Requirements#
Level, reset, and class gating. All optional. A range bound of -1 means "no limit" for the reset and account-level fields.
| Attribute | Type | Default | Effect |
|---|---|---|---|
MinLevel | int | 0 | Minimum character level, inclusive |
MaxLevel | int | 400 | Maximum character level, inclusive. The client treats 400 or higher as "no cap" |
MinReset | int | -1 | Minimum resets. -1 = ignore |
MaxReset | int | -1 | Maximum resets. -1 = ignore |
MinMasterReset | int | -1 | Minimum master resets. -1 = ignore |
MaxMasterReset | int | -1 | Maximum master resets. -1 = ignore |
MinGrandReset | int | -1 | Minimum grand resets. -1 = ignore |
MaxGrandReset | int | -1 | Maximum grand resets. -1 = ignore |
MinAccountLevel | int | -1 | Minimum VIP / premium account tier. 0 = non-VIP, higher = paid tiers. -1 = ignore |
MaxAccountLevel | int | -1 | Maximum VIP / premium account tier. -1 = ignore |
Classes | string | all | Comma list of class tokens (substring-matched). Empty or unmatched = all classes |
Class tokens map to the base race, so each covers its evolutions:
| Token | Covers |
|---|---|
DW | Dark Wizard / Soul Master / Grand Master |
DK | Dark Knight / Blade Knight / Blade Master |
ELF | Fairy Elf / Muse Elf / High Elf |
MG | Magic Gladiator / Duel Master |
DL | Dark Lord / Lord Emperor |
SUM | Summoner / Dimension Master / Narcissist Master |
RF | Rage Fighter / Fist Master |
Text#
Player-facing strings held as element text (not attributes). <Summary> is the short line in the list; <Description> is the detail-pane body and may wrap over multiple lines. Both default to empty.
Objectives#
Up to 8 objectives per quest. A 9th and beyond are ignored. Each <Objective> takes an optional Text attribute (the log line for that step). The other attributes depend on Type. Type is case-insensitive; an unrecognized value falls back to VisitMap.
| Type | Attributes | Behavior |
|---|---|---|
KillMonster | MonsterClass (0), Count (1), Map (-1) | Kill Count of a monster class. Map restricts to a map number; -1 = any map |
CollectItem | ItemType (0), ItemIndex (0), Count (1), Consume (1), Level (-1) | Have or turn in items. Consume=1 takes the items on turn-in; Consume=0 is a "have it" check only. Level sets which item level counts and is taken (-1 = any level). Live-counted as you gain or lose the item. A quest may list each item and each currency only once; a quest that lists one twice is not loaded |
ReachLevel | Level (0) | Reach a character level. Seeded on accept, so an already-high-level player completes it immediately |
TalkNpc | NpcClass (0) | Talk to an NPC by class index |
WinEvent | EventIndex (0), EventLevel (-1), Count (1) | Win event runs. Wired event ids in this build: 0 = Blood Castle, 2 = Chaos Castle. EventLevel restricts to a level; -1 = any |
Currency | CurrencyType (Zen), Amount (0) | Reach or spend a currency balance. Types: Zen, WCoin, Goblin. Spent on turn-in. Live-counted from the current balance |
VisitMap | Map (0), X1 (0), Y1 (0), X2 (255), Y2 (255) | Stand within a map rectangle in tile coordinates. The default rectangle covers the whole map |
Rewards#
Granted on turn-in. No hard cap on count. Type is case-insensitive; an unrecognized value falls back to UnlockQuest.
| Type | Attributes | Behavior |
|---|---|---|
Zen | Amount (0) | Zen added |
Experience | Amount (0) | Quest experience, capped by the server's MaxLevelUpQuest |
Item | ItemType (0), ItemIndex (0), Level (0), Skill (0), Luck (0), Option (0), Excellent (0), Count (1) | Gives an item. Needs a free inventory slot per item reward. Excellent is a bitmask. Ancient, Durability, and Duration are parsed but not applied in this build |
Points | PointType (Normal), Amount (0) | Normal = level-up stat points; Master = master-level points |
Currency | CurrencyType (Zen), Amount (0) | Gives currency. Types: Zen, WCoin, Goblin (Ruud = no-op) |
Buff | BuffIndex (0), Value1 (0), Value2 (0), DurationMin (0) | Applies a server effect. DurationMin is in minutes |
ItemBag | BagIndex (0) | Drops an item bag at the player's feet. Not inventory-room checked |
UnlockQuest | QuestId (0) | Documents intent only. Chaining is driven by PrerequisiteQuestId on the next quest, not by this reward |
Settings.xml#
Optional file in the same folder. Absent = defaults.
<?xml version="1.0" encoding="utf-8"?>
<CustomQuest ActiveCap="5" DailyResetHour="0" WeeklyResetDay="1" RewardToInventory="0" />
| Attribute | Type | Range | Default | Effect |
|---|---|---|---|---|
ActiveCap | int | 1-5 | 5 | Maximum simultaneously-active quests. Values outside 1-5 are clamped |
DailyResetHour | int | 0-23 | 0 | Server local hour at which Daily quests become available again. Weekly quests reset at this hour too |
WeeklyResetDay | int | 0-6 | 1 | Day Weekly quests become available again: 0 = Sunday, 1 = Monday ... 6 = Saturday. Out of range = Monday |
RewardToInventory | int | 0-1 | 0 | 1 = Item and ItemBag rewards go straight into the inventory. If the inventory is full at that moment, the item drops at the player's feet (only they can pick it up). In this mode an ItemBag gives items only: its zen roll, random set-item roll and firework are skipped. 0 = drop at the player's feet |
Gameplay Event Hooks#
Quest objectives are driven by the GameServer's shared gameplay-event bus. The same bus feeds the paid Achievements plugin, so both systems see identical events and stay in sync.
| Event | Quest objective today | Also available to achievements |
|---|---|---|
| Monster kill | KillMonster | yes |
| Level up | ReachLevel | yes |
| NPC talk | TalkNpc | yes |
| Map change | VisitMap | yes |
| Event win (Blood Castle 0, Chaos Castle 2) | WinEvent | yes |
| Item / zen balance | CollectItem, Currency | - (live counted, not an event) |
| Boss kill, PvP kill, reset, chaos mix result, item upgrade (+N), ground pickup, lucky spin, trade, personal store sale, rare drop, play time | not yet a quest objective | yes |
| Quest turn-in | - | yes: turning in any custom quest fires QuestComplete, so an achievement can reward "complete 10 quests" or "complete quest 15" |
Important Behavior#
- The quest id is the filename number, not any XML field. Renaming a file changes the quest identity and its stored progress binding.
Itemrewards do not yet apply Ancient, Durability, or Duration even though those attributes parse without error.- After editing any file in this folder, reload the plugin or restart the GameServer for changes to take effect.
Examples#
Save as 010 - Spider Cull.xml.
<?xml version="1.0" encoding="utf-8"?>
<Quest>
<General Name="Spider Cull" Category="Lorencia" Repeat="Daily" Enabled="1" />
<Requirements MinLevel="6" MaxLevel="50" Classes="DW,DK,ELF,MG,DL,SUM,RF" />
<Text>
<Summary>Thin out the spiders near town.</Summary>
<Description>The roads out of Lorencia are crawling with spiders. Clear eight of them.</Description>
</Text>
<Objectives>
<Objective Type="KillMonster" MonsterClass="3" Count="8" Map="0"
Text="Kill 8 Spiders in Lorencia" />
</Objectives>
<Rewards>
<Reward Type="Zen" Amount="50000" />
<Reward Type="Experience" Amount="10000" />
</Rewards>
</Quest>
Save as 011 - Bless Gathering.xml. Completing it satisfies the prerequisite for quest 12.
<?xml version="1.0" encoding="utf-8"?>
<Quest>
<General Name="Bless Gathering" Category="Main" PrerequisiteQuestId="-1" Enabled="1" />
<Requirements MinLevel="1" MaxLevel="400" />
<Text>
<Summary>Bring 10 Jewels of Bless.</Summary>
<Description>Turn in ten Jewels of Bless to prove your worth.</Description>
</Text>
<Objectives>
<Objective Type="CollectItem" ItemType="14" ItemIndex="13" Count="10" Consume="1"
Text="Collect 10 Jewels of Bless" />
</Objectives>
<Rewards>
<Reward Type="Item" ItemType="14" ItemIndex="11" Level="10" Count="1" />
<Reward Type="UnlockQuest" QuestId="12" />
</Rewards>
</Quest>