Market

The Market replaces the vanilla personal store. Every character owns a store of up to 50 rows, one item per row. The player puts items from the inventory into the store, gives each row a price in one currency, then opens the store (title over the head). Other players buy in person (click the seller) or from the Market search window. Zen and jewel sales are paid into the store wallet; the seller takes them out with Collect. WCoinC, WCoinP and GoblinPoint sales go straight to the seller's account.

Player Side#

ActionHow
Open the search windowS key, or type /market. The S key does nothing in Illusion Temple and Castle Siege
Open My StoreStore button in the inventory window, or /personalshop
Open another player's storeClick the seller, or /purchase <name>
Offline storeGo Offline button in My Store (see Offline Store)

File Location#

Data/Plugins/Market.xml

A missing file is not an error: the Market runs enabled with built-in defaults (see Currency - the built-in price caps differ from the shipped file).

Changes need a GameServer restart. The plugin reload does not re-read this file.

Dependencies#

Depends OnPurpose
ItemMove.xmlAllowStore="0" items cannot go into a store
Common.datTradeItemBlock* rules also block listing. WriteMarketLog turns the Market log on. OnlineRewardOfflineSystems decides if offline stores earn online rewards
MapManager.xmlMap numbers for <BlockedMaps>. Safe zone tiles for the safe-zone checks
ItemStack.xmlSingle jewels paid out by Collect stack up to the jewel's stack size
CashShopWCoinC / WCoinP / GoblinPoint balances (CashShopData table)
DataServerColumn Character.MarketStore and table dbo.MarketSaleLog, created by DataServer/SQL/Migrations/0002_market.sql

Database Setup#

The Market needs database schema 2. Apply DataServer/SQL/Migrations/0002_market.sql (the Axiom Server Manager applies it for you). The script:

  • adds Character.MarketStore (store rows + wallet, saved with the inventory in the same transaction)
  • creates dbo.MarketSaleLog (one row per sale)
  • drops the vanilla dbo.PShopItemValue table (no longer used)

Configuration Sections#

<Market Enabled="1" MaxRows="50" OpenMinLevel="6" SearchSafeZoneOnly="1" StoreViewRange="10"
        SearchPageSize="20" SearchCooldownMs="500" SaleLogKeep="50">
    <BlockedMaps></BlockedMaps>
    <Offline Enabled="1" SafeZoneOnly="1" MaxMinutes="1440" CostPerHour="0"/>
    <Currency Id="1" Enabled="1" Commission="0" Min="1" Max="0"/>
    ...
</Market>

Market#

AttributeTypeRangeDefaultEffect
Enabled0/1-10 = Market off. Store, search, buy, withdraw and collect are all refused
MaxRowsint1-5050Store rows per character
OpenMinLevelint-6Character level needed to open a store
SearchSafeZoneOnly0/1-11 = the search window (search and buying from it) only works inside a safe zone
StoreViewRangeint0+10Tiles a buyer may stand from the seller to open the store in person. 0 = anywhere on the same map
SearchPageSizeint5-2520Maximum rows per search page. The window asks for as many as it shows
SearchCooldownMsint100+500Minimum milliseconds between two searches of one player
SaleLogKeepint1-5050Sales kept per seller for the Sold tab

Out-of-range values are clamped to the nearest limit.

BlockedMaps#

Comma-separated map numbers where a store cannot be opened. Spaces are ignored.

<BlockedMaps>0, 2, 3</BlockedMaps>

These maps are always blocked, even with an empty list:

MapNumbers
Chaos Castle 1-718-23, 53
Illusion Temple 1-645-50
Silent (Custom Arena map)40

Offline#

AttributeTypeRangeDefaultEffect
Enabled0/1-10 = no offline store
SafeZoneOnly0/1-11 = going offline only works inside a safe zone
MaxMinutesint0-432001440Minutes a store may stay offline. 0 = no limit. 43200 = 30 days
CostPerHourzen0+0Zen per hour. 0 = free

Currency#

One element per currency. A currency with no element keeps its built-in rule.

IdCurrencyPaid to
1ZenStore wallet
2Jewel of BlessStore wallet
3Jewel of SoulStore wallet
4Jewel of ChaosStore wallet
5WCoinCSeller's account
6WCoinPSeller's account
7GoblinPointSeller's account
AttributeTypeRangeDefaultEffect
Idint1-7-Currency. Other values are skipped
Enabled0/1-10 = players cannot pick this currency for a listing
Commissionint0-1000Percent the server keeps from each sale. The seller gets the rest
Minint1+1Lowest allowed price
Maxint0+0Highest allowed price. 0 = hard maximum

Jewel prices count single jewels. A bundle counts as 10, 20 or 30 by its level.

Hard maximum (used when Max is 0 or too high):

CurrencyHard maximum
Zen9,000,000,000,000,000,000
Jewels and coins2,147,483,647

Built-in rule when the element (or the whole file) is missing: Enabled 1, Commission 0, Min 1, Max = zen hard maximum / 10,000 for jewels / 1,000,000 for coins. Note that an element with Max="0" gives the hard maximum, not these values.

Important Behavior#

Store rows#

  • Items go into the store and come out only while the store is closed. Prices also change only while it is closed.
  • A row may sit in the store with no price (unlisted). Only priced rows are shown to buyers.
  • Opening needs: OpenMinLevel, a map that is not blocked, at least one priced row, no trade / duel / other window open, and no item lock (/lock).
  • Logging out closes the store (unless it went offline). Rows and wallet stay saved. The player reopens it next time.
  • The store closes by itself when the last priced row is sold.
  • Lowering MaxRows does not delete anything. Rows above the new limit are not sold or shown to buyers, but the owner still sees them and can take them out.

What cannot be listed#

Refused when putting the item in, when pricing it and again at the moment of sale:

  • AllowStore="0" in ItemMove.xml
  • event items and rental (time-limited) items
  • lucky items when TradeItemBlockLucky = 1 in Common.dat
  • excellent / set / harmony items blocked by the TradeItemBlock* rules in Common.dat (GMs bypass these)
  • pentagrams with errtels in their sockets
  • items bound to the character (item extension binding, such as a bound inscription)
  • any item while the player has an item lock (/lock) on

When a rule changes, rows that are no longer allowed become unlisted the next time the owner opens the store. The item stays in the store.

Buying#

  • In person: same map, within StoreViewRange tiles of the seller.
  • From search: inside a safe zone when SearchSafeZoneOnly = 1. Distance does not matter.
  • Search only lists stores on the same GameServer. Own rows never show in search.
  • Search filters: name text, currency, minimum item level, excellent, ancient, socket, luck, skill, option. Sort: newest, price low-high, price high-low. When a store changes, every open search page that shows it refreshes.
  • The buyer must have room in the inventory. If the row changed after the buyer saw it (sold, repriced, withdrawn) the buy is refused.
  • One store action or buy per 150 ms per player.

Jewel payment#

The buyer must pay the exact price from single jewels and bundles. Bundles are used first (30, 20, 10), then singles. If the exact amount cannot be made from what the buyer holds, the buy is refused, even if the total is higher. Example: price 15, buyer holds one bundle of 20 and nothing else = refused.

Wallet and Collect#

  • Zen and jewel sales go into the store wallet (price minus commission).
  • Collect moves zen to the character (up to the zen cap) and creates jewels in the inventory, bundles first, then singles. If the inventory fills up, the rest stays in the wallet.
  • A sale is refused when it would push the seller's wallet past its cap (zen cap, or 2,147,483,647 jewels per type).

Coin sales (escrow)#

WCoinC, WCoinP and GoblinPoint sales run through the DataServer:

  1. The DataServer takes the coins from the buyer and writes a MarketSaleLog row with Status = 0 (pending).
  2. The GameServer moves the item and tells the DataServer to pay the seller (Status = 1).
  3. If the buyer or seller left, the row changed, or the buyer's inventory is full, the buyer is refunded (Status = 2) and the item stays in the store.
  4. If the DataServer does not answer within 15 seconds, the row is released. A late answer is refunded.

The DataServer checks every 60 seconds for rows still at Status = 0 after 10 minutes (GameServer crash, link drop):

Item is found...Result
in the seller's storeBuyer refunded, Status = 2
in the buyer's inventorySeller paid, Status = 1
anywhere elseStatus = 3, red log line. A GM must settle it by hand

Sale log#

Each seller sees the last SaleLogKeep sales in the Sold tab. Older sold rows are deleted. Pending (Status 0) and stuck (Status 3) rows are never deleted: they are the proof of payment.

To show listings and sales on a website, see Website: Market.

Offline Store#

Go Offline in My Store logs the player out. The character stays in the world with the store open and keeps selling, like /offattack.

Needs: Offline Enabled = 1, the store already open with priced rows, a safe zone when SafeZoneOnly = 1, MuHelper and /offattack not running, no coin purchase in progress, and enough zen for the first hour.

  • The first hour is paid when going offline, then every hour. The cost is taken from the wallet zen first, then the character's zen.
  • Online-time rewards are paused while offline unless OnlineRewardOfflineSystems = 1 in Common.dat.

The offline store ends when:

  • the player logs in again
  • the store sells out or is closed
  • MaxMinutes passes
  • the hourly cost cannot be paid
  • a GM disconnects the character, or the server shuts down

Rows and wallet are saved in every case.

Old personal store items#

On the first login after the update, items left in the vanilla 8x4 personal store grid move into free store rows, unlisted. If the store is full, the rest stay in the old grid and a log line is written.

Market log#

WriteMarketLog in GameServerInfo - Common.dat (default 1) writes every deposit, withdraw, price change, open/close, sale, collect and coin escrow step to the Market log folder. Refused requests are logged as [Market][Reject][<action>] with the reason (max 10 lines per second per player).

Examples#

<Market Enabled="1" MaxRows="50" OpenMinLevel="50" SearchSafeZoneOnly="1" StoreViewRange="10"
        SearchPageSize="20" SearchCooldownMs="500" SaleLogKeep="50">
    <BlockedMaps>30</BlockedMaps>
    <Offline Enabled="1" SafeZoneOnly="1" MaxMinutes="1440" CostPerHour="0"/>
    <Currency Id="1" Enabled="1" Commission="5" Min="1000" Max="0"/>
    <Currency Id="2" Enabled="1" Commission="5" Min="1" Max="10000"/>
    <Currency Id="3" Enabled="1" Commission="5" Min="1" Max="10000"/>
    <Currency Id="4" Enabled="1" Commission="5" Min="1" Max="10000"/>
    <Currency Id="5" Enabled="0"/>
    <Currency Id="6" Enabled="0"/>
    <Currency Id="7" Enabled="0"/>
</Market>

Common Issues#

Last updated October 2, 2026