Underground trading system with timed item rotations, per-item cooldowns, stock limits, category filtering, GUI pagination, Redis cross-server synchronisation and support for Vault, PlayerPoints and CoinsEngine economies.
Overview
BlackMarket presents players with a rotating set of items in a chest GUI that resets on a configurable interval. Items can have individual cooldowns, stock limits, one-time purchase restrictions, expiry times and spawn chances. Categories allow players to filter the market. Pagination handles large item pools cleanly.
Data is stored in SQLite by default. MySQL is supported for networked setups. Redis can be enabled for real-time cross-server market synchronisation on BungeeCord or Velocity networks.
Soft Dependencies
- Vault — economy support
- PlayerPoints — points-based economy
- CoinsEngine — coins economy
- PlaceholderAPI — item lore and display name placeholders
- LuckPerms — per-item permission checks
Folia supported. BlackMarket detects Folia automatically and uses threaded schedulers where required.
Installation
- Download BlackMarket from BuiltByBit
- Place the JAR in your
plugins/folder - Start or restart the server — config.yml, items.yml and messages.yml generate automatically
- Edit
plugins/BlackMarket/config.ymlandplugins/BlackMarket/items.yml - Run
/bma reloador restart to apply
Vault must be installed for the default vault economy to work. Install your preferred economy plugin before starting.
Configuration
Market Settings
market:
global-market: true # all players see the same items
reset-interval: 24h # supports s, m, h, d
items-per-reset: 5
send-reset-message: true
GUI
gui:
title: "&8&lBlack Market"
rows: 6
close-on-purchase: false
enable-categories: true
pagination:
enabled: true
title-format: " &8- &7Page %page%/%total%"
Sounds
sounds:
gui-open: BLOCK_CHEST_OPEN
gui-close: BLOCK_CHEST_CLOSE
purchase-success: ENTITY_PLAYER_LEVELUP
purchase-fail: ENTITY_VILLAGER_NO
click: UI_BUTTON_CLICK
page-turn: ITEM_BOOK_PAGE_TURN
Lore Status Lines
Each status type (stock, out-of-stock, cooldown, expiry, etc.) has configurable lore lines that appear dynamically on item stacks in the GUI.
lore:
stock:
enabled: true
lines: ["&7Stock: &e%stock_remaining%&7/&e%stock_max%"]
cooldown:
enabled: true
lines: ["&c&lON COOLDOWN &7— &e%cooldown_time% remaining"]
expires-in:
enabled: true
lines: ["&eExpires in: &f%expire_time%"]
Items
All market items live in plugins/BlackMarket/items.yml. Each item is a named key under items:.
Item Properties
| Key | Description |
|---|---|
| material | Bukkit material name (e.g. DIAMOND_SWORD). |
| display-name | GUI display name. Supports MiniMessage and legacy codes. |
| lore | List of lore lines. |
| price | Purchase price. |
| economy-type | vault, playerpoints, coinsengine or exp. |
| command | Console command on purchase. Use %player%. |
| message | Custom purchase message sent to buyer. |
| category | Category string for the filter button. |
| stock | Max stock. Use -1 for unlimited. |
| one-time | true — item can only be purchased once per player. |
| cooldown | Time between purchases per player (e.g. 1h, 30m). |
| expiry | Time until item expires from the market (e.g. 12h, 1d). |
| permission | Permission node required to purchase. |
| chance | 0 to 100 — probability the item appears in a rotation. |
| sound | Sound played on purchase. |
| effect | Particle effect spawned on purchase. |
| custom-model-data | Resource pack model data integer. |
Example Item
items:
diamond_sword:
material: "DIAMOND_SWORD"
display-name: "&b&lEnchanted Diamond Sword"
lore:
- "&7Price: &e$50,000"
- "&6Chance: &e%item_chance%%"
- "&e&l▶ CLICK TO PURCHASE"
price: 50000
economy-type: "vault"
command: "give %player% diamond_sword 1"
category: "Weapons"
stock: 10
cooldown: "1h"
expiry: "12h"
permission: "blackmarket.buy.diamond_sword"
chance: 100
sound: "ENTITY_PLAYER_LEVELUP"
effect: "VILLAGER_HAPPY"
Commands
Player Commands
Admin Commands
Base: /blackmarketadmin — aliases /bma, /marketadmin
Permissions
| Node | Default | Description |
|---|---|---|
| blackmarket.* | op | All BlackMarket permissions. |
| blackmarket.use | true | Open the market. |
| blackmarket.admin | op | All admin commands. |
| blackmarket.admin.reload | op | Use /bma reload. |
| blackmarket.admin.reset | op | Use /bma reset. |
| blackmarket.admin.open | op | Use /bma open. |
| blackmarket.admin.info | op | Use /bma info. |
| blackmarket.admin.debug | op | Use /bma debug. |
| blackmarket.bypass.cooldown | op | Bypass per-item cooldowns. |
| blackmarket.bypass.stock | op | Buy items even when out of stock. |
| blackmarket.bypass.permission | op | Bypass item permission requirements. |
Economy
The default economy is set globally in config.yml and can be overridden per item in items.yml.
economy:
default: "vault" # vault | playerpoints | coinsengine | exp
Per-item override — set economy-type on any item in items.yml to use a different currency for that item only.
Database
database:
type: "sqlite" # sqlite | mysql
mysql:
host: "localhost"
port: 3306
database: "blackmarket"
username: "root"
password: "password"
use-ssl: false
SQLite stores data locally in plugins/BlackMarket/data.db. No external server is needed. Switch to MySQL for shared data across a network without Redis.
Redis
Enable Redis for real-time market state synchronisation across multiple servers on BungeeCord or Velocity networks. All servers share the same market rotation, stock levels and cooldowns.
redis:
enabled: false
server-id: "server-1" # unique per server in your network
host: "localhost"
port: 6379
password: ""
database: 0
use-ssl: false
pool:
max-total: 8
max-idle: 8
min-idle: 0
Each server must have a unique server-id. Redis pub/sub is used to broadcast market events so all servers react instantly.