Loot Boxes
Loot Boxes is a definition-driven loot box mod. The mod registers only one loot box item, lootbox:loot_box; the actual box type is stored in the item's loot_box_id data. Loot boxes can come from built-in definitions, data packs, or KubeJS.
On login and after /reload, the server synchronizes the final definitions with every client. In multiplayer, JEI, the creative inventory, item names, colors, tooltips, and reward previews therefore use the server's data.
Quick Start
/lootbox give @s lootbox:common
/lootbox give @s lootbox:rare 3
Built-in box tiers, from lowest to highest, are:
common → unusual → rare → epic → legendary → endurance
The Endurance Reward Box has a 0.01% chance to enter its reward roll. Of those rolls, 80% give 100 diamond blocks and 20% give 100 emerald blocks. The remaining 99.99% gives another Endurance Reward Box.
Built-in loot tables can optionally include representative items from Mekanism, Create, Iron's Spells 'n Spellbooks, Goety, Applied Energistics 2, Terra Entity, The Twilight Forest, and The Aether. Missing mods are skipped automatically and never become hard dependencies.
Data Packs
Place definitions at:
data/<namespace>/loot_boxes/<id>.json
Complete example:
{
"display_name_key": "example.lootbox.name",
"color": "#00E5FF",
"rolls": 2,
"jei_info_key": "example.lootbox.jei_info",
"entries": [
{
"item": "minecraft:diamond",
"min": 1,
"max": 3,
"weight": 10,
"luck_weight": 2,
"condition": { "type": "luck", "min": 2 }
},
{
"tag": "minecraft:music_discs",
"min": 1,
"max": 1,
"weight": 5
},
{
"box": "lootbox:rare",
"min": 1,
"max": 1,
"weight": 1
}
]
}
Root fields
| Field | Type | Description |
|---|---|---|
display_name_key |
String | Translation key for the box name. Recommended. Use display_name for literal text instead. |
color |
#RRGGBB, 0xRRGGBB, or integer |
Color applied to the box texture. Defaults to white. |
rolls |
Integer | Number of reward rolls per opening. Defaults to 1. |
jei_info_key |
String | Translation key for the JEI information panel. Use jei_info for literal text instead. |
entries |
Array | Reward entries. Each entry must define exactly one of item, tag, or box. |
Reward entries
item: fixed item ID.tag: item tag ID. One item is selected uniformly from the tag, while the entry's total weight remains unchanged. Tags are resolved again after a data reload.box: another loot box ID.min,max: quantity range.weight: base entry weight.luck_weight: final weight isweight + player luck × luck_weight.condition: {"type":"luck","min":2}: requires the player's luck to be at least2.condition.display_keyorcondition.display: display text for a registered custom condition in JEI and tooltips.
Tag rewards remain one logical reward entry. In JEI, all matching items are shown in one output slot and cycle inside that slot. In the detailed tooltip, the first two matching items and the total number of matching items are shown.
KubeJS
Put loot box definitions in kubejs/server_scripts/lootbox.js so they are re-executed by /reload. Use startup_scripts only for content that must be registered during a complete game restart.
It is recommended to clear the previous scripted definitions before registering them again:
const LootBoxApi = Java.loadClass('net.xuwu.lootbox.LootBoxApi')
LootBoxApi.clearScriptedDefinitions()
LootBoxApi.registerCondition(
'has_vip_tag',
ctx => ctx.hasPlayer() && ctx.player().getTags().contains('vip'),
ctx => 'VIP required'
)
LootBoxApi.registerTranslated(
'example:vip',
'example.lootbox.vip',
1,
LootBoxApi.entries(
LootBoxApi.entry('minecraft:diamond', 1, 2, 10, 2, 'has_vip_tag', ''),
LootBoxApi.entryTag('minecraft:music_discs', 1, 1, 5, 0, '', ''),
LootBoxApi.entryBox('lootbox:rare', 1, 1, 1, 0, '', '')
),
0x00E5FF,
'example.lootbox.vip_jei_info'
)
Data pack and KubeJS mapping
| Data pack | KubeJS | Description |
|---|---|---|
display_name |
register |
Literal box name. |
display_name_key |
registerTranslated |
Translation-key box name. |
item |
entry |
Fixed item reward. |
tag |
entryTag |
Uniform random selection from the tag. |
box |
entryBox |
Another loot box as a reward. |
jei_info_key |
register(..., color, jeiInfoKey) |
Translation key for JEI Info. |
condition.display_key |
entryWithConditionKey, entryTagWithConditionKey, entryBoxWithConditionKey |
Translation key for condition text. |
min, max, weight, luck_weight |
All entry* methods |
Quantity, weight, and luck weight. |
Tags, boxes, and translated conditions can also be combined independently:
LootBoxApi.registerTranslated(
'example:translated',
'example.lootbox.translated',
1,
LootBoxApi.entries(
LootBoxApi.entryTagWithConditionKey(
'minecraft:music_discs', 1, 1, 10, 0, 'has_vip_tag', 'example.condition.vip'
),
LootBoxApi.entryBox('lootbox:endurance', 1, 1, 1, 0, '', '')
),
0x7C4DFF,
'example.lootbox.translated_jei_info'
)
Configuration
All settings are stored in config/lootbox-common.toml. The server's configuration determines the actual gameplay rules:
hide_default_boxes: hides built-in boxes and removes them from the creative inventory and JEI. Defaults tofalse.mob_drops_enabled: enables built-in loot box drops from killed mobs. Defaults totrue.enable_mekanism_rewards,enable_create_rewards,enable_irons_spellbooks_rewards,enable_goety_rewards,enable_ae2_rewards,enable_terra_entity_rewards,enable_twilight_forest_rewards, andenable_aether_rewards: independently enable optional mod integrations. All default totrue.mob_drop_chances: configures the drop chance of the six built-in box tiers. At most one built-in box drops per kill. The checks run in this order: Endurance, Legendary, Epic, Rare, Unusual, Common.
After receiving the server snapshot, clients refresh JEI and the creative inventory using the server's box list and hide settings. A local client configuration is used only as a UI fallback before connecting to a server.
JEI
With JEI installed, each visible loot box shows a recipe entry with its input box and possible rewards:
- Input and output slots use JEI's standard slot backgrounds.
- Tag rewards are condensed into one output slot and cycle through all matching items without splitting the tag entry's total weight.
- Large reward lists are displayed in a scrollable 7×4 reward grid. Drag the scrollbar or use the mouse wheel to browse all rewards.
- Hovering an output shows its quantity, weight, luck weight, final probability at the current luck value, and conditions.
- Rewards whose luck condition is not met show
0.00%consistently in both JEI and tooltips. jei_info_key, or the built-in box acquisition/drop information, is displayed below the JEI entry. Long English text wraps automatically.
Automatic Loot Box Opener
The Automatic Loot Box Opener accepts a loot box in its input slot and sends generated rewards to its output inventory. It can be accessed from the Functional Blocks creative tab or crafted with:
Iron Ingot | Hopper | Iron Ingot
Iron Ingot | Redstone | Iron Ingot
Iron Ingot | Iron Ingot | Iron Ingot
The block requires an iron pickaxe or better to drop itself when mined. If it is destroyed by an invalid tool or by forced block removal, all items currently stored inside it are still dropped.
Multiplayer and Reloading
- Put data packs in the world's
datapacksdirectory and KubeJS definitions in the server'skubejs/server_scriptsdirectory. - Run
/reload. - The server recalculates data pack and KubeJS definitions and sends the final snapshot to every online player.
- Clients automatically refresh JEI, the creative inventory, box names, colors, and reward displays. Players do not need to install or execute the same script separately on each client.
If a new box is not visible, first make sure the server and client use matching mod versions. Then check hide_default_boxes, the KubeJS log, and the server log after /reload. Unknown or removed definitions are displayed safely through the item snapshot and do not crash worlds that already contain those boxes.

