Skip to main content

Loot Tables

Package: dev.anchorlight.stonelib.loot

LootTable turns a list in a config file into weighted random item rolls, for crates, mob drops, event rewards, or anything else that hands out a random set of items.

Config shape

crate-loot:
- material: IRON_INGOT
min: 2
max: 6
weight: 10
- material: GOLDEN_APPLE
weight: 2
- material: ENCHANTED_BOOK
weight: 1
enchantments:
minecraft:sharpness: 3
minecraft:unbreaking: 2
- material: DIAMOND_SWORD
weight: 0.5
enchantments:
minecraft:sharpness: 5
FieldDefaultMeaning
materialrequiredA material name, such as IRON_INGOT, iron_ingot, or minecraft:iron_ingot.
min1Smallest stack.
maxminLargest stack. A max below min is raised to min.
weight1.0Relative chance. Decimals are allowed. Anything below 0.0001, including zero and negatives, becomes 0.0001.
enchantmentsnoneEnchantment key to level. Keys need their namespace, such as minecraft:sharpness.

The chance of an entry is its weight divided by the total weight. In the table above the total is 13.5, so a golden apple comes up about 15% of the time.

Example

LootTable crateLoot = LootTable.fromSection(getConfig(), "crate-loot", getLogger());

public void openCrate(Player player) {
for (ItemStack item : crateLoot.roll(3)) {
player.getInventory().addItem(item).values()
.forEach(overflow -> player.getWorld().dropItemNaturally(player.getLocation(), overflow));
}
}

API

MethodMeaning
LootTable.fromSection(ConfigurationSection, String path, Logger)Reads the list at path. A null section gives an empty table.
LootTable.fromMapList(List<Map<?, ?>> rows, Logger)Builds from raw maps, such as section.getMapList("loot").
LootTable.fromMapList(List<Map<?, ?>> rows, Logger, Random)As above, with your own Random, for repeatable rolls in tests.
roll(int rolls)Rolls the table that many times and returns the items.
pick()One weighted pick, returning the Entry rather than an item.
isEmpty()Whether the table has any entries.
entries()The parsed entries, unmodifiable.
LootTable.material(String)Resolves a material name, with or without minecraft:. null if unknown.
LootTable.enchantment(String)Resolves an enchantment from the registry by namespaced key. null if unknown.

Entry is a record: Entry(Material material, int min, int max, double weight, Map<String, Integer> enchantments).

How a roll builds an item

  1. A weighted pick chooses an entry.
  2. The amount is a random whole number from min to max, inclusive, capped at the material's maximum stack size.
  3. An amount of zero or less produces no item for that roll.
  4. Enchantments are added ignoring level limits, so a config can ask for sharpness: 10. On an enchanted book they are added as stored enchantments, which is what makes the book usable on an anvil. On anything else they are applied directly.

Behaviour to know about

  • Rolls are independent. roll(3) can return the same entry three times. For "three different items", call pick() yourself and skip repeats.
  • roll always rolls at least once. roll(0) and negative counts roll once. Check the count yourself if zero should mean nothing.
  • An empty table rolls nothing. roll returns an empty list and pick throws, so check isEmpty() before calling pick.
  • Bad entries are skipped, not thrown. An unknown material is logged as Unknown loot material: <name> - entry skipped. A typo in a config file should not take an event down. An unknown enchantment is skipped silently when the item is built, so double-check enchantment keys.
  • min, max, weight, and levels must be numbers. A value in quotes is treated as missing and falls back to its default.
  • max above a stack size is capped, not split. min: 100 of an item that stacks to 64 gives one stack of 64.