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.
/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.
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
}
]
}
| 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. |
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 is weight + player luck × luck_weight.condition: {"type":"luck","min":2}: requires the player's luck to be at least 2.condition.display_key or condition.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.
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 | 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'
)
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 to false.mob_drops_enabled: enables built-in loot box drops from killed mobs. Defaults to true.enable_mekanism_rewards, enable_create_rewards, enable_irons_spellbooks_rewards, enable_goety_rewards, enable_ae2_rewards, enable_terra_entity_rewards, enable_twilight_forest_rewards, and enable_aether_rewards: independently enable optional mod integrations. All default to true.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.
With JEI installed, each visible loot box shows a recipe entry with its input box and possible rewards:
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.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.
datapacks directory and KubeJS definitions in the server's kubejs/server_scripts directory./reload.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.