Shop System

The Shop system controls what items NPCs sell in their shops. It uses a two-file pattern: a central registry (ShopManager.xml) that maps NPCs to shop files, and individual shop files (Shop/*.xml) that define item inventories.

See also: Data overview for where this fits in the shared game content.

File Locations#

  • Registry: Data/ShopManager.xml
  • Shop Files: Data/Shop/NNN - ShopName.xml

Where NNN is a 3-digit shop index (000-999).

Configuration Pattern#

Step 1: Register Shop in ShopManager.xml#

Define which NPC uses which shop file.

<ShopList>
    <Shop Index="0" Npc="251" Map="*" X="*" Y="*"/>
</ShopList>
AttributeTypeDescription
IndexintShop index. Must match the shop file name prefix (e.g., 000, 001). Index values are stored in a map keyed by Index, so each Index must be unique in ShopManager.xml. Filenames are limited to 3 digits (000-999)
Npcint/stringNPC class ID that opens this shop. Use "*" to match any NPC (converted to -1 internally)
Mapint/stringMap number where this shop is available. Use "*" to match any map (converted to -1 internally)
Xint/stringX coordinate where this shop is available. Use "*" to match any X (converted to -1 internally)
Yint/stringY coordinate where this shop is available. Use "*" to match any Y (converted to -1 internally)

Step 2: Create Shop File#

Create Data/Shop/NNN - Description.xml where NNN matches the Index from ShopManager.xml.

Shop File Structure#

Individual shop files define the items available for purchase. Items can be listed directly under <Shop>, or grouped into <Page> elements for multi-page shops.

Flat Layout (Single Page)#

<?xml version="1.0"?>
<Shop>
    <Item Cat="0" Index="4" Level="7" Durability="0" Duration="0" Skill="1" Luck="0" Option="0"
          Excellent="48" Ancient="0" JOH="0" OpEx="0"
          Socket1="255" Socket2="255" Socket3="255" Socket4="255" Socket5="255"/>
    <!-- More items... -->
</Shop>

Multi-Page Layout#

Use <Page> elements to organize items across multiple pages. Each <Page> starts a new shop page. Up to 8 pages are supported.

<?xml version="1.0"?>
<Shop>
    <Page>
        <!-- Page 1: Weapons -->
        <Item Cat="0" Index="4" Level="7" Durability="0" Duration="0" Skill="1" Luck="0" Option="0"
              Excellent="48" Ancient="0" JOH="0" OpEx="0"
              Socket1="255" Socket2="255" Socket3="255" Socket4="255" Socket5="255"/>
    </Page>
    <Page>
        <!-- Page 2: Armor -->
        <Item Cat="7" Index="0" Level="5" Durability="0" Duration="0" Skill="0" Luck="0" Option="0"
              Excellent="0" Ancient="0" JOH="0" OpEx="0"
              Socket1="255" Socket2="255" Socket3="255" Socket4="255" Socket5="255"/>
    </Page>
</Shop>

Item Attributes#

AttributeTypeDefaultDescription
Catint-Item category (0-15). See Item.xml for categories
Indexint-Item index within category. Together with Cat, identifies the item
Levelint0Item level (0-15). Adds stats and level requirement
Durabilityint0For regular items: durability (0 = use default). For stackable items: stack count (0 = 1)
Durationint0Temporary item duration in seconds (0 = permanent). See Temporary Items
Skillint0Has skill (1 = yes, 0 = no). Adds +skill option and enables special attacks
Luckint0Has Luck (1 = yes, 0 = no). Adds critical damage chance
Optionint0Additional option level (0-7). Each level adds 4 to primary stat
Excellentint0Excellent option flags (bitwise). See Excellent Options section
Ancientint0Ancient item ID (0 = none). See Ancient item configuration
JOHint0Jewel of Harmony option index (0 = none)
OpExint0380 item option index (0 = none)
Socket1int255Socket 1 option index (255 = empty socket)
Socket2int255Socket 2 option index (255 = empty socket)
Socket3int255Socket 3 option index (255 = empty socket)
Socket4int255Socket 4 option index (255 = empty socket)
Socket5int255Socket 5 option index (255 = empty socket)

Excellent Options (Bitwise Flags)#

The Excellent attribute uses bitwise flags (0-63). Add values together for multiple options:

BitValueDescription
01Excellent option 1
12Excellent option 2
24Excellent option 3
38Excellent option 4
416Excellent option 5
532Excellent option 6

Example: Excellent="48" (32 + 16) = Options 5 and 6 enabled

Actual option effects are defined in ItemOption.xml and vary by item type:

  • Weapons: Typically include Mana/HP per kill, attack speed, damage bonuses
  • Armor/Shields: Typically include HP/Mana boosts, defense, damage reduction
  • Wings: May include max HP%, attack speed, or other special effects

Temporary Items#

The Duration attribute creates time-limited items that expire after a set number of seconds. When a player purchases a temporary item, the server tracks its remaining lifetime.

Duration ValueMeaning
0Permanent item (default)
36001 hour
864001 day (24 hours)
6048001 week (7 days)
259200030 days

Example: A 7-day temporary weapon:

<Item Cat="0" Index="4" Level="9" Durability="0" Duration="604800" Skill="1" Luck="1" Option="4"
      Excellent="63" Ancient="0" JOH="0" OpEx="0"
      Socket1="255" Socket2="255" Socket3="255" Socket4="255" Socket5="255"/>

Shop Matching Algorithm#

When a player clicks an NPC, the server uses a two-pass algorithm to find the correct shop:

Pass 1: Exact Match#

Finds the first shop where ALL four fields match exactly:

  • Npc == NPC class ID
  • Map == map number
  • X == X coordinate
  • Y == Y coordinate

Wildcards ("*") are converted to -1 during loading, so a shop with Map="*" will only match if the actual map number is -1 (invalid), not "any map".

Pass 2: NPC-Only Match#

If Pass 1 fails, finds the first shop where:

  • Npc == NPC class ID
  • Npc is NOT -1 (not a wildcard)
  • Map, X, Y are completely ignored

No Match#

If neither pass succeeds, the NPC has no shop and the interaction fails.

Item Pricing#

Shop items use pricing defined in ItemValue.xml. The currency system works as follows:

Currency Selection (priority order, highest first):

  1. GoblinPoints - If Coin3 toggle is set in ItemValue.xml
  2. WCoinP (Premium coins) - If Coin2 toggle is set
  3. WCoinC (Cash shop coins) - If Coin1 toggle is set
  4. Zen (default) - If no coin toggles are set

Price Multipliers:

  • Stackable items: Buy/sell prices multiply by stack count automatically
  • Non-stackable items: Use base prices from ItemValue.xml
  • Items without ItemValue.xml entries use calculated prices from item properties

See ItemValue documentation for details on configuring custom prices and currency types.

Dependencies#

FilePurpose
Item.xmlDefines all available items, categories, and base stats
ItemValue.xmlDefines custom buy/sell prices and currency types (Zen/WCoinC/WCoinP/GP)
ItemStack.xmlDefines which items are stackable and their maximum stack sizes
SocketItemType.xmlDefines which items can have sockets and maximum socket count
SocketItemOption.xmlDefines socket option effects
SetItemOption.xmlDefines ancient set bonuses

Examples#

<?xml version="1.0"?>
<Shop>
    <!-- Basic sword with skill, no options -->
    <Item Cat="0" Index="4" Level="0" Durability="0" Duration="0" Skill="1" Luck="0" Option="0"
          Excellent="0" Ancient="0" JOH="0" OpEx="0"
          Socket1="255" Socket2="255" Socket3="255" Socket4="255" Socket5="255"/>

    <!-- Enhanced sword: +7, +Luck, +2 option, Excellent (Mana/kill + Attack speed) -->
    <Item Cat="0" Index="4" Level="7" Durability="0" Duration="0" Skill="1" Luck="1" Option="2"
          Excellent="7" Ancient="0" JOH="0" OpEx="0"
          Socket1="255" Socket2="255" Socket3="255" Socket4="255" Socket5="255"/>
</Shop>

Important Behavior#

Filename Parsing#

The server only loads shop files matching the pattern NNN - Name.xml:

  • First 3 characters MUST be digits (000-999)
  • Must have space-dash-space (-) separator after digits (character positions [3] = space, [4] = dash, [5] = space)
  • Filename must contain .xml

Files like 1 - Shop.xml, 01 - Shop.xml, or Shop001.xml will NOT load.

Shop Capacity and Layout#

Each shop page has 120 slots arranged in a grid. A shop can have up to 8 pages, for a maximum of 960 total slots.

Per-Page Grid:

  • 8 columns (X: 0-7)
  • 15 rows (Y: 0-14)
  • Total per page: 120 slots

Item Placement:

  • Items auto-arrange left-to-right, top-to-bottom during loading
  • Items occupy multiple slots based on their size (width × height from Item.xml)
  • Example: A 2×3 item occupies 6 adjacent slots in the grid
  • The server validates that items fit within grid boundaries (8 columns wide, 15 rows tall)
  • If a page fills up, items automatically overflow to the next page
  • When using <Page> elements, each <Page> explicitly starts a new page

Slot Calculation: Slot = (Y × 8) + X

  • Slot 0 = position (0, 0) - top-left
  • Slot 7 = position (7, 0) - top-right
  • Slot 119 = position (7, 14) - bottom-right

Stackable Items#

For stackable items (potions, jewels, etc.), the Durability attribute controls the stack count:

  • Durability="0" = 1 item (default)
  • Durability="10" = stack of 10 items
  • Durability="255" = stack of 255 items (maximum)

Price behavior:

  • Buy price: ItemValue.xml price × stack count
  • Sell price: ItemValue.xml sell price × stack count
  • Prices automatically scale when buying/selling stacked items from shops

Socket Slots#

Set Socket1-Socket5 to 255 for empty sockets.

Important behavior:

  • The server validates socket support using SocketItemType.xml before assigning sockets
  • Only items that support sockets (defined in SocketItemType.xml) will have socket slots allocated
  • Socket slots are only assigned up to the maximum socket count for that item type
  • Example: If an item supports 3 sockets, only Socket1-Socket3 are used; Socket4 and Socket5 are ignored

If an item doesn't support sockets, all socket attributes are ignored regardless of configuration values.

NPC Matching Priority#

Always use specific Map/X/Y when possible. Wildcard shops (Map="*") can cause unexpected behavior if multiple NPCs share the same class ID.

Common Issues#

Adding a New Shop#

  1. Choose Shop Index: Pick an unused index. The filename prefix supports 000-999
  2. Register in ShopManager.xml:
    <Shop Index="50" Npc="999" Map="0" X="100" Y="100"/>
    
    Use Map="*" X="*" Y="*" for global shops (any location).
  3. Create Shop File: Data/Shop/050 - My Custom Shop.xml
    • Filename MUST be exactly 3 digits, space-dash-space, description
    • Shop index (50) must match filename prefix (050)
  4. Add Items: Use examples above as templates
  5. Configure Pricing (optional): Add entries to ItemValue.xml for custom prices/currencies
  6. Configure Stackables (optional): Ensure stackable items are defined in ItemStack.xml
  7. Reload shops: run /reload shop (or reload.shop in the Server Manager), or restart the GameServer
  8. Test: Click NPC to verify shop opens with correct items and prices

Last updated October 1, 2026