ProVouchers

Core Concepts

Vouchers vs codes, where everything is configured, and how a redemption flows.

A quick mental model so the rest of the documentation clicks into place.

Vouchers and codes

ProVouchers has two delivery methods that share everything else:

VoucherCode
What it isA physical item players holdA word players type
How it is redeemedRight-click the item/voucher redeem <code>
Defined invouchers/<id>.ymlcodes/<id>.yml
Use limitPer item (each item redeems once)Per player and/or global counter
Rewards, conditions, effectsSame systemSame system

If you understand one, you understand the other. The fields that differ are listed on the Voucher Reference and Code Reference pages; everything shared (rewards, conditions, text) has its own page and applies to both.

Where everything lives

plugins/ProVouchers/
├── config.yml          # storage backend, anti-dupe, metrics  (see Config Reference)
├── data.db             # created only when the storage backend is sqlite
├── vouchers/           # one voucher per .yml file
│   ├── crate_key.yml
│   └── rank_token.yml
└── codes/              # one code per .yml file
    └── launch_gift.yml
  • Server-wide settings (which database, anti-dupe behaviour, metrics) live in config.yml.
  • Each voucher and code is its own file. The file name without .yml is the default id/code, but you can override it with the id: or code: key inside the file.
  • After editing any file, run /voucher reload. There is no need to restart.

Anatomy of a voucher file

id: crate_key                 # identity (defaults to the file name)
display-name: "<gold>Key"     # how the item is named (MiniMessage)
item: { material: TRIPWIRE_HOOK, glow: true }   # what the item looks like
lore: [ "<gray>Right-click" ] # item description lines (MiniMessage)
cooldown: 0                   # per-player seconds between redeems
expiry: ""                    # when the item stops working
conditions: [ ... ]           # who may redeem it, and where  (see Conditions)
rewards: [ ... ]              # what they get                 (see Rewards)
random-rewards: [ ... ]       # weighted "pick one" rewards

Only item is strictly required (and even then material defaults to PAPER). Everything else has a sensible default.

How a redemption flows

When a player right-clicks a voucher (or runs /voucher redeem), ProVouchers runs these steps in order and stops at the first failure:

  1. Is it a real voucher/code? Unknown or removed ids are rejected.
  2. Is it redeemable? unredeemable: true vouchers are display-only.
  3. Owner check (vouchers only): owner-only vouchers reject other players.
  4. Expiry check: expired vouchers and codes are rejected.
  5. Game mode gate: creative and spectator are blocked by default.
  6. Cooldown check: per-player, per-voucher. Right after a player joins, a voucher with a cooldown waits until their stored cooldowns have loaded.
  7. Conditions: every condition must pass; the first failure shows its message.
  8. Anti-dupe / use limits (checked off the main thread): a duplicate voucher item or an exhausted limit is rejected. A use is reserved in the database here, so players redeeming at the same moment cannot exceed a limit.
  9. Rewards run: the voucher item is taken from the inventory, then always-run rewards plus one weighted random set run, each reward executed independently.

Steps 1 to 7 are instant and on the player's thread. Step 8 touches the database, so it runs asynchronously, then control returns to the player to grant rewards. This keeps the server (and Folia regions) responsive. If the player logs out, or moves the voucher out of their inventory, before the rewards run, nothing is used up: the reserved use is given back and the voucher still works. While a redeem is in progress, further clicks on the same voucher are ignored.

One self-contained plugin

Everything ProVouchers needs (scheduling, storage, text rendering, conditions, integrations, metrics) ships inside the plugin. Practically, this means:

  • Conditions (permission, region, economy, and so on) share one consistent config shape (see Conditions).
  • Integrations (economy, permissions, custom items, placeholders) are detected automatically, so installing a supported plugin "just works" without ProVouchers-specific setup (see Integrations).
  • Text is rendered with MiniMessage and PlaceholderAPI in one place (see Text and Placeholders).

That is the whole model. The rest of the docs are reference pages for each piece.

On this page