6 releases, newest first.
item-model: now shows on the /voucher open icon. v2.3.0 added the key to the voucher-file schema and applied it to the physical voucher, but the two admin menus rebuild their icons from the voucher template of guis/*.yml rather than from the voucher item, so a voucher with an item-model: was listed as its bare material while the item in hand wore the resource-pack model.guis/categories.yml and guis/vouchers.yml) now forward the voucher's own key through item-model: "{item-model}". The line merges into an existing install on the next boot, keeping your edits - no file to delete.item-model: is unaffected: the placeholder resolves to nothing and an empty key is skipped silently.custom-model-data has the same behaviour in the menus and is NOT fixed here: menu files read that key as an integer with no placeholder pass, so it cannot be forwarded as text. Closing it needs a SnLib dependency bump (the per-entry stack override added in SnLib 1.21.0); this plugin is pinned at 1.20.3.
Vouchers can now speak for themselves. Three new optional keys in a voucher file, none of them mandatory - every existing voucher behaves exactly as before.
message: at the top level of the file - sent on any successful claim of that voucher.message: on an individual reward entry - sent only when that command actually runs, so a WEIGHTED/RANDOM crate can name the prize the player actually drew.deny-message: on a reward entry - sent when that entry's condition: did not pass.All three support & and &#RRGGBB colours, the five placeholders {voucher} {category} {amount} {count} {player}, and PlaceholderAPI. A blank value turns one off, exactly like a lang key.
deny-message firesOnly when the claim hands out nothing - when every reward on the voucher failed its condition. A claim that ran at least one command is a success and reports itself as one, so a player who got their reward is never also told about the tiers they did not qualify for.
When at least one failing entry has a deny-message, those messages replace the generic claim.no-eligible-reward line rather than printing under it. Entries without one stay silent, so you choose exactly which requirement is worth explaining. The voucher is not consumed either way, as before.
A multi-claim crate draws many times in one click, so identical reward messages collapse into a single line with a count instead of flooding chat:
You got a diamond! x87
A netherite ingot! Lucky. x3The x87 wrapper is the new claim.reward-grouped key in lang/messages_en.yml, so it can be restyled or translated. A prize drawn exactly once is sent with no suffix.
Giving a reward its own message: also stops that voucher from being swept up by a bulk.aggregate-by-category click on a sibling. Two vouchers that announce themselves differently are two different rewards from the player's seat, and consolidating them would report the wrong text. This only ever makes a click consume less, never more.
lang/messages_en.yml gains claim.reward-grouped automatically on boot, with your own values and comments preserved. Your voucher files are untouched.
vouchers/example.yml documents all three keys, but the vouchers/ folder is seed-only: an existing install keeps the example it already has and will not receive the new documentation. It is on the GitBook and in this release instead.
item-model: key in the item: block: the 1.21.2+ minecraft:item_model component, for resource packs that address items by model key instead of through custom-model-data.custom-model-data - a voucher may carry both, and neither overwrites the other.namespace:path. A key with no namespace means minecraft:, which is almost never what a pack wants.vouchers/example.ymlThe example file documents the new key, but the vouchers/ folder is seed-only: an existing install keeps the example.yml it already has and will NOT receive the new documentation. Only fresh installs get it. Your own voucher files are untouched either way, and the new key works regardless.
It ships commented out on purpose - an item_model key that no installed resource pack defines renders as the missing-model block, so a copied example would look broken.
amount: (crates)A voucher carrying an amount: bulk-claims by consolidating a whole stack into one command execution with the summed {amount}. That works because amount is a multiplier. A crate has nothing to multiply - pets admin givebox {player} Box_Basica 1 is not worth 64 times more written once - and a RANDOM crate has to draw a separate prize per copy. So crates could not bulk-claim at all, and a player holding 200 of them had to right-click 200 times.
The new voucher key fixes that:
multi-claim: trueOne main-hand right-click now consumes the whole stack and rolls the rewards once per voucher consumed. 200 crates, 200 independent draws, one click. Shift is not required. A voucher with neither key still consumes exactly one, as before.
bulk:
multi-limit: 128 # cap per click, 0 = unlimited
commands-per-tick: 20 # dispatch budget per claim per tick, 0 = no spreadingbulk.multi-limit caps how many vouchers one click consumes on a multi-claim voucher - the number of executions one click queues. It bounds /voucher give and /voucher giveall on an auto-claim crate too.bulk.commands-per-tick spreads a claim's overflow over the following ticks, so 128 crate rewards never land in a single tick. The budget is per claim, not server-wide, so one player mass-claiming never delays anybody else's. Anything still queued at shutdown is dispatched rather than dropped - those vouchers were already consumed.bulk.aggregate-by-category applies to the new shape and never crosses the two: an amount click only sweeps up amount siblings, a multi-claim click only multi-claim siblings.{amount} inside each dispatched command is 1 - each execution is worth one voucher. The {amount} the player is shown is the number consumed.amount: and multi-claim: on one file is contradictory: amount wins and the loader warns naming the voucher.messages.claim.multi and messages.claim.multi-category, merged in on boot.No config migration. Existing vouchers behave exactly as they did.
/voucher giveall <voucher> [amount] [-s]Hands a voucher to every online player in one command. Same grammar as /voucher give minus the target: the trailing [amount] [-s] pair is read in either order, and amount is the amount per player, never a pool split between them. An auto-claim voucher dispatches its rewards to everyone instead of minting items.
The pass never aborts part way. A player who cannot be served is counted and skipped, and the sender gets a summary at the end naming how many received and how many were skipped. -s suppresses every line, sender and receivers alike.
New permission snsimplevouchers.admin.giveall (default op, child of snsimplevouchers.admin).
give.drop-overflowControls what happens when the voucher items do not fit in the receiver's inventory.
give:
drop-overflow: truetrue (default, and what every give did before this version): the receiver keeps what fits and the rest drops at their feet, so nothing is ever lost.false: all-or-nothing. A receiver without room for the whole stack gets nothing, and the giver is told they were skipped. A partial delivery never happens, so a giver is never told they handed over 10 vouchers that turned into 4.The key applies to all three ways a voucher item reaches a player: /voucher give, the new /voucher giveall, and the give-on-click of /voucher open. Auto-claim vouchers are unaffected, since they dispatch rewards and never produce an item that could overflow.
messages.inventory-full, messages.give.inventory-full and the four messages.giveall.* lines merge into your language file on boot; your existing values and comments are untouched.
SnSimpleVouchers v2.0.0 - lightweight click-to-claim voucher items for Paper, defined one per YAML file.
Each voucher is its own file under plugins/SnSimpleVouchers/vouchers/, optionally grouped in one level of subfolders. A player right-clicks the item and its rewards are dispatched.
list runs every reward, weighted picks one by weight, random picks one uniformly.amount: consolidates a whole stack into ONE command execution on a single right-click: 64 vouchers are one eco give, not 64. Shift is not required. bulk.aggregate-by-category extends that to other ids in the same category folder that declare the identical reward list, summing their amounts into one dispatch.commands: can carry a condition: expression (e.g. "%player_level% >= 10 && %player_level% < 21"), resolved through PlaceholderAPI at claim time, so one voucher hands out a different reward to different players.auto-claim: true skips the physical item entirely and dispatches the rewards straight to the target player./voucher open browses categories and vouchers and hands them out on click, gated on snsimplevouchers.admin.give.basehead-<base64>./voucher requires snsimplevouchers.admin. Its aliases are /vouchers and /sv, configurable under command.aliases in config.yml.
| Command | Description |
|---|---|
/voucher help | Show the help menu |
/voucher reload | Reload config, language, menus and rescan voucher files |
/voucher debug | Toggle debug logging |
/voucher open | Open the paginated admin GUI |
/voucher give <player> <voucherId> [amount] [-s] | Give a voucher. [amount] and -s may be given in either order; -s suppresses the messages. |
snsimplevouchers.admin is the parent of every node below, so granting it alone gives full access. The root node is required, not just inherited.
| Permission | Default | Description |
|---|---|---|
snsimplevouchers.admin | OP | Full administrative access |
snsimplevouchers.admin.give | OP | /voucher give and the give-on-click button |
snsimplevouchers.admin.open | OP | /voucher open |
snsimplevouchers.admin.reload | OP | /voucher reload |
snsimplevouchers.admin.debug | OP | /voucher debug |
snsimplevouchers.admin.update | OP | Receives update notifications |
There is no player-facing node: claiming a voucher only requires holding one.
Everything under plugins/SnSimpleVouchers/ is yours: config.yml, lang/messages_en.yml, guis/categories.yml, guis/vouchers.yml and vouchers/*.yml. New keys are merged in on boot without touching your edits or your comments, so an update never resets a file. See vouchers/example.yml for every available field.
Java 21+, Paper 1.20.x or 1.21.x, SnLib, a valid Sn licence key in plugins/.Sn-License/license.yml, and outbound internet access from the server for the one-time startup licence check. PlaceholderAPI is optional and only needed for condition:.
Install SnLib first. This release declares depend: [SnLib], so a server without SnLib.jar in plugins/ refuses to load the plugin at all and logs Unknown dependency SnLib. Run a current SnLib: an older one already installed for another Sn plugin can sit below the API level this release needs.