-
Notifications
You must be signed in to change notification settings - Fork 58
Shop
The Shop addon lets you create unlimited, fully-configurable shops for X-Prison — one file per shop. Every item is priced in any currency your server has registered (Money, Tokens, Gems, or your own custom currencies), and a purchase can hand the player items and/or run console commands. The whole experience is GUI-driven: players open a master /shop menu, pick a shop, and buy. There is no database — a shop is stateless, and the only purchase gate is the player's balance plus optional permissions.
| Requirement | Notes |
|---|---|
| X-Prison |
2026.2.6.1 or newer |
| Currencies module | Must be enabled — the addon reads/writes balances through the X-Prison currency API |
| Java 17+ | Required |
| Paper / Spigot / Folia | 1.13 – latest |
If the Currencies module is unavailable when the server starts, the addon logs
[Shop] Currency module is not available. Disabling addon.and does nothing else. Make sure at least one currency is registered before configuring shops.
- Download
X-Prison-Shop-*.jarfrom your purchase platform. - Place the JAR inside
plugins/X-Prison/addons/. - Restart the server (do not use
/reload). - Default config files are created at
plugins/X-Prison/addons/Shop/:-
shop.yml— global settings + the master menu + the confirm menu -
shop-messages.yml— all player-facing text -
shops/tokens-shop.ymlandshops/gems-shop.yml— two ready-to-edit example shops
-
- Edit the files, then run
/shop reloadto apply changes without restarting.
Adding a new shop is just adding a file. Drop any
.ymlfile intoplugins/X-Prison/addons/Shop/shops/and it appears automatically in the/shopmenu after a reload. Copy one of the examples to get started.
-
Open the master menu — Player runs
/shop. Every enabled shop they have permission to view is listed as a clickable icon (the menu paginates automatically if there are more shops than slots). -
Open a shop — Clicking a shop icon (or running
/shop <id>, or a per-shop alias such as/tokenshop) opens that shop's own paginated item menu. - Buy — Left-click or right-click an item to buy one. Shift-click to buy the item's configured bulk amount.
-
Confirm (optional) — If
confirm-purchasesis enabled, a confirm/cancel menu is shown before the player is charged. - Result — On a successful purchase the player's currency is debited, any configured items are placed in their inventory, any configured commands are run from console, and a success message + sound are played.
- Inventory-full protection. If an item grants physical items, the addon simulates fitting them into the player's inventory before charging. If there isn't room, the purchase is refused and nothing is deducted — players are never charged for items they can't hold.
-
Free items. If the total price is
0, the currency step is skipped entirely (soprice: 0reward items work without being rejected as an invalid amount). -
Unknown currency. If an item references a currency that isn't registered, the purchase fails with a message and a warning is logged. Every shop item's currency is also validated on load and on
/shop reload, so misconfigurations show up in the console immediately.
| Command | Permission | Default | Description |
|---|---|---|---|
/shop |
command.permission in shop.yml (empty = everyone) |
All players | Open the master shop menu |
/shop <id> |
Same as above (+ the shop's own permission) |
All players | Open a specific shop directly |
/shop reload |
xprison.shop.admin |
Operators | Reload settings, messages, and all shop definitions |
Default aliases: /shops (configurable via command.aliases).
Per-shop open commands: each shop can define open-command-aliases (e.g. /tokenshop, /gemshop) that open it directly. The shipped examples register /tokenshop and /gemshop.
Permission layers:
| Where | Key | Effect |
|---|---|---|
| Global |
command.permission (in shop.yml) |
Required to run /shop at all. Empty = everyone |
| Per shop |
permission (in the shop file) |
Required to see/open that shop. Empty = everyone. Shops the player can't access are hidden from the master menu |
| Per item |
permission (on an item) |
Required to buy that item. Empty = anyone can buy |
| Admin | xprison.shop.admin |
Required for /shop reload
|
Command names and aliases are registered at startup. Changing
command.name,command.aliases, or a shop'sopen-command-aliases(or adding a brand-new shop that defines aliases) requires a full server restart —/shop reloadrefreshes settings, messages, items, and prices, but not command registrations.
Global settings, the master menu, and the optional confirmation menu all live in shop.yml. All text supports MiniMessage tags and legacy & colour codes.
# Master toggle for the whole addon.
enabled: true
command:
name: shop
aliases: [shops]
# Permission required to run /shop. Leave empty for everyone.
permission: ""
# Currency used by any shop item that does not specify its own `currency`.
# Must match a currency name registered by X-Prison (e.g. money, tokens, gems).
default-currency: tokens
# When true, clicking an item opens a confirmation menu (confirm-gui below)
# before the purchase is charged.
confirm-purchases: false
sounds:
purchase-success: ENTITY_EXPERIENCE_ORB_PICKUP
purchase-fail: ENTITY_VILLAGER_NO
# ---------------------------------------------------------------------------
# Master menu shown by /shop — one button per shop.
# ---------------------------------------------------------------------------
menu:
title: '<gradient:#f7971e:#ffd200><bold>SHOPS</bold></gradient>'
rows: 6
filler: BLACK_STAINED_GLASS_PANE
# Slots the shop buttons are placed into (paginates automatically if there
# are more shops than slots).
shop-slots: [10, 11, 12, 13, 14, 15, 16,
19, 20, 21, 22, 23, 24, 25,
28, 29, 30, 31, 32, 33, 34]
decorations:
border:
material: GRAY_STAINED_GLASS_PANE
name: ' '
slots: [0, 1, 2, 3, 4, 5, 6, 7, 8, 45, 46, 47, 51, 52, 53]
buttons:
close:
slot: 49
material: BARRIER
name: '<red>Close'
prev-page:
slot: 48
material: ARROW
name: '<yellow>« Previous Page'
next-page:
slot: 50
material: ARROW
name: '<yellow>Next Page »'
# ---------------------------------------------------------------------------
# Confirmation menu (only used when confirm-purchases: true).
# Placeholders: %amount% %price% %unit-price% %balance% %currency%
# ---------------------------------------------------------------------------
confirm-gui:
title: '<dark_gray>Confirm Purchase'
rows: 3
filler: BLACK_STAINED_GLASS_PANE
preview-slot: 13
confirm:
slot: 11
material: LIME_WOOL
name: '<green><bold>CONFIRM'
lore:
- '<gray>Buy <white>%amount%x</white> for'
- '<gold>%price% <gray>%currency%'
cancel:
slot: 15
material: RED_WOOL
name: '<red><bold>CANCEL'
lore:
- '<gray>Return to the shop'| Option | Description |
|---|---|
enabled |
Master switch. Set to false to disable the entire addon |
command.name |
Base command that opens the master menu (default shop) |
command.aliases |
Extra labels for the master command (default [shops]) |
command.permission |
Permission to run /shop. Leave empty ("") for everyone |
default-currency |
Currency used by any item that doesn't set its own currency. Must be a registered currency name |
confirm-purchases |
When true, every purchase routes through the confirm menu first |
sounds.purchase-success / sounds.purchase-fail
|
Bukkit Sound enum names played on success/failure. Use none (or leave blank) to disable |
menu.* |
Layout of the master /shop menu — title, rows, filler, shop-slots, decorations, and buttons
|
confirm-gui.* |
Layout of the confirmation menu — title, rows, filler, preview-slot, and the confirm / cancel buttons |
Both the master menu and every shop GUI share the same building blocks:
-
filler— a material that fills empty slots. Set toAIRorNONEto leave them empty. -
decorations— named blocks of{ material, name, slots: [...] }used for borders/accents. Add as many as you like. -
buttons— recognised keys areclose,prev-page,next-page(master menu and shops) plusback(shops only, returns to the master menu). Each button takes aslot,material,name, and optionallore/glow/custom_model_data. Pagination buttons only appear when there's another page to show. -
shop-slots(master menu) /item-slots(shops) — the slot numbers content is placed into. The number of slots is the page size; content paginates automatically when it overflows.
Every icon/button is built with X-Prison Core's item renderer, so it supports material (vanilla or an ItemsAdder namespace:id), custom_model_data, MiniMessage name and lore, and glow: true.
Each file in the shops/ folder defines one shop. The file name (minus .yml) is the shop id unless you set id explicitly. Below is the shipped tokens-shop.yml, trimmed to show every key:
id: tokens
enabled: true
permission: ''
open-command-aliases: [tokenshop]
# How this shop looks in the master /shop menu.
menu-icon:
material: SUNFLOWER
glow: true
name: '<gold><bold>Token Shop'
lore:
- '<gray>Spend your hard-earned <gold>tokens<gray>.'
- '<dark_gray>%items% items'
- ''
- '<yellow>Click to browse »'
gui:
title: '<gold><bold>TOKEN SHOP'
rows: 6
filler: BLACK_STAINED_GLASS_PANE
item-slots: [10, 11, 12, 13, 14, 15, 16,
19, 20, 21, 22, 23, 24, 25]
decorations:
top:
material: ORANGE_STAINED_GLASS_PANE
name: ' '
slots: [0, 1, 2, 3, 4, 5, 6, 7, 8]
buttons:
back:
slot: 45
material: ARROW
name: '<yellow>« Back to Shops'
close:
slot: 49
material: BARRIER
name: '<red>Close'
prev-page:
slot: 48
material: ARROW
name: '<yellow>« Previous Page'
next-page:
slot: 50
material: ARROW
name: '<yellow>Next Page »'
items:
# Gives items to the player.
diamond_blocks:
display:
material: DIAMOND_BLOCK
name: '<aqua>Diamond Blocks'
lore:
- '<gray>A bundle of <white>8 <gray>diamond blocks.'
- ''
- '<gray>Price: <gold>%price% <gray>%currency%'
- '<gray>Balance: <gold>%balance%'
- ''
- '<green>▸ Left-click <gray>to buy <white>8'
- '<green>▸ Shift-click <gray>to buy <white>%bulk% <gray>(%bulk-price%)'
price: 5000
currency: tokens
bulk-buy-amount: 64
give-items:
blocks:
material: DIAMOND_BLOCK
amount: 8
# Runs a console command (here, an X-Prison feature reward).
autominer_time:
display:
material: CLOCK
glow: true
name: '<aqua><bold>Auto Miner <white>— 30 min'
lore:
- '<gray>Adds <white>30 minutes <gray>of Auto Miner time.'
- ''
- '<gray>Price: <gold>%price% <gray>%currency%'
price: 50000
currency: tokens
bulk-buy-amount: 1
commands:
- 'aam give %player% 30 MINUTES'| Key | Description |
|---|---|
id |
Unique shop id (used by /shop <id>). Defaults to the file name. Duplicate ids are skipped with a warning |
enabled |
false hides the shop from the menu and disables its commands |
permission |
Permission needed to view/open the shop. Empty = everyone |
open-command-aliases |
Extra top-level commands that open this shop directly (e.g. [tokenshop]). Registered at startup |
menu-icon |
The icon shown for this shop in the master menu. Supports %shop%, %id%, %items%
|
gui |
This shop's own menu: title, rows (1–6), filler, item-slots, decorations, buttons
|
items |
Map of purchasable entries (see below) |
| Key | Description |
|---|---|
display |
The GUI icon: material, custom_model_data, name, lore, glow. Supports the item placeholders below |
price |
Cost per unit. 0 = free (the currency step is skipped) |
currency |
Currency this item is priced in. Omit/blank to use the global default-currency
|
bulk-buy-amount |
Quantity bought on a shift-click (default 64) |
permission |
Permission required to buy this item. Empty = anyone |
give-items |
Items handed to the player on purchase (see below). Optional |
commands |
Console commands run on purchase (see below). Optional |
An item can grant items, run commands, or both. A shift-click multiplies everything by the bulk amount: items are granted bulk × amount, the price is price × bulk, and each command is run once per unit purchased.
Each entry under give-items is one stack template:
| Key | Description |
|---|---|
material |
Vanilla material or an ItemsAdder namespace:id (required) |
amount |
Stack size per purchase (default 1) |
custom_model_data |
Optional resource-pack model id |
name / lore
|
Optional MiniMessage overrides. If omitted, the item keeps its vanilla name/lore, so plain blocks and tools look normal in the inventory |
Grants are automatically split into valid max-size stacks. As a safety net, if the inventory somehow fills mid-grant, the overflow is dropped at the player's feet rather than lost.
Console commands run on purchase (so admin-only X-Prison commands work). Supported placeholders:
| Placeholder | Replaced with |
|---|---|
%player% |
The buyer's name |
%amount% |
The quantity purchased (bulk-aware) |
%shop% |
The shop id |
Use commands for anything the server can grant from console — kits, ranks, permissions, crate keys, Auto Miner time, sell multipliers, currency conversions, and so on.
Item display name / lore:
| Placeholder | Value |
|---|---|
%price% |
Unit price, currency-formatted |
%bulk-price% |
Price of one shift-click (price × bulk-buy-amount) |
%bulk% |
The item's bulk-buy amount |
%balance% |
The player's balance of this item's currency |
%currency% |
The currency's display name |
Shop menu-icon: %shop%, %id% (both the shop id) and %items% (item count).
Confirmation menu: %amount%, %price% (total), %unit-price%, %balance%, %currency%.
All player-facing text is in plugins/X-Prison/addons/Shop/shop-messages.yml. Run /shop reload after editing. Both MiniMessage tags and & colour codes are supported, and prefix is prepended to every line.
prefix: '<dark_gray>[<gradient:#f7971e:#ffd200>Shop</gradient><dark_gray>] </dark_gray>'
messages:
# %item% (hover to preview the item) %amount% %price% %currency%
purchase-success: '<green>Purchased <white>%amount%x</white> %item% <green>for <gold>%price% <gray>%currency%<green>.'
# %currency% %price%
insufficient-funds: "<red>You can't afford that — you need <gold>%price% <gray>%currency%<red>."
# %currency%
invalid-currency: '<red>That item uses an unknown currency (<gray>%currency%<red>). Tell an admin.'
inventory-full: '<red>Your inventory is full — make some room and try again.'
no-permission: '<red>You do not have permission to do that.'
purchase-failed: '<red>The purchase could not be completed. Please try again.'
# %shop%
shop-not-found: '<red>No shop named <gray>%shop%<red> exists.'
players-only: '<red>Only players can use this command.'
module-disabled: '<red>The shop is currently disabled.'
reloaded: '<green>Shop configuration reloaded.'| Message | When shown |
|---|---|
purchase-success |
A purchase completed. %item% renders the item's display name as a hoverable item — hovering it shows the item tooltip |
insufficient-funds |
The player can't afford the item |
invalid-currency |
The item's currency isn't registered |
inventory-full |
Not enough room for the granted items (nothing is charged) |
no-permission |
Missing a global/shop/item permission, or /shop reload without admin |
purchase-failed |
The currency transaction failed for any other reason |
shop-not-found |
/shop <id> for a missing or disabled shop |
players-only |
A player-only command run from console |
module-disabled |
/shop while enabled: false
|
reloaded |
/shop reload succeeded |
The Shop addon has no custom Bukkit events, but every purchase debits currency with the named cause SHOP_PURCHASE. Any plugin listening to X-Prison currency events will see that cause on shop transactions (instead of UNKNOWN), so you can attribute spend to the shop for logging, analytics, or reward systems.
To build against the addon, add its JAR as a provided dependency — its classes are available at runtime through X-Prison's classloader.
A new shop file doesn't appear in /shop
- Make sure the file is inside
plugins/X-Prison/addons/Shop/shops/and ends in.yml. - Check the shop has
enabled: true, and that you (and your players) meet itspermission. - Run
/shop reloadand watch the console for[Shop] Loaded N shop(s).A parse error is logged as[Shop] Failed to load shop file '...'. - Two shops with the same
idconflict — the second is skipped with aDuplicate shop idwarning. Give each a uniqueid.
"That item uses an unknown currency"
- The item's
currency(or the globaldefault-currency) must exactly match a currency registered in X-Prison'scurrencies.yml. Check the server log on startup/reload foruses unknown currency '...'warnings.
A new /tokenshop-style alias (or renamed /shop) doesn't work
- Command labels are registered at startup. Add/rename
open-command-aliases,command.name, orcommand.aliases, then restart the server — a reload won't register new commands.
Players say they were "charged for nothing"
- They weren't. If an item grants physical items and the inventory is full, the purchase is refused before any currency is taken. The
inventory-fullmessage is shown and no balance changes.
The purchase sound doesn't play / "Unknown sound" in console
-
sounds.purchase-success/sounds.purchase-failmust be valid BukkitSoundenum names for your server version. Set them tononeto disable.
The confirmation menu never shows
- Set
confirm-purchases: trueinshop.ymland run/shop reload.
The whole addon is disabled on startup
- Look for
[Shop] Currency module is not available.— the Currencies module must be enabled, since the addon prices everything through the currency API.
- Currencies
- Ranks
- Prestiges
- Rebirths
- Mines
- AutoSell
- AutoMiner
- Enchants
- Pickaxe Levels
- Pickaxe Skins
- Gangs
- Multipliers
- Blocks
- Bombs
- History
- Mining Stats
- Nicknames
- Battle Pass
- Quests
- Daily Rewards
- config.yml
- autominer.yml
- autosell.yml
- block-rewards.yml
- enchants.yml
- currencies.yml
- multipliers.yml
- ranks.yml
- prestiges.yml
- pickaxe-levels.yml
- pickaxe-skins.yml
- gangs.yml
- mines.yml
- bombs.yml
- blocks.yml
- mining-stats.yml
- rebirths.yml
- battlepass.yml
- quests.yml
- dailyrewards.yml
- efficiency.json
- fortune.json
- unbreaking.json
- haste.json
- speed.json
- fly.json
- nightvision.json
- jumpboost.json
- autosell.json
- tokenfinder.json
- gemfinder.json
- salary.json
- charity.json
- blessing.json
- gangvaluefinder.json
- prestigefinder.json
