Пулы разыгрываются независимо
Loot-таблица содержит список пулов, и каждый обрабатывается отдельно. Это самое полезное, что о них стоит знать, потому что именно так выражается «всегда одно оружие, плюс два-три случайных припаса, плюс редкий шанс на что-то особенное» — три пула, а не один хитрый список.
Внутри пула rolls задаёт, сколько раз выбирать. Это может быть фиксированное число или диапазон:
"rolls": 1
"rolls": { "type": "minecraft:uniform", "min": 2, "max": 4 }
Каждый ролл выбирает ровно одну запись из списка этого пула. Четыре ролла по пулу из трёх предметов вполне могут выдать один и тот же предмет четыре раза — роллы независимы, это не раздача карт без возврата.
Вес — это доля, а не процент
Именно здесь ошибается большинство. Вес — это не шанс из 100. Это доля от суммы всех весов в пуле.
iron_ingot вес 10
gold_ingot вес 5
diamond вес 1
Сумма равна 16, значит железо выпадает 10/16 раз — примерно 62%, а не 10%. Добавьте четвёртую запись с весом 84, и железо упадёт до 10/100, хотя вы не трогали его число. Каждый вес в пуле относителен соседним, поэтому добавление одной записи молча переоценивает всё остальное в этом пуле.
Если нужен настоящий процент — это другой механизм: условие random_chance на записи.
"conditions": [
{ "condition": "minecraft:random_chance", "chance": 0.15 }
]
Вот это честные 15%, вычисляемые независимо от веса. Сочетаются они так, что стоит быть внимательным: запись сначала должна выиграть взвешенный выбор, и только потом сработает бросок на 15%.
Количество — отдельный шаг от выбора
Выбор того, какой предмет выпадет, и выбор того, сколько их будет, — разные операции. Размер стака задаёт функция, применяемая уже после выбора записи:
{
"type": "minecraft:item",
"name": "minecraft:iron_ingot",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": { "type": "minecraft:uniform", "min": 1, "max": 4 }
}
]
}
Без set_count вы получите ровно одну штуку. Объект под count — это number provider, та же конструкция, что используется в rolls. Разобравшись один раз, вы закрываете оба случая.
Тип таблицы — это контракт, а не подпись
type в начале файла объявляет, в каком контексте таблица разыгрывается, и игра держит вас за слово. У таблицы minecraft:chest нет ни убийцы, ни жертвы, поэтому условие, спрашивающее про погибшее существо, там не просто бесполезно — оно делает таблицу невалидной для этого контекста.
| Тип | Когда разыгрывается |
|---|---|
minecraft:chest | Генерируется сундук в структуре или вызвана /loot |
minecraft:entity | Погибает моб |
minecraft:block | Ломается блок |
minecraft:fishing | Что-то поймано на удочку |
minecraft:gift | Житель или кот приносит подарок |
Если таблица ведёт себя правильно на тестах, но в мире не срабатывает никогда, проверьте, совпадает ли её тип с тем, как её реально вызывают.
Проверка без беготни за сундуком
Не нужно искать настоящее подземелье, чтобы увидеть свои шансы. Команда /loot разыгрывает существующую таблицу по требованию:
/loot give @s loot harbor:harbor_dungeon
Стоит проговорить явно, потому что название сбивает с толку: /loot читает таблицу, а не создаёт её. Команды, которая записывает loot-таблицу, не существует — файл сначала должен появиться в датапаке. Если вы его ещё не собрали, статья датапаки против команд объясняет почему, а генератор датапаков сделает папку.
Запустите её двадцать раз подряд — и распределение станет видно сразу. Это же самый быстрый способ поймать неправильно выставленный вес.
Когда таблицу просто никогда не читают
Две поломки выглядят изнутри игры одинаково и к вашему JSON отношения не имеют.
Первая — папка. В Minecraft 1.21 loot_tables переименовали в loot_table, в единственном числе. На 1.21+ файл в старой папке не загружается никогда, и ничего вас не предупредит — пак по-прежнему числится включённым.
Вторая — ID. Файл по пути data/harbor/loot_table/harbor_dungeon.json адресуется как harbor:harbor_dungeon. Пространство имён берётся из папки внутри data, а не из имени файла, и расхождение здесь даст ошибку «unknown loot table», а не тишину — что по сравнению с первым случаем даже милосердно.
Куда идти дальше
Генератор loot-таблиц собирает эти структуры с уже правильными number provider и показывает путь, по которому файл должен лежать. Про контейнер для него — генератор датапаков; чтобы предметы на выходе были интереснее, конструктор предметов закрывает имена, лор и скрытые ID.