Skip to content

Economy

The economy module is the money backbone of the server: balances, /pay, the /baltop leaderboard, and an admin surface for adjusting it โ€” plus optional banking, loans, banknotes, an item marketplace, and currency exchange. It is a multi-currency economy modelled the DDD way: a player owns a Wallet aggregate that holds one balance per Currency, and one currency ships as the default.

The single most important fact about it:

Balances are DB-backed โ€” never PDC

Every balance lives in the database, never in a player's PDC (persistent-data container). This is a hard invariant. It means balances survive world rollbacks, /reload, crashes, and restarts โ€” a rolled-back world never rolls back anyone's money. It also means the economy needs no external service on the default SQLite backend, and the double-spend guard (an atomic guarded UPDATE at the DB) holds even across a cluster.


Currencies & the Wallet

Out of the box a single default currency ships (coins). The currencies.conf file defines additional currencies (the shipped template covers coins, gems, tokens), each with its own:

  • symbol, plural, format, precision โ€” how amounts render.
  • starting, min-balance, max-balance, min-pay โ€” the numeric rules.
  • icon-material โ€” its icon in GUIs.
  • transfer, exchange, leaderboard flags โ€” whether it can be paid, converted, and ranked.
  • permission-required โ€” when true, holding a currency needs uxmessentials.economy.currency.<id>.
  • physical / denominations { โ€ฆ } โ€” whether it can be withdrawn as a banknote, and in what denominations.

A player's /wallet shows every currency they hold; most base commands take an optional [currency] argument and fall back to the default when it's omitted.


Everyday Money: Balance, Pay, Baltop

These are the always-on core commands (they cannot be feature-flagged off):

Command Description Permission
/balance [player] [currency] Show own / another's balance .economy.balance / .balance.others
/pay <player> <amount> [currency] Transfer funds uxmessentials.economy.pay
/payall <amount> [currency] Pay every online player uxmessentials.economy.payall
/paytoggle Refuse incoming /pay uxmessentials.economy.pay.toggle
/baltop [currency] [page] View the top balances uxmessentials.economy.baltop

Large payments can require a confirmation step. The pay config block sets min-pay, a confirm-threshold (amounts above it prompt for /payconfirm), a confirm-timeout-ms, an optional tax, and the toggle-default. Holders of uxmessentials.economy.pay.confirm.bypass skip the confirmation.

/baltop is served from a cached snapshot (its query is bounded and runs off-thread) so it never lags the server. baltop config controls page-size, cache-ttl-ms, snapshot-capacity, exclude-banned, min-balance, and an exempt-permission โ€” players holding uxmessentials.economy.baltop.exempt stay off the leaderboard.


The /eco Admin Surface

/eco (alias economy) is the staff toolbox โ€” bare, it opens an admin GUI hub (uxmessentials.economy.admin). Its subcommands each carry their own node:

Command Purpose Permission
/eco give ยท /eco give-random <player> <amtโ€ฆ> Give (fixed or random range) .economy.admin.give
/eco take <player> <amt> Take money .economy.admin.take
/eco set ยท /eco reset <player> [amt] Set / reset a balance .economy.admin.set
/eco giveall ยท giverandom ยท resetall โ€ฆ Bulk server-wide mutations .economy.admin.bulk
/eco history [player] ยท /eco logs Transaction history / global log GUI .economy.admin.history / .admin.logs
/eco note give <player> <amt> Mint an admin banknote (no debit) .economy.admin.note
/eco backup ยท export ยท restore <player> <date> Snapshot / CSV export / restore .economy.admin.backup / .admin.restore

Every mutation is written to the DB-backed ledger, which is what /eco history and /eco logs read back.


Feature-Flagged Extras

The base commands above are always on. The following are gated by feature flags in economy.conf โ€” they only register and respond when their block is enabled:

Feature Commands Config block
Banks /bank [create\|deposit\|withdraw\|addmember\|removemember โ€ฆ] bank { enabled, interest { tiers } }
Loans / credit /loan [status\|take\|pay โ€ฆ] loans { enabled, limit-multiplier, interest-*, installment-cycle-hours, score-* }
Banknotes /withdraw <amount> ยท /deposit banknotes { โ€ฆ }
Marketplace /worth [item] ยท /setworth โ€ฆ ยท /sell [amount] ยท /sellall worth { enabled, items[] }
Exchange /exchange [<amount> <src> <dst>] exchange { enabled, rates[] }
Wallet dashboard /wallet [currency] wallet { gui-enabled }
  • Banks are shared accounts with members and optional tiered interest.
  • Loans lend against a credit score, repaid on an installment cycle.
  • Banknotes turn virtual money into a physical item (/withdraw) and back (/deposit) โ€” the currency must be marked physical with denominations. Admins can mint notes with /eco note give without debiting anyone.
  • Worth/sell gives items a sell value (worth.items[]) so /sell and /sellall turn inventory into cash.
  • Exchange converts between currencies at configured rates[].

Turning a feature off makes it disappear

If a block is disabled, its commands aren't registered at all โ€” a disabled module wires nothing. Disabling the whole economy module makes paid features elsewhere (home costs, warp costs, vault costs) become free rather than erroring.


Key Settings (module config)

modules/economy/config.conf plus its sibling currencies.conf. The headline keys:

Key What it does
amount-format full or compact (e.g. 1.2k) number rendering.
wallet { default-currency, starting-balance, min-balance, max-balance, gui-enabled } The default currency and wallet limits.
pay { min-pay, confirm-threshold, confirm-timeout-ms, toggle-default, tax { } } Payment rules.
baltop { page-size, cache-ttl-ms, snapshot-capacity, exempt-permission, exclude-banned, min-balance } Leaderboard behaviour.
bank, loans, banknotes, worth, exchange, salary The feature-flag blocks above (salary ships disabled).
command-costs[] Per-command charges.
provider { register, priority } How uxmEssentials registers itself as the economy provider (below).

Provider Registration (Vault / Treasury)

Other plugins (shops, jobs, quests) find an economy through Bukkit's ServicesManager. uxmEssentials plays this both ways with a register-or-defer strategy:

  1. On enable it looks for an existing foreign economy provider โ€” Treasury first, then Vault.
  2. If one is found, uxmEssentials consumes it (foreign economy is authoritative) and defers.
  3. If none is found, uxmEssentials registers its own native DB-backed ledger at ServicePriority.Normal, so every Vault/Treasury-aware plugin uses uxmEssentials as the economy.

The provider { register, priority } block controls whether and at what priority it registers. Vault and non-default currencies don't mix โ€” a Vault call for a non-default currency is rejected with CURRENCY_UNSUPPORTED (Vault has no concept of multiple currencies).

See Vault & Treasury for the full integration story.


Permissions at a Glance

Node Purpose Default
uxmessentials.economy.balance / .balance.others Own / others' balance true / โ€”
uxmessentials.economy.pay / .payall / .pay.toggle Transfer funds โ€”
uxmessentials.economy.baltop View the leaderboard โ€”
uxmessentials.economy.admin (+ .give / .take / .set / .bulk / .history / .logs / .note / .backup / .restore) Admin operations op
uxmessentials.economy.bank / .loan / .wallet / .exchange / .sell / .withdraw / .deposit / .worth / .setworth Feature commands varies
uxmessentials.economy.currency.<id> Per-currency gate (when permission-required = true) โ€”
uxmessentials.economy.baltop.exempt Stay off the leaderboard false
uxmessentials.economy.pay.confirm.bypass Skip large-pay confirmation โ€”
uxmessentials.economy.bypasscmdcost Skip per-command costs โ€”

Tips & Gotchas

  • Balances survive rollbacks; that's the point. Never store money in PDC or scoreboards "for speed" โ€” the DB ledger is the source of truth and is already cached (Caffeine) between the repository and the database.
  • /baltop is a snapshot. If a fresh payment doesn't show at the top immediately, it's the cache-ttl-ms window, not a bug.
  • Disable a currency's leaderboard/transfer/exchange flags to make a token-style currency non-tradeable and non-ranked.
  • Physical currency needs three things aligned: the currency marked physical, denominations defined, and the banknotes block enabled โ€” otherwise /withdraw won't work.
  • Adding uxmEssentials to a server that already has Vault economy? It defers to the existing provider by default. Set provider.register and priority deliberately if you want uxmEssentials to take over.
  • Non-default currencies over Vault fail with CURRENCY_UNSUPPORTED โ€” Vault-only plugins can only ever see the default currency.

Next Steps