Перейти к содержанию

Свиток в сундуке

Игрок находит в сундуке свиток — ПКМ запускает квест. Паттерн описывает два сценария: кастомный сундук в постройке карты и встраивание в ванильную структуру через переопределение лут-таблицы.


Зачем нужен этот паттерн

  • Органичная подача. Квест появляется как находка, а не как системное сообщение. Свиток в сундуке вписывается в исследование без видимого «интерфейса».
  • Без дополнительного кода. Достаточно датапака: лут-таблица и JSON квеста, никаких Fabric-хуков.
  • Любой сундук. Кастомная постройка, ванильный данж, крепость, деревня — подход один и тот же.
  • Контроль редкости. Поля weight и rolls регулируют, насколько редкой будет находка.

Как это работает в одном предложении

Лут-таблица содержит запись inkquest:quest_scroll с функцией minecraft:set_nbt, которая записывает идентификатор квеста в NBT-поле Quest. При открытии сундука Minecraft разыгрывает лут — свиток с нужным квестом попадает в инвентарь.


Шаг 1. Создаём квест

data/story/quests/catacomb_note.json:

{
  "version": 3,
  "variant": 0,
  "title": "Послание из катакомб",
  "description": "Свёрнутый лист в сундуке. «Нижний ярус. Третья колонна слева. Там кое-что есть. — Д.»",
  "tasks": {},
  "stages": []
}

Это квест-заметка без задач — она просто появится в книге как находка. Как добавить задачи и нарративную структуру — в Квест-заметка и Цепочка квестов.


Шаг 2. Создаём лут-таблицу для сундука

data/story/loot_tables/chests/catacomb.json:

{
  "type": "minecraft:chest",
  "pools": [
    {
      "rolls": 1,
      "bonus_rolls": 0.0,
      "entries": [
        {
          "type": "minecraft:item",
          "name": "inkquest:quest_scroll",
          "functions": [
            {
              "function": "minecraft:set_nbt",
              "tag": "{Quest:'story:catacomb_note'}"
            }
          ]
        }
      ]
    }
  ]
}
  • rolls: 1 — пул разыгрывается один раз, свиток гарантирован.
  • minecraft:set_nbt — записывает произвольный NBT в создаваемый предмет.
  • tag — строка в формате SNBT. Идентификатор story:catacomb_note должен совпадать с именем файла из шага 1 (namespace story, path catacomb_note).

Шаг 3. Назначаем лут-таблицу сундуку

Помести сундук в нужное место, затем выполни команду (замени координаты):

/data merge block 10 64 -30 {LootTable:"story:chests/catacomb"}

story:chests/catacomb — идентификатор лут-таблицы из шага 2: namespace story, путь chests/catacomb (файл data/story/loot_tables/chests/catacomb.json).

⚠️ Лут-таблица применяется к сундуку ровно один раз — при первом открытии тег LootTable исчезает. Если нужно назначать её автоматически при каждой загрузке датапака — см. расширение «Автоназначение при загрузке датапака».


Проверка

  1. Открой сундук с назначенной лут-таблицей.
  2. В инвентарь попадает предмет inkquest:quest_scroll. ✅
  3. ПКМ по свитку вне сундука — квест «Послание из катакомб» появляется в книге. ✅
  4. Клавиша J → раздел «Активные» — квест виден. ✅

Если свиток не появился: - Сундук уже открывали? При повторном открытии лута не будет — поставь новый сундук и назначь таблицу заново. - /datapack list — убедись, что датапак активен. - Путь к файлу должен быть data/story/loot_tables/chests/catacomb.json.

Если свиток появился, но ПКМ не выдаёт квест: - ID в tag и путь к JSON квеста не совпадают. - Файл data/story/quests/catacomb_note.json отсутствует или датапак с квестом не загружен.


Расширения

Встроить в ванильную структуру

Чтобы свиток появлялся в сундуках ванильного данжа, крепости или корабля — положи свой файл по пути, совпадающему с ванильным, но в namespace minecraft:

Структура Путь к файлу
Данж data/minecraft/loot_tables/chests/simple_dungeon.json
Крепость, библиотека data/minecraft/loot_tables/chests/stronghold_library.json
Крепость, кладовая data/minecraft/loot_tables/chests/stronghold_crossing.json
Корабль, сокровища data/minecraft/loot_tables/chests/shipwreck_treasure.json
Аванпост разбойников data/minecraft/loot_tables/chests/pillager_outpost.json

Скопируй полное содержимое нужной ванильной таблицы (доступны на Minecraft Wiki или извлеки из JAR-файла) и добавь в конец массива pools новый пул:

{
  "bonus_rolls": 0.0,
  "rolls": 1,
  "entries": [
    {
      "type": "minecraft:item",
      "name": "inkquest:quest_scroll",
      "functions": [
        {
          "function": "minecraft:set_nbt",
          "tag": "{Quest:'story:catacomb_note'}"
        }
      ]
    }
  ]
}

Не трогай уже существующие пулы — они отвечают за остальной лут структуры.

⚠️ Если два датапака оба переопределяют одну и ту же ванильную таблицу, работает только один — последний по порядку в /datapack list. Ошибок нет, но лут одного из датапаков молча игнорируется.

Случайный шанс появления

Чтобы свиток выпадал не всегда, добавь в пул запись minecraft:empty с большим весом:

{
  "bonus_rolls": 0.0,
  "rolls": 1,
  "entries": [
    {
      "type": "minecraft:item",
      "name": "inkquest:quest_scroll",
      "weight": 1,
      "functions": [
        {
          "function": "minecraft:set_nbt",
          "tag": "{Quest:'story:catacomb_note'}"
        }
      ]
    },
    {
      "type": "minecraft:empty",
      "weight": 9
    }
  ]
}

Соотношение 1:9 даёт ~10% шанс. Меняй веса под нужную редкость.

Несколько разных квестов в одном пуле

Если один тип сундуков может содержать один из нескольких квестов — добавь несколько записей в пул:

{
  "bonus_rolls": 0.0,
  "rolls": 1,
  "entries": [
    {
      "type": "minecraft:item",
      "name": "inkquest:quest_scroll",
      "weight": 3,
      "functions": [
        {
          "function": "minecraft:set_nbt",
          "tag": "{Quest:'story:catacomb_note'}"
        }
      ]
    },
    {
      "type": "minecraft:item",
      "name": "inkquest:quest_scroll",
      "weight": 1,
      "functions": [
        {
          "function": "minecraft:set_nbt",
          "tag": "{Quest:'story:lost_expedition'}"
        }
      ]
    }
  ]
}

Minecraft выберет один из двух квестов случайно с учётом весов. Свитки с разными квестами не объединяются в один стак.

Свиток плюс случайные предметы

Чтобы сундук всегда содержал свиток и несколько случайных предметов — раздели лут на два пула. Первый пул гарантирует свиток, второй разыгрывает предметы независимо:

data/story/loot_tables/chests/catacomb.json:

{
  "type": "minecraft:chest",
  "pools": [
    {
      "rolls": 1,
      "bonus_rolls": 0.0,
      "entries": [
        {
          "type": "minecraft:item",
          "name": "inkquest:quest_scroll",
          "functions": [
            {
              "function": "minecraft:set_nbt",
              "tag": "{Quest:'story:catacomb_note'}"
            }
          ]
        }
      ]
    },
    {
      "rolls": {
        "type": "minecraft:uniform",
        "min": 2.0,
        "max": 5.0
      },
      "bonus_rolls": 0.0,
      "entries": [
        {
          "type": "minecraft:item",
          "name": "minecraft:gold_ingot",
          "weight": 5
        },
        {
          "type": "minecraft:item",
          "name": "minecraft:iron_ingot",
          "weight": 10,
          "functions": [
            {
              "function": "minecraft:set_count",
              "add": false,
              "count": {
                "type": "minecraft:uniform",
                "min": 1.0,
                "max": 4.0
              }
            }
          ]
        },
        {
          "type": "minecraft:item",
          "name": "minecraft:bread",
          "weight": 15
        }
      ]
    }
  ]
}

Автоназначение при загрузке датапака

Вместо ручного /data merge block можно назначать таблицы сундукам автоматически при каждом /reload. Подходит, если сундуки стоят в фиксированных координатах.

data/minecraft/tags/functions/load.json:

{
  "values": ["story:setup_chests"]
}

data/story/functions/setup_chests.mcfunction:

data merge block 10 64 -30 {LootTable:"story:chests/catacomb"}
data merge block 45 12 -88 {LootTable:"story:chests/catacomb"}

Функция запускается при каждом /reload.

⚠️ Это перезаписывает тег LootTable при каждом /reload, даже у сундуков, которые уже открывали. Следующее открытие после /reload разыграет лут заново — предметы, которые игрок оставил в сундуке, исчезнут. Не используй для сундуков-хранилищ.


Подводные камни

  • Лут-таблица применяется ровно один раз. Minecraft удаляет тег LootTable из NBT сундука при первом открытии. Если ты назначил таблицу уже открытому сундуку — при следующем открытии он будет пустым. Всегда тестируй на свежем, ещё не открытом сундуке.

  • Свиток без квеста показывает ошибку. Если квест с ID из поля Quest не загружен, при ПКМ игрок получит сообщение об ошибке на action-bar, а свиток останется в руке. Проверь: файл квеста существует, датапак с ним активен.

  • Переопределение ванильной таблицы — полная замена. Датапак не добавляет пул к ванильной таблице, а заменяет её целиком. Если скопировать только свой пул, из сундука исчезнут все ванильные предметы. Всегда копируй оригинал полностью.

  • random_sequence отвечает за воспроизводимость лута. Ванильные лут-таблицы структур содержат поле random_sequence, которое привязывает лут к world seed'у: один и тот же данж при одном seed'е всегда даёт одинаковый лут. Если убрать это поле из своей версии таблицы — лут станет полностью случайным при каждом открытии. При переопределении ванильных таблиц сохраняй это поле без изменений.

  • Конфликт двух датапаков — молчаливый. Если два датапака кладут файл по одному пути (например, data/minecraft/loot_tables/chests/simple_dungeon.json), работает только последний по порядку в /datapack list. Никаких ошибок в логе не будет — об этом легко не узнать.

  • Стаки свитков на один квест объединяются. Если игрок найдёт два свитка на квест story:catacomb_note, они сложатся в стак. При использовании второго свитка мод выдаст сообщение «уже активен» или «уже завершён», а свиток не израсходуется. Это штатное поведение; максимум стака — 16.


См. также

  • Квест-заметка — как оформить квест, который появляется в книге как находка без задач
  • Цепочка квестов — если свиток запускает первое звено серии квестов
  • Предметы — полная спецификация inkquest:quest_scroll, синтаксис NBT в командах и геймрул doQuestBookItemCheck
  • Выдача квестов новому игроку — если квест нужно выдать автоматически при первом входе, а не через сундук