EventItemBag
The EventItemBag system allows you to define reusable loot tables for monsters, events, and special items. When triggered, bags randomly select items from their pool based on configured rates and rules.
File Locations#
Bag Registry: Data/EventItemBagManager.xml
Bag Definitions: Data/EventItemBag/###␣-␣Name.xml
The registry maps bag indices to trigger conditions (item type, monster class, or special value), while individual bag XML files define the actual loot tables.
Dependencies#
| Depends On | Purpose |
|---|---|
| Item | Item indices dropped by bags resolve against the main item table |
| ItemOptionRate | Option rate indices used by extended bag Item entries (Option0-6) |
| ItemStack | Required for the Count attribute to take effect on stackable items |
| SetItemType | Used when SetItemDropRate triggers a random set item drop |
Referenced by:
- Monster - monsters drop via
MonsterClasstriggers when killed - Event - Blood Castle, Chaos Castle, Kundun, and other events trigger bags via
SpecialValue
File Naming Convention#
Bag files must follow this exact pattern:
###␣-␣Name.xml
###= Three-digit bag index (000-999) matching EventItemBagManager.xml␣= Single space-= Hyphen␣= Single spaceName.xml= Descriptive name with .xml extension
Examples:
000 - Box of Luck.xml012 - Blood Castle 1.xml051 - Game Master Box.xml
EventItemBagManager.xml Structure#
Maps bag indices to trigger conditions. The root element is <EventItemBagList> and each entry is a <Bag> element. Individual bag XML files live in the EventItemBag\ subfolder and are discovered by recursively scanning that folder at load time - subdirectories are allowed for organization.
| Attribute | Type | Description |
|---|---|---|
Index | int | Bag index (must match filename ###) |
ItemIndex | int or * | Full item index that triggers this bag when the item is used (e.g., 7179 = Box of Luck). Use * for wildcard |
ItemLevel | int or * | Item level required to trigger. Use * for any level |
MonsterClass | int or * | Monster class (the Class field from Monster) that drops this bag on death. Use * for any monster |
SpecialValue | int or * | Event-specific trigger ID used by Blood Castle, Chaos Castle, Kundun, Illusion Temple, and other events. Use * for any value |
Trigger Examples#
<!-- Box of Luck item (item 7179 level 0) -->
<Bag Index="0" ItemIndex="7179" ItemLevel="0" MonsterClass="*" SpecialValue="*"/>
<!-- Red Dragon monster (class 42) -->
<Bag Index="2" ItemIndex="*" ItemLevel="*" MonsterClass="42" SpecialValue="*"/>
<!-- Blood Castle 1 event (special value 0) -->
<Bag Index="12" ItemIndex="*" ItemLevel="*" MonsterClass="*" SpecialValue="0"/>
<!-- Several monsters sharing ONE loot file: repeat the Index, one row per class.
All rows load "EventItemBag\801 - *.xml" -->
<Bag Index="801" ItemIndex="*" ItemLevel="*" MonsterClass="606" SpecialValue="*"/>
<Bag Index="801" ItemIndex="*" ItemLevel="*" MonsterClass="607" SpecialValue="*"/>
<Bag Index="801" ItemIndex="*" ItemLevel="*" MonsterClass="608" SpecialValue="*"/>
Bags Used by Plugins#
Some shipped bags are not triggered by an item, monster or event, but dropped by a plugin through their index. Their manager rows use * for every trigger.
| Index | File | Used by |
|---|---|---|
200 | 200 - Custom Mix Reward.xml | ChaosMix recipes with ItemBagId |
201 | 201 - Affix Jewels.xml | MonsterAffix: Jeweller affix and Champion tier |
202 | 202 - Affix Chaos.xml | MonsterAffix: Chaos-touched affix |
204-208 | 204 - Affix Golden 1.xml .. 208 - Affix Golden 5.xml | MonsterAffix: Golden affix, Box of Kundun +1 to +5 by monster level |
209 | 209 - Affix Jewels 2.xml | MonsterAffix: Champion tier from monster level 100 (2 jewels) |
210-215 | 210 - Affix Courier 1.xml .. 215 - Affix Courier 6.xml | MonsterAffix: Courier affix, event entry parts +1 to +6 by monster level |
Index 203 is free. Start your own plugin bags at 216 or above.
Bag Configuration Formats#
Bags support two formats: Simple and Extended.
Simple Format#
Randomly selects one item from a flat list. All items have equal probability.
<ItemBag>
<BagConfig Name="Box of Luck"
DropZen="1000"
ItemDropRate="100"
ItemDropCount="1"
SetItemDropRate="0"
ItemDropType="0"
Fireworks="0"/>
<Drop Cat="13" ItemIndex="0" MinLevel="0" MaxLevel="0"
Skill="0" Luck="0" Option="0" Exc="0" Set="0" Socket="0"/>
<Drop Cat="13" ItemIndex="1" MinLevel="0" MaxLevel="0"
Skill="0" Luck="0" Option="0" Exc="0" Set="0" Socket="0"/>
</ItemBag>
Extended Format#
Weighted drops with sections, class requirements, and advanced options.
<ItemBag>
<BagConfig Name="Starter Ring 80"
DropZen="1000"
ItemDropRate="100"
ItemDropCount="1"
SetItemDropRate="0"
ItemDropType="0"
Fireworks="0"/>
<ExtendedBag>
<BagInfo Index="1" DropRate="10000">
<DropInfo Section="5" SectionRate="10000" Money="0"
OptionValue="0" RequireClass="1 0 0 0 0 0 0"/>
<DropInfo Section="6" SectionRate="5000" Money="0"
OptionValue="0" RequireClass="0 1 0 0 0 0 0"/>
</BagInfo>
<ItemSection Id="5">
<Item Index="6277" Level="3" Grade="0"
Option0="*" Option1="*" Option2="*" Option3="*"
Option4="*" Option5="*" Option6="*" Duration="1209600"/>
</ItemSection>
<ItemSection Id="6">
<Item Index="6278" Level="3" Grade="0"
Option0="*" Option1="*" Option2="*" Option3="*"
Option4="*" Option5="*" Option6="*" Duration="1209600"/>
</ItemSection>
</ExtendedBag>
</ItemBag>
BagConfig Attributes#
Common configuration for both formats.
| Attribute | Type | Default | Description |
|---|---|---|---|
Name | string | - | Bag name (for reference only) |
DropZen | int | 0 | Zen amount to drop if item roll fails |
ItemDropRate | int | 100 | Rate out of 100 for item drop chance. If check fails (random >= rate), drops DropZen instead. 100 = always try item, 0 = always drop zen |
ItemDropCount | int | 1 | Simple format only: Number of drop attempts. Each attempt rolls ItemDropRate for item vs zen. Extended format ignores this and uses BagInfo DropRate instead |
SetItemDropRate | int | 0 | Rate out of 10000 for random set item instead of bag item (e.g., 100 = 1%) |
ItemDropType | int | 0 | 0 = Fixed options, 1 = Randomize Skill/Luck and scale Option+3 inversely |
Fireworks | int | 0 | Simple format: 1 = Send fireworks effect after all drops complete, 0 = No effect. Extended format: Ignored, use OptionValue & 1 in DropInfo instead |
Simple Format: Drop Entries#
Flat list of items with equal probability.
| Attribute | Type | Description |
|---|---|---|
Cat | int | Item category (0-15) |
ItemIndex | int | Item index within category |
MinLevel | int | Minimum item level (0-15) |
MaxLevel | int | Maximum item level (0-15). If same as MinLevel, fixed level. If higher, random level in range |
Skill | int or * | 0 = No skill, 1 = Force skill, * = Use ItemOptionRate default rate logic |
Luck | int or * | 0 = No luck, 1 = Force luck, * = Use ItemOptionRate default rate logic |
Option | int or * | Fixed Option+X level (0-7 or 0-28). 0 = No option, * = Use ItemOptionRate default rate logic |
Exc | int or * | Number of excellent options to force generate (0-6), * = Use ItemOptionRate default rate logic |
Set | int or * | 0 = No set, 1 = Force set generation, * = Use ItemOptionRate default rate logic |
Socket | int or * | 0 = Use ItemOptionRate index 0 for socket generation, 1-5 = Force N sockets (0xFE placeholders), * = Use ItemOptionRate default rate logic |
Count | int | Stack size to assign when the item drops. 0 or omitted = default behavior (stack of 1). Only applies to items registered as stackable in ItemStack.xml. See ItemStack |
ItemDropType Behavior#
When ItemDropType="1":
- Skill: Randomized (50% chance)
- Luck: Randomized (50% chance)
- Option: Scaled inversely by MaxItemOption. Higher option values become less likely
- Exc: If any excellent option is set, forces Skill=1
Extended Format: BagInfo#
Defines weighted drop pools with class requirements.
| Attribute | Type | Description |
|---|---|---|
Index | int | BagInfo index (must be unique within file, arbitrary number) |
DropRate | int | Rate out of 10000 for this bag to activate (e.g., 10000 = 100%, 5000 = 50%) |
Extended Format: DropInfo#
Defines sections within a BagInfo. One section is randomly selected based on weights and class requirements.
| Attribute | Type | Description |
|---|---|---|
Section | int | ItemSection Id to use if selected |
SectionRate | int | Weight for weighted random selection. Higher = more likely |
Money | int | Zen amount to drop if section is selected but has no valid items |
OptionValue | int | Bitflags: Bit 0 (+1) = Send fireworks for this drop, Bit 1 (+2) = Check party member classes instead of just bag opener. Can combine (e.g., 3 = fireworks + party check) |
RequireClass | string | Space-separated minimum ChangeUp requirement per class: DW DK FE MG DL SU RF. Value is minimum (ChangeUp+1). 0=block, 1=allow base class, 2=require 1st ChangeUp+, 3=require 2nd ChangeUp+, 4=require 3rd ChangeUp+ |
Class Requirement Format#
"1 0 0 0 0 0 0"
Position mapping:
- Dark Wizard (0=blocked, 1=base class, 2=1st ChangeUp+, 3=2nd ChangeUp+, 4=3rd ChangeUp+)
- Dark Knight
- Fairy Elf
- Magic Gladiator
- Dark Lord
- Summoner
- Ragefighter
Example: "1 0 0 0 0 0 0" = Only Dark Wizards, base class and above (any ChangeUp)
Example: "2 2 0 0 0 0 0" = Only DW/DK with at least 1st class quest completed
Example: "3 3 3 0 0 0 0" = Only DW/DK/FE with at least 2nd class quest completed
Extended Format: ItemSection#
Defines item pools referenced by DropInfo sections.
ItemSection attributes:
Id= Section identifier (referenced by DropInfo)
Item attributes:
| Attribute | Type | Description |
|---|---|---|
Index | int | Item index (full index, e.g., 6277 = 12*512 + 277) |
Level | int | Base item level (0-15) |
Grade | int | Excellent option bitmask to use if Option4 rate generates 0 excellent options (fallback value when no excellent options roll) |
Option0 | int or * | Level generation rate index. * = Use default. |
Option1 | int or * | Skill option rate index. * = Use default. |
Option2 | int or * | Luck option rate index. * = Use default. |
Option3 | int or * | Option+X rate index. * = Use default. |
Option4 | int or * | Excellent option rate index. * = Use default. |
Option5 | int or * | Set option rate index. * = Use default. |
Option6 | int or * | Socket option rate index. * = Use default. |
Duration | int | Time-limited item duration in seconds. 0 = Permanent. 1209600 = 14 days |
Count | int | Stack size to assign when the item drops. 0 or omitted = default behavior (stack of 1). Only applies to items registered as stackable in ItemStack.xml. See ItemStack |
Option Index System#
All Option0-6 attributes reference rate tables in ItemOptionRate.xml:
- Option0: Level adjustment (can increase/decrease base level)
- Option1: Skill (0% or 100% chance depending on rate)
- Option2: Luck (0% or 100% chance depending on rate)
- Option3: Add option level (0-7 or 0-28, rate-based)
- Option4: Excellent options (generates 0-6 exc options by rate)
- Option5: Set bonus (generates set attribute by rate)
- Option6: Socket slots (generates 0-5 sockets by rate)
See ItemOptionRate for rate index definitions.
Stack Count (Count Attribute)#
Both simple bag <Drop> rows and extended bag <Item> rows accept a Count attribute that controls the stack size of the dropped item.
Rules#
- If
Countis omitted or0, the item drops with the default durability/stack value of 1 (unchanged behavior). - If
Countis greater than 0 and the item is registered as stackable in ItemStack.xml, the item's stack count is set to that value. - If the item is not registered as stackable in ItemStack.xml,
Countis ignored and the item drops with a stack of 1. SettingCounton a non-stackable item has no effect. - The stack count is stored in the same byte field as durability. For items where
Count > 1, the durability field carries the count value to the client. - Maximum value is 255 (stored as a single byte).
Examples#
Simple bag dropping 10 Jewels of Bless at once:
<Drop Cat="14" ItemIndex="13" MinLevel="0" MaxLevel="0"
Skill="0" Luck="0" Option="0" Exc="0" Set="0" Socket="0" Count="10"/>
Extended bag dropping 5 Jewels of Soul at once:
<Item Index="7182" Level="0" Grade="0"
Option0="*" Option1="*" Option2="*" Option3="*"
Option4="*" Option5="*" Option6="*" Duration="0" Count="5"/>
Important Behavior#
Over-length config fields#
Text attributes that exceed their storage limit are truncated instead of crashing the server. BagConfig.Name holds at most 31 characters; a longer value is cut to the first 31 characters, a warning naming the file and field is written to the GameServer log, and loading continues. The truncated name affects the reference label only, not drop behavior. This applies to text fields in other config files the same way.
GetItem vs DropItem (Extended Format)#
GetItem (used when bag opens into inventory):
- Iterates BagInfo entries in order and stops on the first whose DropRate roll passes
- That BagInfo then picks a DropInfo by weighted random and returns the generated item
- If the picked BagInfo's DropRate passes but no DropInfo matches the player's class, or the chosen ItemSection is missing/empty, the whole lookup terminates with no item
- Result: Maximum 1 item per bag open (
Moneyzen is never used on this path)
DropItem (used when bag drops items on ground):
- Iterates ALL BagInfo entries; each one rolls its own DropRate independently
- For each BagInfo whose DropRate passes, a DropInfo is picked and an item is dropped on the ground
- If the picked DropInfo's ItemSection is missing or empty,
MoneyAmountzen is dropped in its place - Fireworks (
OptionValue & 1) fire per successful drop, not once at the end - Result: Can drop multiple items/zen piles if multiple BagInfo entries succeed
Selection Algorithm#
Simple Format:
- Repeat
ItemDropCounttimes:- Roll random 0-99, if >=
ItemDropRate, dropDropZenzen and continue to next iteration - Roll random 0-9999, if <
SetItemDropRate, drop random set item and continue - Otherwise, pick random item from Drop list (equal probability) and drop it
- Roll random 0-99, if >=
- If
Fireworks=1, send fireworks effect after all drops
Extended Format - DropItem (ground):
- For EACH BagInfo (can process multiple BagInfo per bag open):
- Roll random 0-9999, if >=
DropRate, skip this BagInfo entirely - Build list of DropInfo entries matching player (or party, if
OptionValue & 2) class/ChangeUp requirements - If no DropInfo matches, skip this BagInfo (no drop)
- Select one DropInfo by weighted random (
SectionRate) - Find ItemSection with matching Section Id
- If the section is missing or empty, drop
Moneyzen instead - Otherwise, pick a random item from the section (equal probability) and generate options via Option0-6 rate indices
- If
OptionValue & 1, send fireworks effect for this drop
- Roll random 0-9999, if >=
- Iteration continues for every BagInfo, so a single bag can drop multiple items or zen piles
Extended Format - GetItem (inventory):
- Iterates BagInfo entries in order; the first whose DropRate roll passes is used
- Picks a DropInfo by the same weighted random rules as above
- Returns the generated item on success; returns nothing (no zen, no fireworks) if the section is missing/empty or no DropInfo matches
- Remaining BagInfo entries are not considered
Class Requirement Checking#
- OptionValue & 2 = 0: Check only the player opening the bag
- OptionValue & 2 = 2: Check all party members. If any party member matches, that DropInfo is eligible
This allows party-wide class rewards where any qualifying member triggers the drop.
Nested Bags#
To reference another bag from a drop, add a <Drop> entry pointing to an item that has its own bag definition:
<!-- Parent bag references child bag item -->
<Drop Cat="14" ItemIndex="13" MinLevel="0" MaxLevel="0"
Skill="0" Luck="0" Option="0" Exc="0" Set="0" Socket="0"/>
If item 14/13 has a bag definition in EventItemBagManager.xml, opening it triggers that bag's logic.
Examples#
Fixed rewards with equal probability.
<ItemBag>
<BagConfig Name="Blood Castle 1"
DropZen="1000"
ItemDropRate="100"
ItemDropCount="1"
SetItemDropRate="0"
ItemDropType="0"
Fireworks="0"/>
<Drop Cat="12" ItemIndex="15" MinLevel="0" MaxLevel="0"
Skill="0" Luck="0" Option="0" Exc="0" Set="0" Socket="0"/>
</ItemBag>
Result: Always drops Jewel of Bless. No randomness.
Random item quality using ItemDropType="1".
<ItemBag>
<BagConfig Name="Box of Luck"
DropZen="1000"
ItemDropRate="100"
ItemDropCount="1"
SetItemDropRate="0"
ItemDropType="1"
Fireworks="0"/>
<Drop Cat="0" ItemIndex="6" MinLevel="4" MaxLevel="4"
Skill="1" Luck="1" Option="1" Exc="1" Set="0" Socket="0"/>
<Drop Cat="13" ItemIndex="8" MinLevel="0" MaxLevel="0"
Skill="0" Luck="0" Option="2" Exc="0" Set="0" Socket="0"/>
</ItemBag>
Result: Randomly picks one item. Skill/Luck are randomized, Option is inversely scaled (higher values rarer), Exc forces Skill=1.
Different items based on character class.
<ItemBag>
<BagConfig Name="Starter Ring 80"
DropZen="1000"
ItemDropRate="100"
ItemDropCount="1"
SetItemDropRate="0"
ItemDropType="0"
Fireworks="0"/>
<ExtendedBag>
<BagInfo Index="1" DropRate="10000">
<DropInfo Section="5" SectionRate="10000" Money="0"
OptionValue="0" RequireClass="1 0 0 0 0 0 0"/>
<DropInfo Section="6" SectionRate="10000" Money="0"
OptionValue="0" RequireClass="0 1 0 0 0 0 0"/>
</BagInfo>
<ItemSection Id="5">
<Item Index="6277" Level="3" Grade="0"
Option0="*" Option1="*" Option2="*" Option3="*"
Option4="*" Option5="*" Option6="*" Duration="1209600"/>
</ItemSection>
<ItemSection Id="6">
<Item Index="6278" Level="3" Grade="0"
Option0="*" Option1="*" Option2="*" Option3="*"
Option4="*" Option5="*" Option6="*" Duration="1209600"/>
</ItemSection>
</ExtendedBag>
</ItemBag>
Result: Dark Wizards get item 6277, Dark Knights get 6278. Other classes get nothing (Money=0).
Different probabilities for reward tiers using SectionRate weights.
<ItemBag>
<BagConfig Name="Lottery Box"
DropZen="0"
ItemDropRate="100"
ItemDropCount="1"
SetItemDropRate="0"
ItemDropType="0"
Fireworks="0"/>
<ExtendedBag>
<BagInfo Index="1" DropRate="10000">
<DropInfo Section="1" SectionRate="7000" Money="0"
OptionValue="0" RequireClass="1 1 1 1 1 1 1"/>
<DropInfo Section="2" SectionRate="2500" Money="0"
OptionValue="1" RequireClass="1 1 1 1 1 1 1"/>
<DropInfo Section="3" SectionRate="500" Money="0"
OptionValue="1" RequireClass="1 1 1 1 1 1 1"/>
</BagInfo>
<ItemSection Id="1">
<Item Index="7680" Level="0" Grade="0"
Option0="*" Option1="*" Option2="*" Option3="*"
Option4="*" Option5="*" Option6="*" Duration="0"/>
</ItemSection>
<ItemSection Id="2">
<Item Index="7682" Level="0" Grade="0"
Option0="*" Option1="*" Option2="*" Option3="*"
Option4="*" Option5="*" Option6="*" Duration="0"/>
</ItemSection>
<ItemSection Id="3">
<Item Index="7684" Level="0" Grade="0"
Option0="*" Option1="*" Option2="*" Option3="*"
Option4="*" Option5="*" Option6="*" Duration="0"/>
</ItemSection>
</ExtendedBag>
</ItemBag>
Result: ONE item per open. 70% chance of common reward (section 1), 25% rare with fireworks (section 2), 5% epic with fireworks (section 3). The SectionRate values create weighted random selection: 7000/(7000+2500+500) = 70% for section 1.
Dropping a bundle of stackable items using the Count attribute.
Simple bag example - drops 10 Jewels of Bless per open:
<ItemBag>
<BagConfig Name="Jewel Bundle"
DropZen="0"
ItemDropRate="100"
ItemDropCount="1"
SetItemDropRate="0"
ItemDropType="0"
Fireworks="0"/>
<Drop Cat="14" ItemIndex="13" MinLevel="0" MaxLevel="0"
Skill="0" Luck="0" Option="0" Exc="0" Set="0" Socket="0" Count="10"/>
</ItemBag>
Extended bag example - drops 5 Jewels of Soul from an event reward:
<ItemBag>
<BagConfig Name="Event Jewel Reward"
DropZen="0"
ItemDropRate="100"
ItemDropCount="1"
SetItemDropRate="0"
ItemDropType="0"
Fireworks="1"/>
<ExtendedBag>
<BagInfo Index="1" DropRate="10000">
<DropInfo Section="1" SectionRate="10000" Money="0"
OptionValue="0" RequireClass="1 1 1 1 1 1 1"/>
</BagInfo>
<ItemSection Id="1">
<Item Index="7182" Level="0" Grade="0"
Option0="*" Option1="*" Option2="*" Option3="*"
Option4="*" Option5="*" Option6="*" Duration="0" Count="5"/>
</ItemSection>
</ExtendedBag>
</ItemBag>
Result: Drops a single item slot containing 5 Jewels of Soul. The item must be registered as stackable in ItemStack.xml (Cat 14 / Index 14 = Jewel of Soul). Without a matching ItemStack entry, Count is ignored and 1 jewel drops instead.