Сборка модов (modpack) на Thunderstore - это небольшой zip-архив из четырёх файлов, в котором нет самих модов: manifest.json со списком dependencies, где указан каждый мод и версия, работающие на вашем сервере, иконка icon.png размером 256 на 256, файл README.md и, по желанию, папка config. Вы загружаете архив под именем своей команды, и после этого каждый игрок устанавливает ваш точный набор одним щелчком в r2modman, Gale или Thunderstore Mod Manager. Подвох кроется в слове "приватная": на Thunderstore нет приватных и скрытых пакетов, поэтому сборка становится публичной сразу после загрузки. Если это важно, делитесь экспортированным файлом профиля. Если нет, опубликованная сборка - самый чистый способ месяцами держать группу на одних и тех же версиях, при условии что вы обновляете её осознанно, а не каждый раз, когда обновился автор очередного мода.
Сборка, код профиля или файл профиля#
Есть три способа передать группе один и тот же набор модов, и решают они немного разные задачи.
| Способ | Где хранится | Срок жизни | Кто видит |
|---|---|---|---|
| Код профиля | Сервис обмена профилями Thunderstore | Временный, коды истекают | Любой, у кого есть код |
Файл профиля (.r2z) | Файл, который вы пересылаете | Постоянный | Те, кому вы его отправили |
| Сборка на Thunderstore | Пакет на thunderstore.io | Постоянный, с версиями | Все |
Код профиля - самый быстрый вариант и правильный выбор для первого вечера. Экспортированный .r2z постоянен и содержит папку config, поэтому это лучший приватный вариант - оба способа разобраны в статье профили r2modman для группы. Дополнительные усилия на сборку оправданы, если верно хотя бы одно из условий:
- Состав группы меняется. Новые игроки приходят через несколько недель, и им не стоит искать файл, закреплённый в канале Discord.
- У вас публичный или полупубличный сервер, и вы хотите дать в описании ссылку, которая всегда ведёт на актуальный набор.
- Вам нужна история версий. Каждая загрузка - это пронумерованная версия, и менеджер сообщает каждому игроку о появлении новой.
- Игроки пользуются разными менеджерами. Пакеты Thunderstore - общий формат, который читают все менеджеры.
Чем сборка не является: способом распространять чужие моды. Сборка зависит от модов, но не содержит их файлов .dll. Правила Thunderstore запрещают повторно загружать чужую работу, и сборку с копиями удалят. Механизм зависимостей существует как раз затем, чтобы вам этого делать не приходилось.
Структура zip-архива#
Загружается один zip-архив, и файлы должны лежать в его корне, а не внутри папки. Архивировать папку вместо её содержимого - самая частая причина отказа при загрузке.
LongshipCrew_Modpack-1.0.0.zip manifest.json icon.png README.md CHANGELOG.md optional, shown on its own tab config/ optional, mod settings for clients com.example.somemod.cfgИмя самого zip-файла для Thunderstore не имеет значения, но если называть его по имени пакета и версии, ваша собственная папка останется читаемой, когда в ней накопится десяток архивов.
Требования, которые Thunderstore проверяет при загрузке:
- `manifest.json` - корректный JSON с полями, описанными в следующем разделе.
- `icon.png` - PNG ровно 256 на 256 пикселей. Не 512 и не переименованный JPEG. Обычный цветной квадрат с инициалами сервера подойдёт: сборки никто не выбирает за красоту картинки.
- `README.md` - отображается как страница пакета. Он может быть коротким, но должен быть.
CHANGELOG.md необязателен. Если он есть, страница пакета показывает его на вкладке Changelog, и это самое полезное, что можно дать игрокам, которые хотят понять, почему менеджер предлагает им обновление.
manifest.json: поле за полем#
Вот весь файл для небольшой групповой сборки:
{ "name": "LongshipCrew_Modpack", "version_number": "1.0.0", "website_url": "", "description": "Mods for the Longship Crew server. Install this, then join.", "dependencies": [ "denikson-BepInExPack_Valheim-5.4.2202", "ValheimModding-Jotunn-2.20.1", "ValheimModding-HookGenPatcher-0.0.4", "RandyKnapp-EpicLoot-0.10.3", "Advize-PlantEverything-1.18.2" ]}Номера версий выше показывают формат, а не являются рекомендацией: настоящие значения копируйте со страницы каждого пакета, как описано ниже.
| Поле | Правило | Примечания |
|---|---|---|
name | Только буквы, цифры и подчёркивание | Без пробелов и дефисов. Входит в URL, и потом его нельзя переименовать |
version_number | Major.Minor.Patch | Три числа. Для каждой загрузки нужна версия, которая ещё не использовалась |
website_url | URL или пустая строка | Поле обязано присутствовать; "" принимается |
description | До 250 символов | Показывается в результатах поиска внутри каждого менеджера |
dependencies | Массив строк зависимостей | Сам список модов |
Ограничение на name многих сбивает с толку, но дефисы запрещены не зря: дефис - разделитель в строках зависимостей. Longship-Crew было бы неоднозначным, а Longship_Crew - нет.
На сайте Thunderstore в разделе Tools есть и валидатор манифеста. Вставьте файл туда до упаковки, и пропущенную запятую вы найдёте раньше, чем форма загрузки.
Строки зависимостей
Каждая запись имеет вид Namespace-PackageName-Version, где namespace - это команда, загрузившая пакет, а не обязательно отображаемое имя автора. Ничего из этого угадывать не нужно: на странице каждого пакета для просматриваемой версии показана готовая к копированию строка зависимости. Если нужна более старая версия, откройте список версий на той же странице.
Нужно учесть три вещи:
- Включите загрузчик и библиотеки.
BepInExPack_Valheimотdenikson- это сборка BepInEx для Valheim, и она должна быть в каждой сборке. Библиотеки вроде Jotunn и HookGenPatcher подтягиваются как зависимости модов, которым они нужны, но явное перечисление фиксирует и их версии, а именно это не даёт обновлению библиотеки тихо сломать весь набор. - Одна запись на пакет. Две версии одного мода в списке - ошибка в ожидании, а некоторые менеджеры установят ту, которая встретится последней.
- Не добавляйте то, что сервер запрещает. Если сервер не использует клиентский мод, меняющий правила (изменение переносимого веса, размера стопок), не кладите его в сборку. Игрок, у которого он есть, подключится к серверу без него и окажется не в ногу со всеми остальными.
Публикация на thunderstore.io#
Вам понадобятся аккаунт и команда. Войдите на thunderstore.io (доступен вход через Discord, GitHub и Overwolf), откройте настройки и создайте команду. Имя команды - это namespace, который стоит перед именем пакета в каждой строке зависимости, и, как и имя пакета, оно по сути постоянное, поэтому выберите то, за что вам не будет стыдно через год. Обычно это название сервера.
Дальше:
- Откройте страницу загрузки в меню сайта и выберите zip-файл.
- Выберите сообщество Valheim. Загрузить не туда проще, чем кажется, потому что форма запоминает прошлый выбор.
- Выберите категорию Modpacks и другие категории, которые честно описывают содержимое.
- Отметьте флажок NSFW, только если он применим, и отправьте форму.
Если форма отклонила загрузку, в сообщении будет названа проблема: размеры иконки, поле манифеста, уже существующая версия. Исправьте и загрузите снова. После принятия пакет появляется в списке Valheim и в поиске каждого менеджера, обычно в течение нескольких минут.
Считайте каждую опубликованную версию постоянной. Загруженную версию нельзя незаметно отредактировать, и на удаление рассчитывать не стоит: исправление сломанного релиза - это новая версия с большим номером. Это и достоинство, и ограничение: игрок, импортировавший 1.2.0 в марте, всегда может найти, что именно в ней было.
Тем, кто публикует часто, Thunderstore предлагает консольный инструмент tcli: он собирает zip из папки проекта и загружает его с помощью токена, созданного в настройках команды. Для сборки, которая обновляется раз в месяц, это избыточно, а формат его конфигурации менялся между релизами, поэтому, если пойдёте этим путём, читайте его собственный README, а не скопированный откуда-то пример.
Файлы конфигурации в сборке#
Сборка может нести не только моды, но и настройки. Файлы из папки config верхнего уровня zip-архива копируются r2modman и построенными на нём менеджерами в BepInEx/config профиля при установке сборки. Так вы добиваетесь того, что интерфейсные моды, значения по умолчанию без привязок клавиш и клиентские значения у всех одинаковы с первого запуска.
Что туда стоит класть, а что нет:
- Клиентские настройки, которые должны быть общими. Значения по умолчанию для меток на карте, согласованная раскладка горячих клавиш, мод для удобства, настроенный так, как решила группа.
- Не настройки, синхронизируемые с сервера. Если мод передаёт свою конфигурацию с сервера (так делает большинство модов на ServerSync или на админской синхронизации Jotunn), клиентская копия перезаписывается при подключении. Класть такой файл безвредно, но бессмысленно, и он вводит в заблуждение тех, кто правит его и ждёт изменений. Какая сторона побеждает, объясняет статья как работают ServerSync и принудительная синхронизация конфигов.
- Не BepInEx.cfg, если нет особой причины. Собственные настройки загрузчика лучше оставить у клиентов такими, какие заданы по умолчанию в сборке.
Проверьте, что делает ваш менеджер при обновлении. В некоторых версиях файлы конфигурации из сборки заменяются при каждом обновлении, и личные изменения игрока сбрасываются, в других существующие файлы не трогаются. Установите сборку в свежий профиль, измените настройку, обновите сборку и посмотрите. Если игроки теряют личные настройки, оставьте в поставляемой конфигурации только те несколько файлов, которые действительно должны совпадать.
Тот же набор на выделенном сервере#
Ни один менеджер не устанавливает сборку на сервер. Серверу нужны те же плагины в BepInEx/plugins, и доставлять их туда придётся вручную. Надёжный способ использует профиль как источник:
- Импортируйте собственную сборку в чистый профиль на своём ПК. Так вы убедитесь, что опубликованная сборка разрешается, и получите точные файлы.
- В настройках менеджера воспользуйтесь пунктом открытия папки профиля. В r2modman она находится в
%AppData%\r2modmanPlus-local\Valheim\profiles\<profile name>в Windows. - Скопируйте
BepInEx/pluginsиз профиля вBepInEx/pluginsсервера, пропустив чисто клиентские моды. - Скопируйте и содержимое
BepInEx/patchers. HookGenPatcher лежит там, а не вplugins. - Запустите сервер один раз, остановите и отредактируйте созданные конфиги в
BepInEx/configсервера. - Запустите снова и сравните строки о плагинах в логе с вашим манифестом.
$ grep -o 'Loading \[[^]]*\]' BepInEx/LogOutput.log | sortLoading [EpicLoot 0.10.3]Loading [Jotunn 2.20.1]Loading [PlantEverything 1.18.2]Сам BepInExPack тоже ставится на сервер, но из собственной загрузки, распакованной в корень сервера, как описано в статье моды Valheim с BepInEx на сервере, а не по частям из клиентского профиля. На сервере Valheim от RE:NODE загрузка делается через файловый менеджер или SFTP: перетащите папку plugins или загрузите zip и распакуйте его на месте, а консоль в реальном времени покажет баннер BepInEx и каждую строку Loading при запуске сервера.
Чисто клиентские моды лучше не ставить на сервер, даже если они загрузятся. Большинство безвредны в безголовом процессе, но некоторые при старте обращаются к интерфейсу и выбрасывают исключения, а каждый лишний плагин - это ещё одна строка, которую придётся читать, когда что-то действительно сломается. Если вы не уверены, к какой стороне относится мод, об этом сказано на странице автора, а как выглядит клиентский мод, отказавший на сервере, показывает руководство по логам BepInEx.
Обновление сборки при изменении модов#
Сборка полезна, только пока совпадает с сервером, а совпадать она перестаёт в тот день, когда кто-то обновил одну сторону и не обновил другую. Проверенный порядок действий:
- Решайте обновляться сами, а не следуйте за авторами. Новый релиз Epic Loot - не повод менять сборку во вторник вечером. Собирайте изменения в пакеты и вносите их до игровой сессии, а не во время неё.
- Сделайте backup папки `BepInEx` сервера и мира. Блокируемый backup последнего рабочего состояния - то, что вы восстановите, если новый набор будет вести себя плохо. Довод в пользу его проверки - в статье backup, который действительно восстанавливается.
- Сначала обновите тестовый профиль. Смените версии в копии профиля, запустите игру, при крупных изменениях загрузите копию мира локально и убедитесь, что всё стартует чисто.
- Увеличьте номер версии. Patch - при обновлении одного мода, minor - при добавлении или удалении мода, major - при изменении, которому нужен новый мир или которое ломает сохранения.
- Напишите строку в changelog. По одной строке на изменение, с причиной.
- Загрузите, затем обновите сервер, затем сообщите группе. Именно в таком порядке и в течение одного часа. Промежуток между изменением сервера и обновлением у игроков - то самое время, когда людей выкидывает из-за несовпадения.
## 1.3.0- Added PlantEverything (agreed in Discord, 12 Oct)- Jotunn 2.20.1, required by the new Epic Loot## 1.2.1- Epic Loot 0.10.3 - fixes the enchanting table crashПосле патча Valheim порядок другой: обновление игры ломает моды, пока их авторы не догонят, поэтому сборка ждёт авторов, а сервер ждёт сборку. Общая процедура описана в статье что делать, когда обновление мода всё ломает, а сообщения, которые видят игроки при расхождении сторон, разобраны в статье выкидывает из-за несовпадения версий модов.
Неполадки при загрузке и установке#
"Manifest is invalid" или ошибка поля при загрузке. Обычно это дефис или пробел в name, версия из двух частей вроде 1.0, отсутствующий website_url или запятая после последней зависимости. Прогоните файл через валидатор.
"Icon must be 256x256". Ровно такой размер и формат PNG. Экспортируйте заново, а не переименовывайте файл другого формата.
Загрузка сообщает, что в пакете нет манифеста. Файлы лежат внутри папки в архиве. Откройте архив: manifest.json должен быть сразу в корне, а не в каталоге.
"Version already exists". Вы загрузили повторно, не изменив version_number. Увеличьте его, даже если правите в README один символ.
Игроки импортировали сборку, а какого-то мода нет. В строке зависимости опечатка в namespace или версия, которая никогда не публиковалась. Каждую строку нужно копировать со страницы пакета, а не набирать вручную.
Сборка установлена, но игроков всё равно выкидывает при подключении. Сервер не совпадает со сборкой. Сравните строки Loading сервера с манифестом; различие и есть ответ. Обычная причина - библиотека, обновлённая на сервере вручную.
Настройки игроков сбрасываются после каждого обновления сборки. Сборка содержит файлы конфигурации, которые менеджер перезаписывает. Сократите папку config до файлов, которые обязаны совпадать.
FAQ#
Можно ли сделать сборку на Thunderstore приватной?
Нет. На Thunderstore нет приватных или скрытых пакетов; всё загруженное видно всем. Для закрытой группы экспортируйте профиль r2modman как файл .r2z и передайте его напрямую. В нём тот же список модов и конфиги.
Нужно ли разрешение, чтобы включить чужой мод в свою сборку?
Чтобы зависеть от него - нет. Сборка перечисляет моды строками зависимостей, и каждый игрок скачивает их из пакета самого автора, так Thunderstore и задумывает работу сборок. Копировать файлы автора в свой zip - совсем другое дело, и это запрещено.
Получат ли игроки мои обновления автоматически?
Менеджер показывает, что есть более новая версия сборки, и предлагает обновить её. Большинство не применяют обновление без щелчка игрока, поэтому короткое объявление в чате группы в день обновления избавляет от череды выкидываний.
Устанавливает ли сборка BepInEx на сервер?
Нет. Сборки устанавливаются менеджерами модов в клиентские профили. Серверу нужен BepInExPack, распакованный в его корень, и те же плагины, скопированные в BepInEx/plugins вручную через SFTP или файловый менеджер.
Можно ли пустить игроков с Xbox на сервер, использующий мою сборку?
Только если каждый мод в сборке необязателен для клиентов. Консольные игроки не могут устанавливать моды, поэтому сборка из модов, нужных и клиенту, и серверу, делает сервер доступным только с ПК, независимо от настройки кроссплея.
Что если мод из моей сборки признан устаревшим или удалён?
Старые версии обычно остаются доступными для скачивания, так что существующие установки продолжают работать, но строить на нём не стоит. Найдите замену, проверьте её на копии мира и опубликуйте новую версию сборки, в которой мод заменён.


