Auction house
Players list items from their hand, buy through a GUI and collect unsold items from /ah expired.
Commands 1#
How the auction house works#
A separate module of the fork: players list the whole stack in their main hand with /ah sell <price>, and everyone else buys through the /ah GUI. Anything unsold when the timer runs out goes to /ah expired and waits there until the seller collects it.
The money flow is the same Vault/EconomyAPI that /pay uses. The config is config/auctionhouse.json (not the neoessentials/ folder). Data lives in the DataStore collections auction_listings / auction_expired.
The module is turned off with modules (auction house) and commands.ah. While the command is disabled, its Brigadier tree is not registered.
Examples#
List an item and buy it from another account#
Check that the economy and the GUI are connected: the seller loses the item from their hand, the buyer pays, and the seller gets the money even while offline.
/ah sell 250
/ah selling
/ah
sell takes the whole stack from the main hand (an empty hand gives "need_item"; a price ≤ 0 is rejected already at the Brigadier level). In /ah selling the seller sees the listing with a timer; in /ah everyone sees it. Buying is a click in the GUI, not a command. If the player already has maxItemsPerPlayer active listings, sell replies with a limit error and the item stays in the hand.
Collect unsold items after expiry#
A listing stayed up for a week (auctionSecondsDuration, 604800 s by default) and disappeared from the storefront — it must not be lost silently.
/ah expired
Opens the unsold items GUI. You can collect only your own listings. The item returns to the inventory or drops at your feet if there is no room. Until the player collects it, the record lives in the auction_expired collection of the same storage.type as the rest of the mod.
Reload the listing limit without a restart#
You changed maxItemsPerPlayer in config/auctionhouse.json and want the new cap to apply immediately.
/ah reload
Only config/auctionhouse.json is re-read (not config.json and not crates.json). Requires neoessentials.ah.reload (or OP with opsBypassPermissions). Existing listings are not trimmed — the limit is checked only on a new /ah sell.
Edge cases#
The config is not in config/neoessentials/#
AuctionConfig writes config/auctionhouse.json at the root of the server's configs, not in config/neoessentials/. It has three keys: maxItemsPerPlayer (10), auctionSecondsDuration (604800), maxPages (50). /neoe reload does not touch this file.
What to do: Edit config/auctionhouse.json and run /ah reload. The whole module is enabled by modules + commands.ah — changing those needs a restart.
A double click in two GUIs no longer duplicates an item#
cancelListing and buyItem first atomically remove the listing from activeListings, and only then move items and money. Previously two windows on one listing gave two items or a double payment. If the removal fails, the method returns false and changes nothing. If the buyer does not have enough money, the listing is put back.
What to do: If a player swears they "bought it but have no item", check logs/debug.log with the auctionHouse.debug category instead of relying on chat: the GUI may close before the message arrives.
The seller is paid even if the deposit was cancelled#
After a successful withdraw from the buyer, the listing is already removed. EconomyAPI.deposit to the seller may be cancelled by an EconomyDepositEvent listener or hit the balance cap. In that case the manager sets the balance via setBalance, bypassing the cancellable event — otherwise the buyer's money would vanish.
What to do: Do not count on an economy protection plugin blocking auction payouts. The seller's balance cap can be exceeded this way.
Shared DataStore, not a separate auctionhouse.db#
Active listings are the auction_listings collection, expired ones are auction_expired, on the same backend as storage.type. The old auctionhouse.db is imported once if the collection is empty and autoMigrate is on. The listing's numeric id is kept when it moves to expired.
What to do: After changing storage.type, do not copy auctionhouse.db by hand — wait for the migration or check neoessentials/store/.
Permissions 3#