ModsJava
Lootables ⭕ Turn Any Block Into a Searchable Loot Container ⚡
Java mod listed for Minecraft 26.x. Downloads from the MC Java Mods app on Android.
⬇ Download on Spigot
Lootables
Turn any placed block into a searchable, refilling loot container
Turn any placed block into a searchable, refilling loot container
What it does
Lootables lets you take any block already in the world (a chest, a barrel, a flower pot, a head, a plain stone block, anything) and register it as a "lootable" with /loot link. From then on, right-clicking that block opens a virtual loot window players can take items out of. The contents come from a loot pool (a loot table) you define: a list of items, each with its own percent chance per draw. Each lootable rerolls its contents on a refill cooldown, so loot spots replenish over time. You can require a key to open a pool, restrict pools to players with a permission, and tune everything in an in-game editor GUI, no file editing needed.
Features
- Any block becomes a loot container: register an existing block with /loot link; right-clicking it then opens the loot window instead of its normal vanilla action
- Loot pools (loot tables): a named pool holds entries, an amount setting, a fill mode, a refill cooldown, a GUI layout, sounds, a colour-coded display name and an optional required key; many lootables can share one pool, each keeping its own contents and timer
- Faithful item entries: items are stored via the server's own item serialization, so display name, lore, enchantments and all Data Components survive a save/load round-trip exactly
- Per-entry percent chances: every entry has a chance written as a PERCENT per draw, from 0.0001% (one in a million) up to 100%; exact integer-ticket lottery (no float drift)
- Two fill modes: Mode A (air allowed): your percents are true absolute rarities, a draw can come up empty ("searched an empty dumpster"). Mode B (always full): every draw lands on an entry, so chances are only relative to each other
- Amount modes: FIXED N, RANGE min-max or MAX:N draws per refill; visible items clamped to the layout
- Lazy refill: there is NO per-lootable timer and NO global gameplay loop; a lootable is only ever evaluated when a player opens it, and its cooldown is armed only on leave (so thousands of unopened lootables cost nothing). The only repeating task is a periodic save to disk
- Full anti-dupe: the loot window is take-only: drag, shift-click in, hotbar swaps, double-click-collect and placing are all blocked; a take removes the item from the lootable first and then gives it, so an item can never exist twice. A full inventory leaves the item in the lootable (nothing dropped). Vanilla container behaviour is suppressed at a lootable for all block types
- Shared, exclusive access: only one player can have a given lootable open at a time; others are told it is being searched
- Optional keys: a key is a faithful 1:1 copy of the item you create it from (no hidden tag); a key from a PLAIN item is matched by any identical plain item, a key from a SPECIAL item (renamed / lored / custom model data) is exclusive. Keys can be "consumed" on use, but never on an empty lootable
- Restricted pools: flag a pool as restricted so looting it also needs lootables.pool.<name> (a per-pool permission registered automatically); otherwise anyone with lootables.loot may loot it
- In-game editor GUI: drop an item on a free slot to add it as an entry, click an entry to type its chance in chat, Q / middle-click to delete; buttons for amount, fill mode, refill, layout, sounds, required key, display name and restricted access; closes = saves automatically
- Auto-deregistration when the block is removed: if a registered lootable's block is destroyed by something other than a sneak-break (explosion, piston, fire, lava, flooding), the plugin tears the lootable entry down safely on the spot, closing any open session first
- Sneak-protected destruction: standing on a lootable and breaking it does nothing (no break progress, survival or creative); only SNEAK + lootables.lootable.remove removes it, dropping the block as usual and keeping the pool
- Configurable command: the command name and aliases are set in config.yml and registered at runtime, so /lootables / /loot can be changed if they clash
- Permission-filtered help & tab completion: every player only sees the subcommands they may use
- Fully customizable messages: every user-facing line lives in config.yml with & colour codes and &#RRGGBB hex
- Graceful degradation: bad data is clamped or skipped with a warning; one broken pool/lootable/key never affects the others
- Lightweight, standalone, no hard dependencies (runs on Paper or Spigot)
Commands (default command: /lootables, alias /loot)
- /loot: no subcommand shows the help; right-click a lootable to loot it
- /loot help: show the commands you may use (permission-filtered)
- /loot pool create <name>: create a pool and immediately open its editor
- /loot pool edit <name>: open the editor for an existing pool
- /loot pool delete <name> [confirm]: delete a pool (needs confirm if lootables still use it)
- /loot pool list: list all pools
- /loot pool info <name>: show a pool's settings
- /loot pool restrict <name> on|off: toggle a pool's restricted-access flag
- /loot link <pool>: register the block you look at as a lootable for that pool
- /loot lootable remove: deregister the lootable you look at (block and pool kept)
- /loot lootable info: show the lootable you look at: pool, cooldown left, items inside, lock state
- /loot key create <name>: turn the item in your main hand into a key (asks "consumed?" in chat)
- /loot key give <player> <name> [amount]: give copies of a key to a player
- /loot key assign <key> <pool>: require that key to open the pool (none to clear)
- /loot key list: list all keys
- /loot key delete <name>: delete a key (any pool that required it is cleared)
- /loot give <player> <pool>: roll ONE item from the pool and give it (for testing)
- /loot reset: reset the cooldown of the lootable you look at and release any stuck lock
- /loot reload: reload config.yml and the messages (re-registers the command if its name/aliases changed)
Permissions
Player (default: everyone):
- lootables.loot: loot lootables in general
- lootables.help: use the help subcommand
- lootables.pool.<name>: loot the pool called <name> (default true; only actually gates anything when the pool is marked restricted)
- lootables.pool.create, lootables.pool.edit, lootables.pool.delete, lootables.pool.list, lootables.pool.info
- lootables.pool.restrict: toggle a pool's restricted-access flag
- lootables.link: register the block you look at as a lootable
- lootables.lootable.remove: remove (deregister) a lootable, including sneak-break destruction
- lootables.lootable.info: show information about a lootable you look at
- lootables.key.create: create a key from the item in hand (also gates /loot key list)
- lootables.key.give, lootables.key.assign, lootables.key.delete
- lootables.give: roll one item from a pool and give it (testing)
- lootables.reset: reset a lootable cooldown and force-release its lock
- lootables.reload: reload the plugin configuration
- lootables.admin: umbrella permission granting every admin capability above
Pools, entries & lootables
A pool is a loot table: a list of entries plus an amount setting, a fill mode, a refill cooldown, a GUI layout, sounds, a colour-coded display name and an optional required key. The pool's internal name is what you type in commands; its display name is the pretty title players see on the loot window. An entry is one possible drop: an item plus a chance written as a PERCENT per draw. A lootable is a block in the world linked to a pool. Many lootables can share one pool, and each keeps its own current contents and its own refill timer.
Percent chances
Every entry's chance is a PERCENT per draw, e.g. 0.5% = one in two hundred, 0.0001% (the minimum) = one in a million, 100% = guaranteed each draw. The lottery draws exact integer tickets over a fixed denominator (no floats in the decision), so exact rarities are preserved. Values outside the configured range ( chance.min-percent / chance.max-percent) are clamped and the player is told.
Lazy refill
There is no per-lootable timer and no global gameplay tick. A lootable is evaluated only when a player opens it: if its cooldown has elapsed it rerolls fresh contents (the old contents are discarded, never topped up, and in Mode A the reroll may be empty); if it is still cooling down you see the current contents unchanged. The cooldown is (re)started only when a player leaves the lootable, and only if the contents were fresh. Thousands of unopened lootables therefore cost nothing: the only repeating task is a periodic save of changes to disk.
Anti-dupe (take-only)
The loot window is virtual and take-only: there is no way to put anything in. Drag, shift-click from your inventory, hotbar swaps, double-click-collect and placing are all blocked. A take removes the item from the lootable first and then gives it to you, so an item can never exist twice. If your inventory is full, the item simply stays in the lootable (nothing is dropped). Contents are shared: only one player can have a given lootable open at a time; the lock is released and the cooldown armed on every exit path (inventory close, logout, kick, death, server stop).
Keys
A key is a faithful 1:1 copy of the item you create it from. No hidden marking is added (exactly like looted items). An item counts as the key when it is identical (same type, name, lore, components; stack size ignored). So a key made from a PLAIN bone is matched by any plain bone, while a key made from a SPECIAL item (renamed on an anvil, with lore, custom model data) is exclusive. Create one with /loot key create <name> (you are asked whether it is "consumed"), hand out copies with /loot key give, and require it on a pool with /loot key assign <key> <pool>. A consumed key removes exactly one matching item on use, but opening an empty keyed lootable never uses your key.
Restricted pools
Every pool has a per-pool permission lootables.pool.<name> that is registered automatically and defaults to true. It only gates anything when you flag the pool as restricted with /loot pool restrict <name> on: a restricted pool then needs both lootables.loot and lootables.pool.<name>, while a non-restricted pool can be looted by anyone with lootables.loot. (Pools may not be named create/edit/delete/list/info/restrict, because those would collide with the admin permission nodes.)
The edit GUI
The editor is always a double chest (slots 0 to 44 entries, 45 to 53 buttons). Add an entry by dropping an item from your inventory onto an empty slot, or shift-clicking it: the pristine item becomes the entry with the default chance; drag-to-add is disabled on purpose to keep the stored item byte-perfect. Click an entry to open a chat prompt and type its new chance in percent; Q / middle-click deletes it. The bottom-row buttons set Amount, Fill Mode, Refill, Layout, Sounds, Required Key, Display Name and Restricted Access, and there is an info book. Just close the editor to save. It also saves on logout, kick, death and server stop while open.
Auto-deregistration on block removal
A lootable is tied to a coordinate, not protected as a block. If the registered block is removed by something other than a sneak-break: an explosion (TNT, creeper, bed/anchor, end crystal), a piston push/pull, fire (burning/fading) or flowing lava/water. The plugin notices at the moment the removal happens and safely tears down the lootable entry there, closing any open loot session first. It never influences whether the removal happens; it only cleans up afterwards so no lootable is left pointing at air.
Compatibility
Paper or Spigot, Minecraft 26.1, 26.2 and 26.3. Main version: 26.2. Paper 26.3 is currently a beta build; Lootables was tested on that beta build. Requires Java 25, api-version: 26.1. Built against paper-api 26.1.2 (the oldest tested version). The command is registered at runtime via the server's command map: on Paper the public Bukkit.getCommandMap(), on Spigot a single reflective CraftServer.getCommandMap() fallback; no NMS. Tested (server start, console commands, restart with saved data) on Paper 26.1.2 (build 74), 26.2 (build 129) and 26.3 (build 135, beta) and on Spigot 26.1.2, 26.2 and 26.3. Standalone: no hard depends; the only bundled library is bStats (relocated).
Server on 1.20.5 to 1.21.11 (Java 21)? Use Lootables 1.0.0. Tested on Paper 1.21.11: 2.0.0 is refused at load ("Unsupported API version 26.1") and the server keeps running.
Good to know
- Items are stored using the server's own item serialization, so every component (name, lore, enchantments, custom model data, …) is preserved faithfully through a save/load round-trip.
- config.yml is written once on first start and never overwritten, so your settings and messages are safe across updates. Tutorial.txt and Changelog.txt are rewritten on every start, so they always match the installed version.
- Storage lives under plugins/Lootables/: one readable file per pool (pools/<name>.yml), all lootables in lootables.yml, all keys in keys.yml. Buffered changes are flushed every storage.auto-save-interval-seconds (default 120); a crash loses at most that many seconds of changes.
- Bad data never crashes the plugin: it is clamped or skipped with a warning, and one broken pool/lootable/key never affects the others.
- Paper-format items cannot be read by Spigot: such pool entries, keys and lootable contents are dropped (the server logs errors) and are removed from the files on the next save. Back up plugins/Lootables before switching from Paper to Spigot.
- bStats: Lootables sends anonymous usage statistics to bStats. To turn this off for all plugins on your server, set enabled: false in plugins/bStats/config.yml.
Spoiler: Config
# =====================================================================================
# Lootables - configuration
# Author: WuZaa
#
# Turn any placed block into a searchable loot container (a "lootable"). This file controls
# the command name, storage, defaults for new pools, the edit-GUI button texts, and every
# user-facing message. It is written ONCE on first start and never overwritten, so your
# edits are safe across updates. Compare it with the latest defaults (see Tutorial.txt /
# Changelog.txt, which ARE refreshed each start) when 'config-version' falls behind.
#
# Colour codes: use & codes (&a, &c, &l, &r, ...) and hex &#RRGGBB anywhere in messages
# and GUI texts.
# =====================================================================================
# Internal schema version. Do not change by hand; used to warn you when new options exist.
config-version: 4
# ---- The main command ----------------------------------------------------------------
# Registered at RUNTIME (so it can avoid clashes). Changing it takes effect on /loot reload
# or restart. Default command: /lootables with the alias /loot.
command:
name: lootables
aliases:
- loot
# ---- Storage -------------------------------------------------------------------------
storage:
# How often (in seconds) buffered changes are flushed to disk. This is the ONLY repeating
# task in the whole plugin; it never iterates lootables for gameplay. A crash loses at most
# this many seconds of changes. Minimum 5.
auto-save-interval-seconds: 120
# ---- Interaction ---------------------------------------------------------------------
interaction:
# How far (in blocks) /loot link, /loot lootable ..., and /loot reset raycast for a block.
link-range: 5
# ---- Chat prompts --------------------------------------------------------------------
# Several edit actions ask you to type a value in chat (the GUI closes, you type, it reopens).
chat-prompt:
timeout-seconds: 30 # how long the plugin waits for your typed answer
cancel-word: cancel # type this to abandon a prompt
# ---- Chance bounds (PERCENT) ---------------------------------------------------------
# Per-entry chances are expressed as a PERCENTAGE per draw. These two values are the lowest
# and highest chance you are allowed to set; a typed value outside the range is clamped (and
# the player is told). min-percent = 0.0001 means "one in a million"; both are editable.
chance:
min-percent: 0.0001 # rarest chance you can set (0.0001 % = one in a million)
max-percent: 100 # highest chance (100 % = guaranteed each draw)
# ---- Defaults for newly created pools ------------------------------------------------
# When you run /loot pool create <name>, the new pool starts with these settings.
# (Its display name starts as the internal name; change it with the editor's "Display name" button.)
defaults:
amount-mode: FIXED # FIXED | RANGE | MAX (how many DRAWS happen per refill)
amount-fixed: 3 # used when amount-mode = FIXED
amount-min: 1 # used when amount-mode = RANGE (lower bound)
amount-max: 5 # used when amount-mode = RANGE/MAX (upper bound)
fill-mode: A # A = air allowed (true rarities) | B = always full (relative)
refill-min-seconds: 60 # cooldown lower bound after a lootable is looted
refill-max-seconds: 120 # cooldown upper bound
layout: DOUBLE # SINGLE (27) | DOUBLE (54) | GRID3X3 = Dropper 3x3 (9)
open-sound: BLOCK_CHEST_OPEN # Bukkit Sound enum name; invalid -> skipped + warning
close-sound: BLOCK_CHEST_CLOSE
entry-percent: 1.0 # default chance (in PERCENT) for a newly added entry
# ---- Edit GUI --------------------------------------------------------------------------
# The editor is always a double chest. Slots 0-44 hold the entries, slots 45-53 are buttons.
gui:
edit-title: '&8Editing &6%pool%'
buttons:
amount:
label: '&6Amount'
lore:
- '&7How many draws happen when the lootable refills.'
- '&8Click to set: N | min-max | max:N'
mode:
label: '&6Fill Mode'
lore:
- '&7A = air allowed (true rarities).'
- '&7B = always full (chances are relative).'
- '&8Click to toggle A/B.'
refill:
label: '&6Refill Cooldown'
lore:
- '&7Seconds before a looted lootable rerolls.'
- '&8Click to set: seconds | min-max'
layout:
label: '&6Layout'
lore:
- '&7Size of the loot window players see.'
- '&8Click to cycle: Single Chest / Double Chest / Dropper 3x3.'
sounds:
label: '&6Sounds'
lore:
- '&7Open and close sounds for this pool.'
- '&8Click to set: OPEN_SOUND CLOSE_SOUND'
key:
label: '&6Required Key'
lore:
- '&7A key the player must hold to open this pool.'
- '&8Click to set a key name, or "none".'
display-name:
label: '&6Display Name'
lore:
- '&7The pretty name players see on the loot window.'
- '&7Colour codes (& and &#RRGGBB) are allowed.'
- '&8Click to type a new display name in chat.'
restricted:
label: '&6Restricted Access'
lore:
- '&7ON = players also need lootables.pool.<name> to loot.'
- '&7OFF = anyone with lootables.loot may loot it.'
- '&8Click to toggle ON/OFF.'
info:
label: '&6How To Edit'
lore:
- '&7Drop an item from below onto an empty slot'
- '&7(or shift-click it) to add it as an entry.'
- '&7Click an entry to type its chance in percent.'
- '&7Q / Middle-click an entry to delete it.'
- '&7Close the editor to save automatically.'
# ---- Messages ------------------------------------------------------------------------
# Every user-facing line. Placeholders: %pool% (pretty display name) %pool_id% (internal name
# / what you type in a command) %other% (a second, conflicting pool name) %player% %key% %amount%
# %layout% %limit% %count% %node% %consumed% %cancel% %min% %max%. Missing keys fall back to
# the key name + a warning.
messages:
prefix: '&8[&6Lootables&8]&r '
# General
no-permission: '&cYou do not have permission to do that.'
players-only: '&cThis can only be used by a player.'
unknown-subcommand: '&cUnknown subcommand. Try &6/loot help&c.'
reloaded: '&aConfiguration and messages reloaded.'
# Open flow
pool-missing: '&cThis lootable points at a pool that no longer exists.'
lootable-in-use: '&cThis lootable is currently being searched by &e%player%&c.'
no-pool-permission: '&cYou are not allowed to loot this lootable.'
need-key: '&cYou need the key &e%key%&c to open this lootable.'
lootable-empty-key-kept: '&7This lootable is empty - your key was not used.'
inventory-full: '&cYour inventory is full; the item stays in the lootable.'
# Break / lootable management
block-destroyed: '&aLootable removed. (The pool was kept.)'
lootable-protected: '&cThis lootable is protected. Sneak + permission is required to break it.'
lootable-removed: '&aLootable deregistered.'
lootable-reset: '&aLootable cooldown reset and lock released.'
not-a-lootable: '&cThe block you are looking at is not a lootable.'
lootable-info-header: '&6Lootable info:'
# Linking
link-no-block: '&cNo solid block in range. Look directly at the block to register.'
lootable-linked: '&aBlock registered as a lootable for pool &e%pool_id%&a.'
lootable-already: '&cThat block is already a lootable (pool &e%pool_id%&c).'
# Pools
pool-created: '&aPool &e%pool_id%&a created. Editor opened.'
pool-deleted: '&aPool &e%pool_id%&a deleted.'
pool-delete-warn-lootables: '&e%count%&7 lootable(s) still use pool &e%pool_id%&7. Run &6/loot pool delete %pool_id% confirm&7 to delete anyway.'
pool-not-found: '&cNo pool named &e%pool_id%&c.'
pool-exists: '&cA pool named &e%pool_id%&c already exists.'
pool-name-reserved: '&cThe name &e%pool_id%&c is reserved and cannot be used.'
pool-name-collision: '&cThe name &e%pool_id%&c collides with the existing pool &e%other%&c (same save file). Please choose another name.'
pool-list-empty: '&7There are no pools yet.'
pool-list-header: '&6Pools (&e%count%&6):'
pool-info-header: '&6Pool &e%pool_id%&6:'
pool-full: '&cThis pool is full (45 entries maximum).'
pool-empty-entries: '&cPool &e%pool_id%&c has no entries.'
pool-restrict-on: '&aPool &e%pool_id%&a is now restricted; looting needs &e%node%&a.'
pool-restrict-off: '&aPool &e%pool_id%&a is no longer restricted; anyone with &elootables.loot&a may loot it.'
# Edit GUI
edit-drag-disabled: '&cDrag-to-add is disabled. Click one item at a time onto a free slot.'
amount-clamped: '&eHeads up: amount can exceed the layout (&6%limit%&e slots, %layout%); extra items will be clamped.'
chance-clamped: '&eChance was out of range; clamped into &6%min%&e .. &6%max%&e percent.'
# Chat prompts
prompt-chance: '&7Type this entry''s chance in PERCENT (e.g. &e0.5&7 or &e5 percent&7) (or &e%cancel%&7).'
prompt-display-name: '&7Type the display name (colour codes allowed) (or &e%cancel%&7).'
prompt-amount: '&7Type the amount: &eN&7 | &emin-max&7 | &emax:N&7 (or &e%cancel%&7).'
prompt-refill: '&7Type the refill cooldown: &eseconds&7 or &emin-max&7 (or &e%cancel%&7).'
prompt-sounds: '&7Type: &eOPEN_SOUND CLOSE_SOUND&7 (or &e%cancel%&7).'
prompt-key: '&7Type the key name to require, or &enone&7 (or &e%cancel%&7).'
prompt-key-consumed: '&7Should this key be consumed on use? Type &eyes&7 or &eno&7 (or &e%cancel%&7).'
prompt-applied: '&aValue applied.'
prompt-cancelled: '&7Prompt cancelled.'
prompt-bad-number: '&cThat was not a valid number.'
prompt-bad-amount: '&cInvalid amount. Use N, min-max, or max:N.'
prompt-bad-sound: '&cProvide two sound names: OPEN_SOUND CLOSE_SOUND.'
# Keys
key-created: '&aKey &e%key%&a created (consumed: %consumed%).'
key-create-failed: '&cCould not create the key.'
key-need-hand-item: '&cHold the item you want to turn into a key in your main hand.'
key-exists: '&cA key named &e%key%&c already exists.'
key-not-found: '&cNo key named &e%key%&c.'
key-given: '&aGave &e%amount%x %key%&a to &e%player%&a.'
key-received: '&aYou received &e%amount%x %key%&a.'
key-assigned: '&aKey &e%key%&a assigned to pool &e%pool_id%&a.'
key-deleted: '&aKey &e%key%&a deleted.'
key-list-empty: '&7There are no keys yet.'
key-list-header: '&6Keys (&e%count%&6):'
# Give / test
give-done: '&aGave a rolled item from &e%pool_id%&a to &e%player%&a.'
give-nothing: '&7The roll from &e%pool_id%&7 produced nothing (Mode A).'
# Player lookup
player-not-found: '&cPlayer &e%player%&c is not online.'
# Usage hints
usage-pool: '&cUsage: /loot pool <create|edit|delete|list|info|restrict> ...'
usage-pool-create: '&cUsage: /loot pool create <name>'
usage-pool-edit: '&cUsage: /loot pool edit <name>'
usage-pool-delete: '&cUsage: /loot pool delete <name> [confirm]'
usage-pool-info: '&cUsage: /loot pool info <name>'
usage-pool-restrict: '&cUsage: /loot pool restrict <name> on|off'
usage-link: '&cUsage: /loot link <pool>'
usage-lootable: '&cUsage: /loot lootable <remove|info>'
usage-key: '&cUsage: /loot key <create|give|assign|list|delete> ...'
usage-key-create: '&cUsage: /loot key create <name> (hold the item)'
usage-key-give: '&cUsage: /loot key give <player> <name> [amount]'
usage-key-assign: '&cUsage: /loot key assign <key> <pool>'
usage-key-delete: '&cUsage: /loot key delete <name>'
usage-give: '&cUsage: /loot give <player> <pool>'
# Help
help-header: '&6Lootables &7- commands you can use:'
Code (Text):
# =====================================================================================
# Lootables - configuration
# Author: WuZaa
#
# Turn any placed block into a searchable loot container (a "lootable"). This file controls
# the command name, storage, defaults for new pools, the edit-GUI button texts, and every
# user-facing message. It is written ONCE on first start and never overwritten, so your
# edits are safe across updates. Compare it with the latest defaults (see Tutorial.txt /
# Changelog.txt, which ARE refreshed each start) when 'config-version' falls behind.
#
# Colour codes: use & codes (&a, &c, &l, &r, ...) and hex &#RRGGBB anywhere in messages
# and GUI texts.
# =====================================================================================
# Internal schema version. Do not change by hand; used to warn you when new options exist.
config-version: 4
# ---- The main command ----------------------------------------------------------------
# Registered at RUNTIME (so it can avoid clashes). Changing it takes effect on /loot reload
# or restart. Default command: /lootables with the alias /loot.
command:
name: lootables
aliases:
- loot
# ---- Storage -------------------------------------------------------------------------
storage:
# How often (in seconds) buffered changes are flushed to disk. This is the ONLY repeating
# task in the whole plugin; it never iterates lootables for gameplay. A crash loses at most
# this many seconds of changes. Minimum 5.
auto-save-interval-seconds: 120
# ---- Interaction ---------------------------------------------------------------------
interaction:
# How far (in blocks) /loot link, /loot lootable ..., and /loot reset raycast for a block.
link-range: 5
# ---- Chat prompts --------------------------------------------------------------------
# Several edit actions ask you to type a value in chat (the GUI closes, you type, it reopens).
chat-prompt:
timeout-seconds: 30 # how long the plugin waits for your typed answer
cancel-word: cancel # type this to abandon a prompt
# ---- Chance bounds (PERCENT) ---------------------------------------------------------
# Per-entry chances are expressed as a PERCENTAGE per draw. These two values are the lowest
# and highest chance you are allowed to set; a typed value outside the range is clamped (and
# the player is told). min-percent = 0.0001 means "one in a million"; both are editable.
chance:
min-percent: 0.0001 # rarest chance you can set (0.0001 % = one in a million)
max-percent: 100 # highest chance (100 % = guaranteed each draw)
# ---- Defaults for newly created pools ------------------------------------------------
# When you run /loot pool create <name>, the new pool starts with these settings.
# (Its display name starts as the internal name; change it with the editor's "Display name" button.)
defaults:
amount-mode: FIXED # FIXED | RANGE | MAX (how many DRAWS happen per refill)
amount-fixed: 3 # used when amount-mode = FIXED
amount-min: 1 # used when amount-mode = RANGE (lower bound)
amount-max: 5 # used when amount-mode = RANGE/MAX (upper bound)
fill-mode: A # A = air allowed (true rarities) | B = always full (relative)
refill-min-seconds: 60 # cooldown lower bound after a lootable is looted
refill-max-seconds: 120 # cooldown upper bound
layout: DOUBLE # SINGLE (27) | DOUBLE (54) | GRID3X3 = Dropper 3x3 (9)
open-sound: BLOCK_CHEST_OPEN # Bukkit Sound enum name; invalid -> skipped + warning
close-sound: BLOCK_CHEST_CLOSE
entry-percent: 1.0 # default chance (in PERCENT) for a newly added entry
# ---- Edit GUI --------------------------------------------------------------------------
# The editor is always a double chest. Slots 0-44 hold the entries, slots 45-53 are buttons.
gui:
edit-title: '&8Editing &6%pool%'
buttons:
amount:
label: '&6Amount'
lore:
- '&7How many draws happen when the lootable refills.'
- '&8Click to set: N | min-max | max:N'
mode:
label: '&6Fill Mode'
lore:
- '&7A = air allowed (true rarities).'
- '&7B = always full (chances are relative).'
- '&8Click to toggle A/B.'
refill:
label: '&6Refill Cooldown'
lore:
- '&7Seconds before a looted lootable rerolls.'
- '&8Click to set: seconds | min-max'
layout:
label: '&6Layout'
lore:
- '&7Size of the loot window players see.'
- '&8Click to cycle: Single Chest / Double Chest / Dropper 3x3.'
sounds:
label: '&6Sounds'
lore:
- '&7Open and close sounds for this pool.'
- '&8Click to set: OPEN_SOUND CLOSE_SOUND'
key:
label: '&6Required Key'
lore:
- '&7A key the player must hold to open this pool.'
- '&8Click to set a key name, or "none".'
display-name:
label: '&6Display Name'
lore:
- '&7The pretty name players see on the loot window.'
- '&7Colour codes (& and &#RRGGBB) are allowed.'
- '&8Click to type a new display name in chat.'
restricted:
label: '&6Restricted Access'
lore:
- '&7ON = players also need lootables.pool.<name> to loot.'
- '&7OFF = anyone with lootables.loot may loot it.'
- '&8Click to toggle ON/OFF.'
info:
label: '&6How To Edit'
lore:
- '&7Drop an item from below onto an empty slot'
- '&7(or shift-click it) to add it as an entry.'
- '&7Click an entry to type its chance in percent.'
- '&7Q / Middle-click an entry to delete it.'
- '&7Close the editor to save automatically.'
# ---- Messages ------------------------------------------------------------------------
# Every user-facing line. Placeholders: %pool% (pretty display name) %pool_id% (internal name
# / what you type in a command) %other% (a second, conflicting pool name) %player% %key% %amount%
# %layout% %limit% %count% %node% %consumed% %cancel% %min% %max%. Missing keys fall back to
# the key name + a warning.
messages:
prefix: '&8[&6Lootables&8]&r '
# General
no-permission: '&cYou do not have permission to do that.'
players-only: '&cThis can only be used by a player.'
unknown-subcommand: '&cUnknown subcommand. Try &6/loot help&c.'
reloaded: '&aConfiguration and messages reloaded.'
# Open flow
pool-missing: '&cThis lootable points at a pool that no longer exists.'
lootable-in-use: '&cThis lootable is currently being searched by &e%player%&c.'
no-pool-permission: '&cYou are not allowed to loot this lootable.'
need-key: '&cYou need the key &e%key%&c to open this lootable.'
lootable-empty-key-kept: '&7This lootable is empty - your key was not used.'
inventory-full: '&cYour inventory is full; the item stays in the lootable.'
# Break / lootable management
block-destroyed: '&aLootable removed. (The pool was kept.)'
lootable-protected: '&cThis lootable is protected. Sneak + permission is required to break it.'
lootable-removed: '&aLootable deregistered.'
lootable-reset: '&aLootable cooldown reset and lock released.'
not-a-lootable: '&cThe block you are looking at is not a lootable.'
lootable-info-header: '&6Lootable info:'
# Linking
link-no-block: '&cNo solid block in range. Look directly at the block to register.'
lootable-linked: '&aBlock registered as a lootable for pool &e%pool_id%&a.'
lootable-already: '&cThat block is already a lootable (pool &e%pool_id%&c).'
# Pools
pool-created: '&aPool &e%pool_id%&a created. Editor opened.'
pool-deleted: '&aPool &e%pool_id%&a deleted.'
pool-delete-warn-lootables: '&e%count%&7 lootable(s) still use pool &e%pool_id%&7. Run &6/loot pool delete %pool_id% confirm&7 to delete anyway.'
pool-not-found: '&cNo pool named &e%pool_id%&c.'
pool-exists: '&cA pool named &e%pool_id%&c already exists.'
pool-name-reserved: '&cThe name &e%pool_id%&c is reserved and cannot be used.'
pool-name-collision: '&cThe name &e%pool_id%&c collides with the existing pool &e%other%&c (same save file). Please choose another name.'
pool-list-empty: '&7There are no pools yet.'
pool-list-header: '&6Pools (&e%count%&6):'
pool-info-header: '&6Pool &e%pool_id%&6:'
pool-full: '&cThis pool is full (45 entries maximum).'
pool-empty-entries: '&cPool &e%pool_id%&c has no entries.'
pool-restrict-on: '&aPool &e%pool_id%&a is now restricted; looting needs &e%node%&a.'
pool-restrict-off: '&aPool &e%pool_id%&a is no longer restricted; anyone with &elootables.loot&a may loot it.'
# Edit GUI
edit-drag-disabled: '&cDrag-to-add is disabled. Click one item at a time onto a free slot.'
amount-clamped: '&eHeads up: amount can exceed the layout (&6%limit%&e slots, %layout%); extra items will be clamped.'
chance-clamped: '&eChance was out of range; clamped into &6%min%&e .. &6%max%&e percent.'
# Chat prompts
prompt-chance: '&7Type this entry''s chance in PERCENT (e.g. &e0.5&7 or &e5 percent&7) (or &e%cancel%&7).'
prompt-display-name: '&7Type the display name (colour codes allowed) (or &e%cancel%&7).'
prompt-amount: '&7Type the amount: &eN&7 | &emin-max&7 | &emax:N&7 (or &e%cancel%&7).'
prompt-refill: '&7Type the refill cooldown: &eseconds&7 or &emin-max&7 (or &e%cancel%&7).'
prompt-sounds: '&7Type: &eOPEN_SOUND CLOSE_SOUND&7 (or &e%cancel%&7).'
prompt-key: '&7Type the key name to require, or &enone&7 (or &e%cancel%&7).'
prompt-key-consumed: '&7Should this key be consumed on use? Type &eyes&7 or &eno&7 (or &e%cancel%&7).'
prompt-applied: '&aValue applied.'
prompt-cancelled: '&7Prompt cancelled.'
prompt-bad-number: '&cThat was not a valid number.'
prompt-bad-amount: '&cInvalid amount. Use N, min-max, or max:N.'
prompt-bad-sound: '&cProvide two sound names: OPEN_SOUND CLOSE_SOUND.'
# Keys
key-created: '&aKey &e%key%&a created (consumed: %consumed%).'
key-create-failed: '&cCould not create the key.'
key-need-hand-item: '&cHold the item you want to turn into a key in your main hand.'
key-exists: '&cA key named &e%key%&c already exists.'
key-not-found: '&cNo key named &e%key%&c.'
key-given: '&aGave &e%amount%x %key%&a to &e%player%&a.'
key-received: '&aYou received &e%amount%x %key%&a.'
key-assigned: '&aKey &e%key%&a assigned to pool &e%pool_id%&a.'
key-deleted: '&aKey &e%key%&a deleted.'
key-list-empty: '&7There are no keys yet.'
key-list-header: '&6Keys (&e%count%&6):'
# Give / test
give-done: '&aGave a rolled item from &e%pool_id%&a to &e%player%&a.'
give-nothing: '&7The roll from &e%pool_id%&7 produced nothing (Mode A).'
# Player lookup
player-not-found: '&cPlayer &e%player%&c is not online.'
# Usage hints
usage-pool: '&cUsage: /loot pool <create|edit|delete|list|info|restrict> ...'
usage-pool-create: '&cUsage: /loot pool create <name>'
usage-pool-edit: '&cUsage: /loot pool edit <name>'
usage-pool-delete: '&cUsage: /loot pool delete <name> [confirm]'
usage-pool-info: '&cUsage: /loot pool info <name>'
usage-pool-restrict: '&cUsage: /loot pool restrict <name> on|off'
usage-link: '&cUsage: /loot link <pool>'
usage-lootable: '&cUsage: /loot lootable <remove|info>'
usage-key: '&cUsage: /loot key <create|give|assign|list|delete> ...'
usage-key-create: '&cUsage: /loot key create <name> (hold the item)'
usage-key-give: '&cUsage: /loot key give <player> <name> [amount]'
usage-key-assign: '&cUsage: /loot key assign <key> <pool>'
usage-key-delete: '&cUsage: /loot key delete <name>'
usage-give: '&cUsage: /loot give <player> <pool>'
# Help
help-header: '&6Lootables &7- commands you can use:'
Spoiler: Tutorial
=====================================================
Lootables - Tutorial
Author: WuZaa
=====================================================
WHAT THIS PLUGIN DOES
Lootables turns any placed block into a searchable loot container - a "lootable".
Players right-click a lootable to open a loot window and TAKE items out of it. The
contents come from a "loot pool" (a loot table) you define. Each lootable rerolls its
contents on a cooldown, so lootables refill over time. You can require a key to open
certain pools, and you can restrict pools to players with a permission.
Lootables are NOT placed like normal blocks. You take ANY existing block in the world
(a chest, a barrel, a flower pot, a head, a regular stone block - anything) and
REGISTER it as a lootable with /loot link. From then on, right-clicking that block opens
the loot window instead of doing its normal vanilla action.
THE CORE IDEA: POOLS, ENTRIES, LOOTABLES
- A POOL is a loot table. It has a list of ENTRIES, an amount setting, a fill mode,
a refill cooldown, a GUI layout, sounds, a pretty display name, and (optionally) a
required key. The pool's internal NAME is what you type in commands; its DISPLAY NAME
is the pretty, colour-coded title players see on the loot window (you can change it any
time in the editor).
- An ENTRY is one possible drop: an item plus a chance written as a PERCENT per draw
(e.g. 0.1% means a 0.1% chance per draw). The smallest chance you can set is 0.0001%
(one in a million); the largest is 100%.
- A LOOTABLE is a block in the world that is linked to a pool. Many lootables can share
the same pool. Each lootable keeps its OWN current contents and its OWN refill timer.
QUICK START
1. /loot pool create MyPool (creates a pool and opens the editor)
2. In the editor, drop items from your inventory onto the empty slots to add them as
entries, and click an entry to type its chance (in percent) in chat.
3. Close the editor (it saves automatically).
4. Look at a block in the world and run: /loot link MyPool
5. Right-click that block - the loot window opens. Take items by clicking them.
COMMANDS (default command: /lootables, alias /loot)
/loot Right-click a lootable to loot it. (No subcommand = help.)
/loot help Show the commands YOU may use (permission-filtered).
/loot pool create <name> Create a pool and immediately open its editor.
/loot pool edit <name> Open the editor for an existing pool.
/loot pool delete <name> [confirm] Delete a pool. If lootables still use it you must add the
word "confirm". (The lootables are kept but will report a
missing pool until relinked.)
/loot pool list List all pools.
/loot pool info <name> Show a pool's settings (including its display name).
/loot pool restrict <name> on|off Mark a pool as restricted. While ON, players also need
lootables.pool.<name> to loot it (besides lootables.loot).
/loot link <pool> Register the block you are looking at as a lootable for
that pool. (Raycast; look directly at a solid block.)
/loot lootable remove Deregister the lootable you are looking at. (The block and
the pool are kept.)
/loot lootable info Show the lootable you are looking at: pool, cooldown
remaining, items inside, and lock state.
/loot key create <name> Turn the item in your main hand into a key. You will be
asked in chat whether the key is "consumed" on use.
/loot key give <player> <name> [amount]
Give copies of a key to a player.
/loot key assign <key> <pool> Require that key to open the pool (use "none" to clear).
/loot key list List all keys.
/loot key delete <name> Delete a key. Any pool that required it is cleared.
/loot give <player> <pool> Roll ONE item from the pool and give it (for testing).
/loot reset Reset the cooldown of the lootable you look at and release
any stuck lock on it.
/loot reload Reload config.yml and the messages. If you changed the
command name/aliases, they are re-registered.
The command NAME and ALIASES can be changed in config.yml (command.name / command.aliases)
if /lootables or /loot clash with another plugin. Changes apply after /loot reload.
PERMISSIONS
Player:
lootables.loot Loot lootables in general. (default: everyone)
lootables.help Use the help subcommand. (default: everyone)
Per-pool (registered automatically when a pool is created/loaded):
lootables.pool.<name> Loot the pool called <name>. (default: TRUE)
This only actually GATES anything when the pool is marked
"restricted". A non-restricted pool can be looted by anyone with
lootables.loot. A restricted pool ALSO requires
lootables.pool.<name>.
(Reserved: pools may not be named create/edit/delete/list/info/restrict,
because those would collide with the admin permission nodes.)
Admin (default: operators only; each can be assigned individually):
lootables.pool.create lootables.pool.edit lootables.pool.delete
lootables.pool.list lootables.pool.info lootables.pool.restrict
lootables.link lootables.lootable.remove lootables.lootable.info
lootables.key.create (also gates "/loot key list")
lootables.key.give lootables.key.assign lootables.key.delete
lootables.give lootables.reset lootables.reload
lootables.admin Umbrella: grants every admin capability above.
HOW LOOTING WORKS (anti-dupe: TAKE-ONLY)
The loot window is virtual. You can only TAKE items out of it - there is NO way to put
anything in. Drag, shift-click from your inventory, hotbar swaps, double-click-collect and
placing are all blocked. A take removes the item from the lootable first and then gives it
to you, so an item can never exist twice. If your inventory is full, the item simply stays
in the lootable (nothing is dropped on the ground). Contents are SHARED: only one player can
have a given lootable open at a time; others see "this lootable is being searched".
DESTROYING A LOOTABLE (sneak + break)
Standing on a lootable and breaking it does NOTHING - no break progress at all, in survival
or creative. To destroy a lootable you must SNEAK and have the permission
lootables.lootable.remove, then break the block normally. Doing so deregisters the lootable
and lets the block drop as usual. The pool is NOT deleted. (You can also use
/loot lootable remove while looking at it.)
Note: if a lootable block is removed by non-player means - an explosion, a piston, fire/burning,
or flowing lava/water - the lootable DEREGISTERS itself automatically (any open loot window is
closed cleanly first). The block and the pool are kept. Only blocks removed by external tools that
fire no normal Bukkit events (e.g. vanilla /fill or WorldEdit //set air), or rare edge cases, can leave a stale
registration pointing at air - then use /loot lootable remove to clean it up.
FILL MODES (the key to rarity)
Each draw the lootable makes resolves to either an item or "nothing", depending on the mode:
Mode A (air allowed) - the default and the realistic one:
Your percent chances are TRUE absolute rarities. A draw can come up empty, so a lootable
may end up partially filled or even completely empty - the "searched an empty dumpster"
feel. Rare items are genuinely rare.
Mode B (always full) - never empty:
Every draw always lands on one of your entries; "nothing" is impossible. This means the
chances are only RELATIVE to each other (an entry at 0.1% vs one at 10% is simply
one-hundred-times-less-likely-than). A true absolute rarity cannot exist in Mode B.
CHANCES (per-entry, in PERCENT)
Every entry has a chance written as a PERCENT per draw. Examples: 0.5% is a one-in-two-hundred
chance; 0.0001% (the minimum) is one in a million; 100% is guaranteed each draw. You type the
chance directly - there is no stepping and no old-style ratio form. The allowed range (chance.min-percent
and chance.max-percent) is set in config.yml; a value outside it is clamped and you are told.
AMOUNT (how many DRAWS per refill)
FIXED N Always exactly N draws.
RANGE min-max A random number of draws between min and max (inclusive).
MAX:N A random number of draws between 0 and N.
In Mode A, a draw may be "nothing", so the number of draws is NOT the number of items that
end up inside. The number of VISIBLE items is clamped to the layout's slot count.
LAYOUTS (the player-facing loot window size)
SINGLE = 27 slots (single chest)
DOUBLE = 54 slots (double chest)
GRID3X3 = 9 slots (a 3x3 dropper window)
The EDITOR is always a double chest regardless of the pool layout. If your amount can exceed
the layout's slot count, the visible items are clamped and you get a heads-up.
KEYS
A key is a faithful 1:1 copy of the item you create it from - no hidden marking is added, exactly
like looted items. An item counts as the key when it is identical to that item (same type, name,
lore, components; the stack size does not matter).
- This means: make a key from a PLAIN bone and ANY plain bone works as the key. Want an EXCLUSIVE
key? Create it from a SPECIAL item (e.g. a bone renamed on an anvil, with lore) - then only that
special item counts, an ordinary bone does not.
- Create: hold the item, run /loot key create <name>, answer whether it is "consumed".
- Give out copies: /loot key give <player> <name> [amount] (handy for special/exclusive keys).
- Consumed keys: opening a lootable that requires the key removes exactly ONE matching item -
BUT only if the lootable actually had something inside. Opening an EMPTY keyed lootable never
uses your key. Non-consumed keys are never removed; the player just needs to hold one.
- Require a key on a pool: /loot key assign <key> <pool> (or "none" to clear).
THE EDIT GUI (slots 0-44 entries, 45-53 buttons)
Adding entries:
- Drop an item from your inventory onto an empty entry slot, OR shift-click an item from
your inventory. The pristine item (with the amount you placed) becomes the entry, with
the default chance from config (defaults.entry-percent).
- Drag-to-add is disabled on purpose, to keep the stored item byte-perfect. Add one at a
time.
Tuning an entry (click it):
- A single LEFT or RIGHT click on an entry opens a chat prompt: type the new chance in
PERCENT (e.g. 0.5 or 5%). Commas and a trailing % are accepted.
- Q / Middle-click an entry = delete it.
Buttons (bottom row):
- Amount, Fill Mode, Refill, Layout, Sounds, Required Key, "Restricted Access" (on/off; while
ON players also need lootables.pool.<name>), "Display Name" (type a pretty, colour-coded name
players see on the loot window), and an info book.
Saving: just CLOSE the editor - it saves automatically. It also saves on logout, kick, death
and server stop while open.
REFILLS (lazy - nothing ticks in the background)
There is NO per-lootable timer and NO global gameplay loop. A lootable is only ever evaluated
when a player OPENS it:
- If its cooldown has elapsed, it REROLLS fresh contents (the old contents are discarded,
never topped up). The reroll may be empty in Mode A.
- If it is still cooling down, you see the current contents unchanged.
The cooldown is (re)started only when a player LEAVES the lootable, and only if the contents
were fresh. Peeking at a lootable that is still on cooldown does NOT extend it. Emptied
lootables stay empty until the timer elapses; partially looted lootables keep the remainder.
This means thousands of unopened lootables cost nothing - the plugin does no work until someone
right-clicks. The only repeating task is a periodic save of changes to disk.
STORAGE & FILES (under plugins/Lootables/)
config.yml Your settings + all messages. Written once, never overwritten.
Tutorial.txt This file. Rewritten every start (always matches the installed version).
Changelog.txt Version history + recorded design decisions. Rewritten every start.
pools/<name>.yml One file per pool (readable).
lootables.yml All lootables (positions, current contents, cooldowns).
keys.yml All keys.
Items are stored using the server's own item serialization, so every component is preserved
faithfully. Bad data never crashes the plugin: it is clamped or skipped with a warning, and
one broken pool/lootable/key never affects the others.
=====================================================
Code (Text):
=====================================================
Lootables - Tutorial
Author: WuZaa
=====================================================
WHAT THIS PLUGIN DOES
Lootables turns any placed block into a searchable loot container - a "lootable".
Players right-click a lootable to open a loot window and TAKE items out of it. The
contents come from a "loot pool" (a loot table) you define. Each lootable rerolls its
contents on a cooldown, so lootables refill over time. You can require a key to open
certain pools, and you can restrict pools to players with a permission.
Lootables are NOT placed like normal blocks. You take ANY existing block in the world
(a chest, a barrel, a flower pot, a head, a regular stone block - anything) and
REGISTER it as a lootable with /loot link. From then on, right-clicking that block opens
the loot window instead of doing its normal vanilla action.
THE CORE IDEA: POOLS, ENTRIES, LOOTABLES
- A POOL is a loot table. It has a list of ENTRIES, an amount setting, a fill mode,
a refill cooldown, a GUI layout, sounds, a pretty display name, and (optionally) a
required key. The pool's internal NAME is what you type in commands; its DISPLAY NAME
is the pretty, colour-coded title players see on the loot window (you can change it any
time in the editor).
- An ENTRY is one possible drop: an item plus a chance written as a PERCENT per draw
(e.g. 0.1% means a 0.1% chance per draw). The smallest chance you can set is 0.0001%
(one in a million); the largest is 100%.
- A LOOTABLE is a block in the world that is linked to a pool. Many lootables can share
the same pool. Each lootable keeps its OWN current contents and its OWN refill timer.
QUICK START
1. /loot pool create MyPool (creates a pool and opens the editor)
2. In the editor, drop items from your inventory onto the empty slots to add them as
entries, and click an entry to type its chance (in percent) in chat.
3. Close the editor (it saves automatically).
4. Look at a block in the world and run: /loot link MyPool
5. Right-click that block - the loot window opens. Take items by clicking them.
COMMANDS (default command: /lootables, alias /loot)
/loot Right-click a lootable to loot it. (No subcommand = help.)
/loot help Show the commands YOU may use (permission-filtered).
/loot pool create <name> Create a pool and immediately open its editor.
/loot pool edit <name> Open the editor for an existing pool.
/loot pool delete <name> [confirm] Delete a pool. If lootables still use it you must add the
word "confirm". (The lootables are kept but will report a
missing pool until relinked.)
/loot pool list List all pools.
/loot pool info <name> Show a pool's settings (including its display name).
/loot pool restrict <name> on|off Mark a pool as restricted. While ON, players also need
lootables.pool.<name> to loot it (besides lootables.loot).
/loot link <pool> Register the block you are looking at as a lootable for
that pool. (Raycast; look directly at a solid block.)
/loot lootable remove Deregister the lootable you are looking at. (The block and
the pool are kept.)
/loot lootable info Show the lootable you are looking at: pool, cooldown
remaining, items inside, and lock state.
/loot key create <name> Turn the item in your main hand into a key. You will be
asked in chat whether the key is "consumed" on use.
/loot key give <player> <name> [amount]
Give copies of a key to a player.
/loot key assign <key> <pool> Require that key to open the pool (use "none" to clear).
/loot key list List all keys.
/loot key delete <name> Delete a key. Any pool that required it is cleared.
/loot give <player> <pool> Roll ONE item from the pool and give it (for testing).
/loot reset Reset the cooldown of the lootable you look at and release
any stuck lock on it.
/loot reload Reload config.yml and the messages. If you changed the
command name/aliases, they are re-registered.
The command NAME and ALIASES can be changed in config.yml (command.name / command.aliases)
if /lootables or /loot clash with another plugin. Changes apply after /loot reload.
PERMISSIONS
Player:
lootables.loot Loot lootables in general. (default: everyone)
lootables.help Use the help subcommand. (default: everyone)
Per-pool (registered automatically when a pool is created/loaded):
lootables.pool.<name> Loot the pool called <name>. (default: TRUE)
This only actually GATES anything when the pool is marked
"restricted". A non-restricted pool can be looted by anyone with
lootables.loot. A restricted pool ALSO requires
lootables.pool.<name>.
(Reserved: pools may not be named create/edit/delete/list/info/restrict,
because those would collide with the admin permission nodes.)
Admin (default: operators only; each can be assigned individually):
lootables.pool.create lootables.pool.edit lootables.pool.delete
lootables.pool.list lootables.pool.info lootables.pool.restrict
lootables.link lootables.lootable.remove lootables.lootable.info
lootables.key.create (also gates "/loot key list")
lootables.key.give lootables.key.assign lootables.key.delete
lootables.give lootables.reset lootables.reload
lootables.admin Umbrella: grants every admin capability above.
HOW LOOTING WORKS (anti-dupe: TAKE-ONLY)
The loot window is virtual. You can only TAKE items out of it - there is NO way to put
anything in. Drag, shift-click from your inventory, hotbar swaps, double-click-collect and
placing are all blocked. A take removes the item from the lootable first and then gives it
to you, so an item can never exist twice. If your inventory is full, the item simply stays
in the lootable (nothing is dropped on the ground). Contents are SHARED: only one player can
have a given lootable open at a time; others see "this lootable is being searched".
DESTROYING A LOOTABLE (sneak + break)
Standing on a lootable and breaking it does NOTHING - no break progress at all, in survival
or creative. To destroy a lootable you must SNEAK and have the permission
lootables.lootable.remove, then break the block normally. Doing so deregisters the lootable
and lets the block drop as usual. The pool is NOT deleted. (You can also use
/loot lootable remove while looking at it.)
Note: if a lootable block is removed by non-player means - an explosion, a piston, fire/burning,
or flowing lava/water - the lootable DEREGISTERS itself automatically (any open loot window is
closed cleanly first). The block and the pool are kept. Only blocks removed by external tools that
fire no normal Bukkit events (e.g. vanilla /fill or WorldEdit //set air), or rare edge cases, can leave a stale
registration pointing at air - then use /loot lootable remove to clean it up.
FILL MODES (the key to rarity)
Each draw the lootable makes resolves to either an item or "nothing", depending on the mode:
Mode A (air allowed) - the default and the realistic one:
Your percent chances are TRUE absolute rarities. A draw can come up empty, so a lootable
may end up partially filled or even completely empty - the "searched an empty dumpster"
feel. Rare items are genuinely rare.
Mode B (always full) - never empty:
Every draw always lands on one of your entries; "nothing" is impossible. This means the
chances are only RELATIVE to each other (an entry at 0.1% vs one at 10% is simply
one-hundred-times-less-likely-than). A true absolute rarity cannot exist in Mode B.
CHANCES (per-entry, in PERCENT)
Every entry has a chance written as a PERCENT per draw. Examples: 0.5% is a one-in-two-hundred
chance; 0.0001% (the minimum) is one in a million; 100% is guaranteed each draw. You type the
chance directly - there is no stepping and no old-style ratio form. The allowed range (chance.min-percent
and chance.max-percent) is set in config.yml; a value outside it is clamped and you are told.
AMOUNT (how many DRAWS per refill)
FIXED N Always exactly N draws.
RANGE min-max A random number of draws between min and max (inclusive).
MAX:N A random number of draws between 0 and N.
In Mode A, a draw may be "nothing", so the number of draws is NOT the number of items that
end up inside. The number of VISIBLE items is clamped to the layout's slot count.
LAYOUTS (the player-facing loot window size)
SINGLE = 27 slots (single chest)
DOUBLE = 54 slots (double chest)
GRID3X3 = 9 slots (a 3x3 dropper window)
The EDITOR is always a double chest regardless of the pool layout. If your amount can exceed
the layout's slot count, the visible items are clamped and you get a heads-up.
KEYS
A key is a faithful 1:1 copy of the item you create it from - no hidden marking is added, exactly
like looted items. An item counts as the key when it is identical to that item (same type, name,
lore, components; the stack size does not matter).
- This means: make a key from a PLAIN bone and ANY plain bone works as the key. Want an EXCLUSIVE
key? Create it from a SPECIAL item (e.g. a bone renamed on an anvil, with lore) - then only that
special item counts, an ordinary bone does not.
- Create: hold the item, run /loot key create <name>, answer whether it is "consumed".
- Give out copies: /loot key give <player> <name> [amount] (handy for special/exclusive keys).
- Consumed keys: opening a lootable that requires the key removes exactly ONE matching item -
BUT only if the lootable actually had something inside. Opening an EMPTY keyed lootable never
uses your key. Non-consumed keys are never removed; the player just needs to hold one.
- Require a key on a pool: /loot key assign <key> <pool> (or "none" to clear).
THE EDIT GUI (slots 0-44 entries, 45-53 buttons)
Adding entries:
- Drop an item from your inventory onto an empty entry slot, OR shift-click an item from
your inventory. The pristine item (with the amount you placed) becomes the entry, with
the default chance from config (defaults.entry-percent).
- Drag-to-add is disabled on purpose, to keep the stored item byte-perfect. Add one at a
time.
Tuning an entry (click it):
- A single LEFT or RIGHT click on an entry opens a chat prompt: type the new chance in
PERCENT (e.g. 0.5 or 5%). Commas and a trailing % are accepted.
- Q / Middle-click an entry = delete it.
Buttons (bottom row):
- Amount, Fill Mode, Refill, Layout, Sounds, Required Key, "Restricted Access" (on/off; while
ON players also need lootables.pool.<name>), "Display Name" (type a pretty, colour-coded name
players see on the loot window), and an info book.
Saving: just CLOSE the editor - it saves automatically. It also saves on logout, kick, death
and server stop while open.
REFILLS (lazy - nothing ticks in the background)
There is NO per-lootable timer and NO global gameplay loop. A lootable is only ever evaluated
when a player OPENS it:
- If its cooldown has elapsed, it REROLLS fresh contents (the old contents are discarded,
never topped up). The reroll may be empty in Mode A.
- If it is still cooling down, you see the current contents unchanged.
The cooldown is (re)started only when a player LEAVES the lootable, and only if the contents
were fresh. Peeking at a lootable that is still on cooldown does NOT extend it. Emptied
lootables stay empty until the timer elapses; partially looted lootables keep the remainder.
This means thousands of unopened lootables cost nothing - the plugin does no work until someone
right-clicks. The only repeating task is a periodic save of changes to disk.
STORAGE & FILES (under plugins/Lootables/)
config.yml Your settings + all messages. Written once, never overwritten.
Tutorial.txt This file. Rewritten every start (always matches the installed version).
Changelog.txt Version history + recorded design decisions. Rewritten every start.
pools/<name>.yml One file per pool (readable).
lootables.yml All lootables (positions, current contents, cooldowns).
keys.yml All keys.
Items are stored using the server's own item serialization, so every component is preserved
faithfully. Bad data never crashes the plugin: it is clamped or skipped with a warning, and
one broken pool/lootable/key never affects the others.
=====================================================
Feedback & Support
Found a bug?
Have an idea for a new feature?
Need help with the plugin?
Feel free to join my Discord server:
Discord: https://discord.gg/rSQ8ksysQT
I'm always open to feedback, suggestions, and feature requests.
I'll try to respond as quickly as possible and help you with any problems you may encounter.
Reviews
Reviews are always appreciated as a small thank-you, whether they're positive or negative. However, if you're thinking about leaving a negative review, I'd really appreciate it if you contacted me on Discord first.
There's a good chance we can solve the issue together, and if we can't, you're of course still free to leave your review afterward.
Thanks for giving it a try, and have fun!
Found a bug?
Have an idea for a new feature?
Need help with the plugin?
Feel free to join my Discord server:
Discord: https://discord.gg/rSQ8ksysQT
I'm always open to feedback, suggestions, and feature requests.
I'll try to respond as quickly as possible and help you with any problems you may encounter.
Reviews
Reviews are always appreciated as a small thank-you, whether they're positive or negative. However, if you're thinking about leaving a negative review, I'd really appreciate it if you contacted me on Discord first.
There's a good chance we can solve the issue together, and if we can't, you're of course still free to leave your review afterward.
Thanks for giving it a try, and have fun!
Quick facts
- Edition: Minecraft Java
- File type: .jar
- Minecraft versions listed: 26.1, 26.2, 26.3
- How to install: Install the matching mod loader (Forge, Fabric or NeoForge) for your Minecraft version. → Download the .jar. → Put it in the .minecraft/mods folder and launch that loader profile.
- Where to get it: Opens on Spigot — not every file is mirrored on our own servers.
Install steps are the general flow for this file type — How to install Minecraft Java mods & modpacks walks through it step by step.
Lootables ⭕ Turn Any Block Into a Searchable Loot Container ⚡ is a free Minecraft Java mod. Compatible with Minecraft 26.1, 26.2, 26.3. Downloaded 27 times (via Spigot). Download it and open it directly in the game.