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
| Field | Default | Meaning |
|---|---|---|
material | required | A material name, such as IRON_INGOT, iron_ingot, or minecraft:iron_ingot. |
min | 1 | Smallest stack. |
max | min | Largest stack. A max below min is raised to min. |
weight | 1.0 | Relative chance. Decimals are allowed. Anything below 0.0001, including zero and negatives, becomes 0.0001. |
enchantments | none | Enchantment 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
| Method | Meaning |
|---|---|
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
- A weighted pick chooses an entry.
- The amount is a random whole number from
mintomax, inclusive, capped at the material's maximum stack size. - An amount of zero or less produces no item for that roll.
- 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", callpick()yourself and skip repeats. rollalways 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.
rollreturns an empty list andpickthrows, so checkisEmpty()before callingpick. - 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.maxabove a stack size is capped, not split.min: 100of an item that stacks to 64 gives one stack of 64.