PeaShops
A sign-based chest shop plugin for Paper 1.21
Bulk pricing tiers, sale windows, granular trust, opt-in dynamic pricing.
What it is
PeaShops is a chestshop plugin for servers that want clean signs, not menu after menu, on every trade. Stick a sign on
a chest, type [BUY] / [SELL] / [ADMIN], and you've got a shop. There's a GUI fallback for
sign-allergic players, but signs are the canonical interface.
It was built around a few things stock chestshop plugins don't do well — bulk volume tiers on a single shop, timed
sales, per-player permissions per shop, and an opt-in dynamic pricing curve. All of that on top of a transaction path
that's been hammered against the usual dupe vectors before launch.
Showcase video
▶ Watch the walkthrough on YouTube
Quick run-through of the main features in one video
Features in action
Short loops of the main flows — click to view
Creating a shop
→ open GIF in new tab
Purchasing + the info GUI
→ open GIF in new tab
/shop find — distance-sorted search
→ open GIF in new tab
Buying with a sale active
→ open GIF in new tab
Buying with dynamic pricing on
→ open GIF in new tab
Features
- Sign-based shops — [BUY], [SELL], [ADMIN] on any sign attached
to a chest. Type the lines yourself or use the GUI flow. - Bulk pricing tiers — /shop tier <minQty> <pricePerUnit>. One shop can charge
1@$10, 16@$8, 64@$6, without you running three shops to do it. - Timed sale mode — /shop sale <hours> <%off> flags a discount window. The shop
tells buyers they're in a sale; price reverts when the timer ends. - Granular trust — per-player, per-shop. Let someone restock without letting them
change prices, or vice versa. Perms: edit, restock, withdraw, delete, view_analytics. - Opt-in dynamic pricing — off by default, owners enable per-shop. Curve is bounded by
config floor / ceiling so it can't run away. - Admin shops — infinite stock, infinite money, with a per-transaction payout cap so a
faulty config can't drain a server economy. - /shop find <item> — distance-sorted search across every shop on the server. Top
results in a paginated GUI, optional click-to-teleport (perm-gated). - /shop info — shift+right-click any shop sign for a panel showing item, stock,
per-unit price, sale alert with savings + countdown, and the owner's description. - Custom shop description — owners can set a chat-prompted description that shows in
the info GUI. - Hopper guard — hoppers and hopper-minecarts are blocked from moving items in or out
of a shop chest while a transaction lock is held. Restock works fine outside the lock window. - Vault economy — works with EssentialsX Economy, CMI, and any Vault-compatible
provider. Auto-creates accounts that providers leave behind. - Admin commands — /shopadmin reload | stats | list | remove.
Anti-dupe trade path
Why it doesn't dupe under stress
Every trade goes through a per-shop reentrant lock, an inventory + balance snapshot, and a price-drift check before it
commits. If anything fails — vault provider lying about success, inventory full, stock pulled out from under the
click — state restores cleanly.
The path was hammered against the classic dupe vectors before launch:
- Rapid double-click on the same sign
- Shift-click bypass attempts
- Hopper restock racing the trade lock
- Hopper-minecart pickup under the chest
- Player death mid-click
- Vault provider returning success without actually moving funds
- /reload mid-trade
- Adjacent-hopper grief (anyone placing a hopper next to your shop to dump junk in)
- Sign-only break (breaking the sign without breaking the chest)
- Bundle-vs-per-unit price math (a "32 for $5" sign was, in an early build, charging per-unit — fixed and verified)
Player commands
- /shop — Help / overview (aliases: /peashop, /ps)
- /shop info — Open info GUI for the shop you're looking at (also: shift+right-click a shop sign)
- /shop find <item> — Distance-sorted search for shops selling/buying an item
- /shop sale <hours> <%off> — Start a timed sale on your shop
- /shop sale clear — End the sale early
- /shop tier <minQty> <ppu> — Add a bulk-pricing tier
- /shop tier clear — Remove all tiers
- /shop trust <player> <perm> — Trust a player on this shop with a specific perm
- /shop untrust <player> — Revoke all trust for a player on this shop
- /shop trustlist — List trusted players on this shop
- /shop dynamic on|off — Toggle dynamic pricing for this shop
Admin commands
- /shopadmin reload — Reload config + messages (alias: /psa)
- /shopadmin stats — Shop count, search index size, locks, in-flight trades
- /shopadmin list [page] — Paginated dump of all shops (id / owner / coords / item)
- /shopadmin remove <prefix> — Force-remove a shop by id or unique uuid prefix
Permissions
- peashops.use — buy/sell at shops (default: true)
- peashops.create — create new shop signs (default: true)
- peashops.find — use /shop find (default: true)
- peashops.find.tp — teleport from /shop find GUI (default: op)
- peashops.admin — admin shops + admin commands (default: op)
- peashops.bypass — bypass shop perms / land trust (default: op)
Requirements
- Paper 1.21+ (or compatible fork — Pufferfish, Purpur, etc.)
- Java 21
- Vault + any Vault-compatible economy (EssentialsX Economy, CMI, etc.)
Known issues / monitoring
- A few testers reported visual glitching when walking past a chest shop on high-latency servers — investigating,
suspect a sign-prediction / chest-anim desync. Open an issue if you see it. - Linked shop networks (one stock pool across multiple signs) — not in 1.0, planned.
- Hopper auto-restock (push/pull outside trades is fine; an opt-in mode for owner-controlled auto-restock is planned).
- Persistent journal-based crash recovery — planned.
All coming in a future update
Support & community
Join Pea Studios on Discord
Bug reports, feature requests, server showcase, and the rest of our plugins
PeaShops 1.0 — by Pea Studios
