← Все статьи

Как на самом деле разыгрываются loot-таблицы Minecraft

Большинство loot-таблиц, которые «не работают», структурно в полном порядке. Просто шансы в них не те, что задумывал автор, — потому что вес означает не то, чем кажется. Здесь разобрано, как таблица реально вычисляется, в том же порядке, в каком это делает игра.

Открыть генератор loot-таблиц

Пулы разыгрываются независимо

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.