Shop System
Configure NPC shops with custom items, pricing, and options
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.
File Locations
Registry:
GameServer/Data/ShopManager.xmlShop Files:
GameServer/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>Index
int
Shop index (0-99, limited by MAX_SHOP=100). Must match the shop file name prefix (e.g., 000, 001)
Npc
int/string
NPC class ID that opens this shop. Use "*" to match any NPC (converted to -1 internally)
Map
int/string
Map number where this shop is available. Use "*" to match any map (converted to -1 internally)
X
int/string
X coordinate where this shop is available. Use "*" to match any X (converted to -1 internally)
Y
int/string
Y coordinate where this shop is available. Use "*" to match any Y (converted to -1 internally)
Step 2: Create Shop File
Create GameServer/Data/Shop/NNN - Description.xml where NNN matches the Index from ShopManager.xml.
The filename format is strict: NNN - Description.xml where the first 3 characters are digits, followed by - (space-dash-space).
Shop File Structure
Individual shop files define the items available for purchase.
Item Attributes
Cat
int
-
Item category (0-15). See Item.txt for categories
Index
int
-
Item index within category. Together with Cat, identifies the item
Level
int
0
Item level (0-15). Adds stats and level requirement
Durability
int
0
For regular items: durability (0 = use default). For stackable items: stack count (0 = 1)
Skill
int
0
Has skill (1 = yes, 0 = no). Adds +skill option and enables special attacks
Luck
int
0
Has Luck (1 = yes, 0 = no). Adds critical damage chance
Option
int
0
Additional option level (0-7). Each level adds 4 to primary stat
Excellent
int
0
Excellent option flags (bitwise). See Excellent Options section
Ancient
int
0
Ancient item ID (0 = none). See Ancient item configuration
JOH
int
0
Jewel of Harmony option index (0 = none)
OpEx
int
0
380 item option index (0 = none)
Socket1
int
255
Socket 1 option index (255 = empty socket)
Socket2
int
255
Socket 2 option index (255 = empty socket)
Socket3
int
255
Socket 3 option index (255 = empty socket)
Socket4
int
255
Socket 4 option index (255 = empty socket)
Socket5
int
255
Socket 5 option index (255 = empty socket)
Excellent Options (Bitwise Flags)
The Excellent attribute uses bitwise flags (0-63). Add values together for multiple options:
0
1
Excellent option 1
1
2
Excellent option 2
2
4
Excellent option 3
3
8
Excellent option 4
4
16
Excellent option 5
5
32
Excellent 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
The Excellent field in the shop configuration is a bitmask that enables option slots. The actual stat bonuses applied depend on the item's category and are looked up in ItemOption.xml at indices 3-8 (corresponding to bits 0-5).
Excellent options only apply if the item supports them. Check ItemOption.xml for specific item index ranges and their assigned bonuses before configuring shop items with excellent options.
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 IDMap== map numberX== X coordinateY== 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 IDNpcis NOT-1(not a wildcard)Map,X,Yare completely ignored
No Match
If neither pass succeeds, the NPC has no shop and the interaction fails.
How to use wildcards correctly:
Use
Map="*" X="*" Y="*"to create a global NPC shop that works anywhereThis works because Pass 2 ignores position entirely
Pass 1 will fail (map/position don't match -1), then Pass 2 succeeds (NPC class matches)
Position-specific shops: To have the same NPC with different shops at different locations:
Create shop entries with exact Map/X/Y coordinates
Do NOT create a wildcard entry for that NPC
Pass 1 will match the exact location
If player clicks the NPC at a non-registered location, Pass 2 will fail (no wildcard fallback)
The algorithm returns the first match found when iterating through registered shops. If multiple shops match the criteria, only the first one is used. Shop registration order in ShopManager.xml matters.
Item Pricing
Shop items use pricing defined in ItemValue.xml. The currency system works as follows:
Currency Selection (priority order, highest first):
GoblinPoints - If
Coin3toggle is set in ItemValue.xmlWCoinP (Premium coins) - If
Coin2toggle is setWCoinC (Cash shop coins) - If
Coin1toggle is setZen (default) - If no coin toggles are set
The Coin1, Coin2, and Coin3 fields in ItemValue.xml are toggles (0 or 1), not currency amounts. They select which currency to use. The actual price is stored in the BuyPrice and SellPrice fields.
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
Defines all available items, categories, and base stats
Defines custom buy/sell prices and currency types (Zen/WCoinC/WCoinP/GP)
Defines which items are stackable and their maximum stack sizes
Defines which items can have sockets and maximum socket count
Defines socket option effects
Defines ancient set bonuses
Examples
Each shop index (25, 26) has its own shop file with different items.
Ancient="5" refers to an ancient set defined in SetItemOption.xml.
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)Must have
.xmlextension
Files like 1 - Shop.xml, 01 - Shop.xml, or Shop001.xml will NOT load.
While filenames support 000-999, the shop index is limited to 0-99 by MAX_SHOP=100. Shop files with indices 100-999 will be ignored even if they match the filename pattern.
Shop Capacity and Layout
Each shop has 120 slots arranged in a grid:
8 columns (X: 0-7)
15 rows (Y: 0-14)
Total: 120 slots (SHOP_SIZE=120)
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.txt)
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 an item cannot fit in the remaining space, it's skipped
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 itemsDurability="255"= stack of 255 items (maximum)
Price behavior:
Buy price:
ItemValue.xml price × stack countSell price:
ItemValue.xml sell price × stack countPrices automatically scale when buying/selling stacked items from shops
The server detects stackable items using ItemStack.xml configuration. Items not defined as stackable will use Durability as actual durability value instead of stack count.
Socket Slots
Set Socket1-Socket5 to 255 for empty sockets.
Important behavior:
The server validates socket support using
SocketItemType.xmlbefore assigning socketsOnly 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-Socket3are used;Socket4andSocket5are 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
Shop not appearing: Check these common mistakes:
Filename doesn't match
NNN - Name.xmlpatternIndex in ShopManager.xml doesn't match filename prefix
NPC class ID mismatch between ShopManager.xml and actual NPC in map
Items appear but can't be purchased: Check ItemValue.xml for pricing. Items without prices default to 0 Zen.
Wrong shop opens: Multiple shops with same NPC ID will use first match. Use Map/X/Y coordinates to differentiate position-specific shops.
Testing shops: Use /move command to teleport to NPC location, or spawn NPC in test map to verify shop contents before deploying to production.
Adding a New Shop
Choose Shop Index: Pick unused index (0-99, limited by MAX_SHOP)
Register in ShopManager.xml:
Use
Map="*" X="*" Y="*"for global shops (any location).Create Shop File:
GameServer/Data/Shop/050 - My Custom Shop.xmlFilename MUST be exactly 3 digits, space-dash-space, description
Shop index (50) must match filename prefix (050)
Add Items: Use examples above as templates
Configure Pricing (optional): Add entries to ItemValue.xml for custom prices/currencies
Configure Stackables (optional): Ensure stackable items are defined in ItemStack.xml
Restart GameServer: Shops load at startup only
Test: Click NPC to verify shop opens with correct items and prices
You can reload shops without restarting by calling gShopManager.LoadShop() from code, but this requires a custom admin command. By default, shops only load during server startup.
Shop files with indices 100+ will be ignored even if the filename is valid (e.g., 100 - Shop.xml) due to MAX_SHOP=100 limitation.
Last updated