> For the complete documentation index, see [llms.txt](https://axiomemu.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://axiomemu.gitbook.io/docs/data/plugins/customquests.md).

# 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. The folder ships with a `_TEMPLATE - Quest Format Reference.xml` reference file that is never loaded as a quest (see below).

## Dependencies

| Depends On                                    | Purpose                                                                                     |
| --------------------------------------------- | ------------------------------------------------------------------------------------------- |
| [Item configuration](/docs/data/item/item.md) | Item identity for CollectItem objectives and Item rewards (ItemType / ItemIndex)            |
| [common.dat](/docs/gameserver/common-dat.md)  | `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.xml` becomes quest id 15. `7 - Foo.xml` becomes quest id 7.
* Valid id range: 0 to 1023.
* A file whose name does not start with a number is skipped. This is why the shipped `_TEMPLATE ...` file (starts with `_`) is never loaded as a live quest. To turn it into a quest, copy it and rename to `NNN - Some Name.xml`.
* `Settings.xml` is 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.

{% hint style="warning" %}
The `<?xml ...?>` declaration must be the first thing in the file. A comment placed before it makes the whole file fail to parse. Comments are allowed anywhere after the declaration, but never inside a tag between attributes.
{% endhint %}

## Quest Structure

```xml
<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`, or `Cooldown` (case-insensitive; unknown falls back to `OneTime`) |
| `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                                          |

### 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) | Have or turn in items. `Consume=1` takes the items on turn-in; `Consume=0` is a "have it" check only. Live-counted as you gain or lose the item |
| `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                                                    |

{% hint style="warning" %}
`WinEvent` only recognizes Blood Castle (0) and Chaos Castle (2) in this build. Devil Square and Illusion Temple are not wired. `Currency` type `Ruud` is accepted but treated as 0.
{% endhint %}

### 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
<?xml version="1.0" encoding="utf-8"?>
<CustomQuest ActiveCap="5" DailyResetHour="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     |

## 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.
* `Item` rewards 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

{% tabs %}
{% tab title="Kill quest" %}
Save as `010 - Spider Cull.xml`.

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

{% endtab %}

{% tab title="Collect + chain" %}
Save as `011 - Bless Gathering.xml`. Completing it satisfies the prerequisite for quest 12.

```xml
<?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>
```

{% endtab %}
{% endtabs %}

## Common Issues

{% hint style="warning" %}
Quest not appearing: confirm the filename starts with a number and that `Enabled` is not 0. A file starting with any other character is skipped silently.
{% endhint %}

{% hint style="warning" %}
Whole file ignored: check that `<?xml ...?>` is the first line with no comment before it, and that a `<Quest>` root element is present.
{% endhint %}

{% hint style="warning" %}
Duplicate quest missing: two files resolving to the same leading number collide. The first loaded (alphabetical) wins; rename one.
{% endhint %}
