Hey everyone! This release is a big rework of the trader system: cleaner config, safer API usage on 1.21+, stock & limits built-in, and a shiny paginated GUI. Here’s what changed
✨ Highlights
- New Offers GUI (SmartInvs) with 6×9 layout, pagination, and Prev/Next buttons.
- Per-trader feature flags: enable or disable Offers, Stock, and Per-Player Limits per NPC.
- Stock & Restock system with automatic timers and persistent runtime file.
- Per-player purchase limits with timed resets.
- Safer 1.21+ attribute handling (uses the new AttributeModifier.Builder when available; falls back safely on older APIs).
- MiniMessage-style & & color formatting everywhere (titles, lore, messages). Optional PlaceholderAPI in player-facing text.
- Item builder overhaul: model data, enchants, attributes, PDC tags, unbreakable, lore etc.
- Vault economy support for costs/rewards, with graceful fallback if Vault isn’t present.
- Optional confirmation GUI before purchases.
- Legacy “single trade” path still supported if you don’t want per-offer GUI.
How players use it (examples)
- Click an NPC → see a scrollable offers menu with item previews, costs, stock, and limits.
- If enabled, they’ll get a confirmation screen before buying.
- Offers can charge money, XP levels, and items, and can give items, money, and run commands.
- Titles/lore support <green>, <bold>, <br> and classic &a, &l codes; PlaceholderAPI placeholders expand for the viewer.
️ New/Updated Config (trader.yml)
Top-level per-NPC
Code (YAML):
npc-1:
display-name
:
"<gold><bold>Traveling Trader</bold></gold>"
requireConfirmation
: true
# show confirm GUI for any purchase (legacy & GUI)
message
:
"<green>Trade complete!</green>"
features:
enableOffers
: true
# use the GUI with per-offer config
enableStock
: true
# track stock per offer
enablePerPlayerLimits
: true
# per-player limits
# Legacy single-trade path is still supported if enableOffers=false:
requirements:
exp
: 5
money
: 250.0
items:
key1:
material
: DIAMOND
amount
: 2
modelId
: 123
fail
:
"<red>You need 2 custom diamonds!</red>"
commands:
- "console
: give
%player% bread 1"
GUI offers
Code (YAML):
npc-1:
offers:
speed_boots:
title
:
"<yellow>Speedy Boots</yellow>"
icon:
material
: LEATHER_BOOTS
amount
: 1
modelId
: 10
lore
:
-
"<gray>Zoom zoom.</gray>"
-
"<white>+Movement Speed</white>"
# What it costs to buy
cost:
money
: 500.0
exp
: 3
items:
- { material
: FEATHER, amount
: 8
}
# What the player receives
gives:
items:
- material
: LEATHER_BOOTS
amount
: 1
name
:
"<aqua><bold>Speedy Boots</bold></aqua>"
lore
:
-
"<gray>Run like the wind.</gray>"
modelId
: 10
unbreakable
: true
enchants:
minecraft:depth_strider
: 3
protection_fall
: 2
# accepts namespaced or simple keys
# attributes support amount/operation/slotGroup
attributes:
generic.movement_speed:
amount
: 0.05
operation
: ADD_SCALAR
# ADD_NUMBER | ADD_SCALAR | MULTIPLY_SCALAR_1
slotGroup
: FEET
# ANY/HAND/MAINHAND/OFFHAND/ARMOR/HEAD/CHEST/LEGS/FEET
pdc:
myplugin:rarity
:
"rare"
# arbitrary metadata on the item
money
: 0.0
commands:
- "console
: playsound entity.player.levelup master
%player%"
# Stock system (only used if features.enableStock=true)
stock:
max
: 20
initial
: 10
restock:
amount
: 2
interval_seconds
: 900
# every 15 minutes
# Per-player limits (only used if features.enablePerPlayerLimits=true)
perPlayer:
limit
: 2
reset_seconds
: 86400
# resets daily
⚙️ Runtime persistence
The plugin writes trader_runtime.yml with current stock, last restock timestamps, and per-player counters.
- You can delete it to reset all stock & limits (server will recreate it).
Compatibility & Safety
- Minecraft/Spigot 1.21+: Uses AttributeModifier.Builder when available.
- Older APIs: Safe reflective fallback to the old constructor (still works, even if deprecated).
- Attributes & Enchants via Registry to avoid deprecated lookups.
- Flexible namespaced keys: minecraft:generic.attack_damage, generic.attack_damage, or GENERIC_ATTACK_DAMAGE all work.
Admin Checklist (after updating)
- Back up your current trader.yml and trader_runtime.yml.
- Update trader.yml to the new structure (see examples above).
- If you had hardcoded NPC names/holograms: ensure you use the plugin’s formatted name so <green> etc. don’t show literally.
- Verify Vault is installed if you use money costs/rewards.
- Test an offer with stock and per-player limit enabled.
- Optional: delete trader_runtime.yml to start with fresh stock/limits.
Fixes & Improvements
- Fixed titles showing literal <green> by consistently converting MiniMessage-style tags and & codes in both static and per-player contexts.
- Replaced deprecated attribute APIs where possible; added compatibility fallback for older servers.
- More robust parsing for EquipmentSlotGroup values (ANY, HAND, MAINHAND, OFFHAND, ARMOR, HEAD, CHEST, LEGS, FEET).
- Cleaner error handling & optional debug logs.
Thanks
Thanks for all the feedback and reports—this update was shaped by your suggestions. If you hit any issues, send your trader.yml and a short repro; I’ll jump on it!