Code (YAML):
################################################################################
# Trader Config (for your current TraderManager)
# - Works on 1.21+
# - Requires Vault for money costs/rewards
# - Optional: PlaceholderAPI (PAPI) for %placeholders%
# - Color formatting:
# * Legacy & codes are supported (e.g., &a, &c, &l)
# * A light subset of MiniMessage tags is mapped to legacy automatically:
# <yellow>, <red>, <green>, <gold>, <bold>, <italic>, <underlined>, <strikethrough>, <br>
# - Commands:
# * "console:<cmd>" runs as console
# * "player:<cmd>" runs as the player
# * "%player%" is replaced with the player name
################################################################################
# ───────────────────────────────────────────────────────────────────────────────
# NPC 1 — LEGACY SINGLE-TRADE (no offers GUI)
# This mode uses a single set of requirements + commands/message.
# Set "features.enableOffers: false" (or omit "features") to use legacy mode.
# ───────────────────────────────────────────────────────────────────────────────
npc-1:
display-name
:
"&6Stone Trader &7(%player_name%)"
requireConfirmation
: true
# shows a small confirm GUI before completing
# In legacy mode, ONLY this section + commands/message are used
requirements:
exp
: 10
# player must have at least 10 XP levels
money
: 500
# needs $500 (Vault)
items
:
# items the player must have (will be removed on success)
"1":
material
: STONE
amount
: 1
modelId
: 57
# optional CustomModelData match
fail
:
"<red>You lack 1x special Stone</red>"
# shown if missing
# Run after successful trade
commands
:
-
"console:money give %player% 1000"
-
"player:me just traded 1 stone!"
message
:
"&aTrade complete! You earned &e$1000&a."
# features section present but "enableOffers" is false, so legacy path is used
features:
enableOffers
: false
# ← important: keeps legacy mode
enableStock
: false
# ignored in legacy mode
enablePerPlayerLimits
: false
# ignored in legacy mode
# ───────────────────────────────────────────────────────────────────────────────
# NPC 2 — BASIC OFFERS SHOP (SmartInvs GUI, no stock/limits)
# Turn on offers and define "offers:"; legacy requirements are ignored.
# ───────────────────────────────────────────────────────────────────────────────
npc-2:
display-name
:
"&bFisherman &7| <yellow>Deals</yellow>"
requireConfirmation
: false
features:
enableOffers
: true
enableStock
: false
enablePerPlayerLimits
: false
# Each key under "offers" is a separate buy option (button in the GUI)
offers
:
fish_kit:
title
:
"&eFish Starter Kit"
icon
:
# what the player sees in the GUI
material
: SALMON
amount
: 1
# modelId: 123 # optional CustomModelData for the icon
lore
:
-
"&7A simple kit to start fishing."
-
"<gold>Price shows below</gold>"
-
"&7Hello &f%player_name%&7!"
cost
:
# what the player pays
money
: 250
exp
: 0
items:
- material
: STRING
amount
: 5
gives
:
# what the player receives
items:
- material
: FISHING_ROD
amount
: 1
name
:
"&b&lStarter Rod"
lore
:
-
"&7Light and reliable."
-
"<yellow>Good luck!</yellow>"
unbreakable
: true
enchants:
LURE
: 2
LUCK_OF_THE_SEA
: 2
commands
:
-
"console:bc &a%player% bought a Fish Starter Kit!"
# No stock/limits here because features.disable those
# ───────────────────────────────────────────────────────────────────────────────
# NPC 3 — PREMIUM OFFER WITH STOCK & PER-PLAYER LIMITS
# Shows timed restock and daily purchase limits. Great for limited-time / rare items.
# ───────────────────────────────────────────────────────────────────────────────
npc-3:
display-name
:
"&dPremium Smith &8• <green>Limited Offers</green>"
requireConfirmation
: true
features:
enableOffers
: true
enableStock
: true
# enable timed stock management
enablePerPlayerLimits
: true
# enable per-player purchase caps
offers:
ocean_blade:
title
:
"&b&lOcean Blade"
icon:
material
: DIAMOND_SWORD
lore
:
-
"&7A blade touched by the tide."
-
"<gold>Limited stock — restocks hourly</gold>"
- "&7Your money
:
&a$%vault_eco_balance_formatted%"
cost:
money
: 5000
exp
: 10
items:
- material
: PRISMARINE_CRYSTALS
amount
: 16
gives
:
# Option A — issue ItemsAdder (or any plugin) command(s)
commands
:
-
"console:ia give %player% itemsadder:ocean_blade 1"
# Option B — or give a fully custom ItemStack built by the plugin itself
# items:
# - material: DIAMOND_SWORD
# amount: 1
# name: "&b&lOcean Blade"
# lore:
# - "&7Forged in the deep."
# - "&7(&bLimited Edition&7)"
# modelId: 12345
# unbreakable: true
# enchants:
# SHARPNESS: 5
# LOOT_BONUS_MOBS: 3
# # Attributes can be simple numbers OR detailed objects (both supported):
# attributes:
# GENERIC_ATTACK_DAMAGE: 6.0
# generic.attack_speed:
# amount: -2.2
# operation: ADD_NUMBER # ADD_NUMBER | ADD_SCALAR | MULTIPLY_SCALAR_1
# slotGroup: MAINHAND # ANY|HAND|MAINHAND|OFFHAND|ARMOR|HEAD|CHEST|LEGS|FEET
# # PersistentDataContainer (namespace:key → string value)
# pdc:
# "yourplugin:ocean_blade": "1"
# STOCK SETTINGS (persisted in trader_runtime.yml)
stock:
max
: 10
# hard cap
initial
: 5
# first load value (if runtime empty)
restock:
amount
: 2
# add this much per tick
interval_seconds
: 3600
# every 1 hour
# PER-PLAYER LIMITS
perPlayer:
limit
: 1
# each player can buy once...
reset_seconds
: 86400
# ...then resets after 24h
tide_token:
title
:
"&3Tide Token"
icon:
material
: PRISMARINE_CRYSTALS
amount
: 1
lore
:
-
"&7Trade these with rare vendors."
-
"<yellow>Always in stock.</yellow>"
cost:
money
: 250
gives:
money
: 0
items:
- material
: PRISMARINE_CRYSTALS
amount
: 1
name
:
"&3Tide Token"
lore
:
-
"&7A coin minted under the waves."
# simple attribute example
attributes:
GENERIC_LUCK
: 1.0
# ───────────────────────────────────────────────────────────────────────────────
# NPC 4 — FULLY CUSTOM ITEM (no external commands)
# Demonstrates attributes, slotGroup, enchants, PDC, modelId, etc.
# ───────────────────────────────────────────────────────────────────────────────
npc-4:
display-name
:
"&aArtifact Curator"
requireConfirmation
: true
features:
enableOffers
: true
enableStock
: false
enablePerPlayerLimits
: false
offers:
relic_bundle:
title
:
"&aRelic Bundle"
icon:
material
: CHEST
lore
:
-
"&7A bundle of mysterious relics."
-
"<gold>One per click</gold>"
cost:
items:
- material
: EMERALD
amount
: 8
gives:
items:
- material
: TOTEM_OF_UNDYING
amount
: 1
name
:
"&e&lGlimmering Totem"
lore
:
-
"&7It hums with quiet power."
-
"<green>Handle with care.</green>"
modelId
: 9001
enchants:
VANISHING_CURSE
: 1
# slotGroup here acts as default for attribute entries that don't set their own
slotGroup
: OFFHAND
attributes
:
# "simple" style (number only → amount + ADD_NUMBER)
GENERIC_ARMOR
: 2.0
# "object" style (full control)
generic.armor_toughness:
amount
: 1.0
operation
: ADD_NUMBER
slotGroup
: OFFHAND
pdc:
"myplugin:relic"
:
"glimmer_totem"
"myplugin:tier"
:
"artifact"
# ───────────────────────────────────────────────────────────────────────────────
# NOTES
# • "display-name" and any "lore"/"title" strings support:
# - PlaceholderAPI, e.g. %player_name%, %vault_eco_balance_formatted%
# - Legacy color codes (&a, &c, &l…)
# - Light MiniMessage tags: <yellow>, <red>, <green>, <gold>, <bold>, <italic>, <underlined>, <strikethrough>, <br>
#
# • OFFERS vs LEGACY:
# - Set features.enableOffers: true → Offers GUI is used and "offers:" is required.
# - Set features.enableOffers: false (or omit "features") → Legacy single-trade path uses:
# requirements:, commands:, message:
#
# • COST ITEMS format (both legacy + offers):
# - items:
# - material: STONE
# amount: 3
# modelId: 57 # optional CustomModelData match
#
# • REWARD ITEMS format (offers → gives.items):
# - material: <MATERIAL>
# - amount: <int>
# - name: "<colored display name>"
# - lore: ["line1", "line2", ...]
# - modelId: <int> # resource-pack CustomModelData
# - unbreakable: true|false
# - enchants: { SHARPNESS: 5, LUCK_OF_THE_SEA: 2 } # namespaced/enchant names supported
# - attributes:
# # You can mix styles:
# GENERIC_ATTACK_DAMAGE: 5.0
# generic.attack_speed:
# amount: -2.0
# operation: ADD_NUMBER # ADD_NUMBER | ADD_SCALAR | MULTIPLY_SCALAR_1
# slotGroup: MAINHAND # ANY|HAND|MAINHAND|OFFHAND|ARMOR|HEAD|CHEST|LEGS|FEET
# - pdc:
# "namespace:key": "stringValue" # stored in PersistentDataContainer
#
# • STOCK (offers only; requires features.enableStock: true):
# stock:
# max: <int> # total cap
# initial: <int> # first value if runtime empty
# restock:
# amount: <int> # how many to add per tick
# interval_seconds: <int> # one restock tick every N seconds
#
# • PER-PLAYER LIMITS (offers only; requires features.enablePerPlayerLimits: true):
# perPlayer:
# limit: <int> # max purchases in the window
# reset_seconds: <int> # window length in seconds (e.g., 86400 = 24h)
#
# • RUNTIME:
# Current stock & per-player counters are saved in "trader_runtime.yml".
################################################################################