RE:NODE

Spawn That, Drop That и Custom Raids на сервере Valheim

Автор Команда RE:NODE
12 мин чтения


Spawn That, Drop That и Custom Raids, все от ASharpPen, - три мода на основе конфигов, которые переписывают то, что спавнит Valheim, что выпадает из объектов и какие рейды нападают на вашу базу. Работают они одинаково: обычные файлы .cfg в BepInEx/config с одним [Section] на запись, нумерованные записи, переопределяющие ваниль при совпадении номера, дополнительные файлы с вашими именами и отладочные переключатели, выгружающие ванильные таблицы, чтобы вы начинали с реальных данных. Все три нужно ставить на сервер и каждый клиент. Клиенты при подключении игнорируют свои файлы и используют копию, присланную сервером, поэтому значение имеют только файлы сервера. Большинство сообщений "не работает" сводится к трём вещам: правка не той копии, отсутствие перезапуска или условия, которые никогда не могут выполниться одновременно.

В руководстве разбираем, как Valheim решает, что спавнить, что выпадает и какие бывают рейды, файлы каждого мода, отладочные выгрузки, рабочие примеры, безопасную проверку изменений и ошибки, из-за которых рейд объявлен, но пуст.

Как работают спавны, выпадения и рейды в Valheim#

Нужно знать ванильную модель, чтобы настраивать эти моды, потому что они изменяют системы ванили, а не заменяют их.

  • Мировые спавнеры - фоновые правила появления: список шаблонов на биом, где указано, какое существо, сколько максимум поблизости, как часто проверять, днём или ночью, при какой погоде, как далеко от центра мира. Документация Spawn That насчитывает 44 шаблона по умолчанию.
  • Локальные спавнеры - невидимые точки появления внутри локаций и комнат подземелий: скелеты в разрушенной башне, кабаны у своего рунического камня. Каждый управляет одним существом и только по одному за раз.
  • Области спавна - спавнеры вроде гнёзд Грейдвёрфов, которые порождают существ из списка вокруг себя.
  • CharacterDrop - как существа роняют добычу: каждая запись бросает свой шанс и количество независимо.
  • DropTable - как выпадает большинство не-существ: деревья, камни, сундуки и несколько существ вроде птиц. Таблица бросает, сколько выборов сделать, затем выбирает записи по весу.
  • Рейды - события. Сервер время от времени проверяет, начинать ли рейд, выбирает из рейдов, условия которых выполнены, и сообщает клиентам начать.

Деталь, объясняющая большую часть поведения сервера: спавн происходит на клиенте, владеющем зоной. Сервер решает, что рейд начался, но игрок, чья игра симулирует область, запускает спавнеры. Поэтому эти моды должны быть на каждом клиенте, и поэтому игра одного игрока решает, что появится возле него. Ванильная логика рейдов подробнее описана в статье о рейдах и событиях на серверах.

Установка трёх модов и как работает синхронизация конфигов#

Каждый зависит только от BepInExPack. Устанавливайте их как любой плагин BepInEx - полный путь описан в статье о модах Valheim с BepInEx на сервере - на сервер и на ПК каждого игрока в одинаковых версиях. Общий профиль менеджера модов - простой способ держать группу в согласии; об этом r2modman для групп.

МодОсновные файлыДополнительные файлы, которые вы добавляете
Spawn Thatspawn_that.cfg, spawn_that.world_spawners_advanced.cfg, spawn_that.local_spawners_advanced.cfg, spawn_that.simple.cfgspawn_that.world_spawners.*.cfg, spawn_that.local_spawners.*.cfg
Drop Thatdrop_that.cfg, drop_that.character_drop.cfg, drop_that.drop_table.cfgdrop_that.character_drop.*.cfg, drop_that.drop_table.*.cfg
Custom Raidscustom_raids.cfg, custom_raids.raids.cfgcustom_raids.supplemental.*.cfg

Первый файл в каждой строке - общий конфиг: отладочные переключатели и глобальное поведение. Остальные содержат ваши записи. Большинство из них изначально пусты - вы заполняете только то, что хотите изменить.

Правила синхронизации из документации самих модов:

  • Клиенты, подключающиеся к серверу, не используют свои локальные конфиги. Они получают конфиги сервера в памяти, не трогая свои файлы, так что игрок может держать другую настройку для одиночной игры.
  • Конфиги загружаются при входе в мир. На выделенном сервере это момент запуска сервера, поэтому перезапускайте сервер после правок, а затем пусть игроки переподключатся.
  • Дополнительные файлы объединяются с основным. Когда две записи пересекаются, побеждает загруженная позже. Spawn That и Drop That загружают основной файл последним, так что за ним всегда последнее слово. Custom Raids также ищет свои дополнительные файлы в подпапках.

На RE:NODE это текстовые файлы, которые вы редактируете в файловом менеджере в браузере с подсветкой синтаксиса или по SFTP; перезапускайте из консоли и следите за выводом BepInEx там же на предмет предупреждений. Ничего не устанавливается за вас - вы загружаете моды сами - и списка разрешённых модов нет.

Выгрузите ванильные таблицы, прежде чем что-то менять#

Каждый из этих модов может записать собственные таблицы игры в том же формате, что и его конфиг. Начинайте с этого. Вы узнаете реальные имена prefab, существующие номера записей для переопределения и значения, которые использует ваниль.

spawn_that.cfg
[WorldSpawner]WriteSpawnTablesToFileBeforeChanges = true[LocalSpawner]WriteSpawnTablesToFileBeforeChanges = true[Datamining]WriteLocationsToFile = true
drop_that.cfg
[Debug]WriteCharacterDropsToFile = trueWriteDropTablesToFiles = true
custom_raids.cfg
[Debug]WriteDefaultEventDataToDisk = trueWriteGlobalKeyDataToDisk = true

Результат попадает в папку, заданную DebugFileFolder, по умолчанию Debug относительно папки BepInEx - то есть BepInEx/Debug. Потом выключите переключатели снова. Проще всего создавать выгрузки в одиночном мире на своём ПК с теми же модами, потому что файлы появляются на этой машине и их можно читать в редакторе. Выгрузки также показывают имена локаций, нужные для локальных спавнеров, и глобальные ключи, которые проверяют рейды, например defeated_bonemass.

Spawn That: мировые и локальные спавнеры#

Запись мирового спавнера - [WorldSpawner.ID]. Если ID совпадает с одним из шаблонов по умолчанию (от 0 до 43 в текущей документации), она изменяет этот шаблон; любой неиспользуемый ID добавляет новый. Этот пример добавляет охотящихся волков в Тёмный лес после Бонемасса, ночью, группами:

spawn_that.world_spawners_advanced.cfg
[WorldSpawner.200]Name = Night wolvesPrefabName = WolfBiomes = BlackForestHuntPlayer = trueMaxSpawned = 3SpawnInterval = 300SpawnChance = 20GroupSizeMin = 2GroupSizeMax = 3LevelMin = 1LevelMax = 2SpawnDuringDay = falseSpawnDuringNight = trueRequiredGlobalKey = defeated_bonemassConditionDistanceToCenterMin = 1500
ОпцияПо умолчаниюПримечания
MaxSpawned1Предел для этого существа в локальной области, а не во всём мире
SpawnInterval90Секунды между проверками
SpawnChance100Процент за проверку
LevelMin / LevelMax1 / 1Уровень 2 - это одна звезда
LevelUpChance10Процент, бросается заново за каждый полученный уровень
GroupSizeMin / GroupSizeMax1 / 1Появляются вместе
RequiredGlobalKeyпустоСпавнится только когда этот ключ установлен
ConditionAreaSpawnChance100Бросается один раз на область биома, так что в некоторых лесах этого не будет никогда

Enabled = false у существующего шаблона останавливает ванильную версию, так спавн и убирают. Заметьте, что SpawnDuringDay = false также заставляет существ из этого шаблона пытаться исчезнуть при дневном свете. Общий раздел [WorldSpawner] в том же файле принимает DisableSpawnLimiter = true, отключающий ванильное ограничение спавна; документация называет его возможно временным, и это быстрый способ затопить зону, если ваши числа велики.

Локальные спавнеры используют [Location.PrefabName] или [DungeonRoom.PrefabName] и могут изменять только уже существующие спавнеры. Каждое сочетание должно быть уникальным:

spawn_that.local_spawners_advanced.cfg
[Runestone_Boars.Boar]PrefabName = BoarLevelMin = 1LevelMax = 3LevelUpChance = 25RespawnTime = 20

RespawnTime для локальных спавнеров задаётся в минутах, а SpawnInterval для мировых - в секундах. Если несколько спавнеров делят локацию и prefab, шаблон получают все - Spawn That не умеет их различать.

Spawn That добавляет консольные команды для проверки работы: spawnthat wheredoesitspawn 200 записывает PNG-карту того, где может спавниться шаблон 200, spawnthat area выводит ID области, в которой вы стоите, а spawnthat room сообщает, в какой комнате подземелья вы находитесь, что удобно для поиска имён комнат. Если установлен Creature Level and Loot Control, он берёт управление уровнями на себя, пока вы не зададите UseDefaultLevels = true в подразделе [WorldSpawner.200.CreatureLevelAndLootControl]; эту интеграцию разбирает статья о Creature Level and Loot Control.

Drop That: выпадения существ и таблицы выпадений#

Выпадения существ записываются в drop_that.character_drop.cfg как [PrefabName] для настроек всего существа и [PrefabName.ID] для каждого выпадения. Как и со спавнерами, совпадающий ID переопределяет ванильную запись, а новый добавляет выпадение.

drop_that.character_drop.cfg
[Draugr.10]PrefabName = IronScrapAmountMin = 1AmountMax = 2ChanceToDrop = 25ScaleByLevel = falseConditionKilledByEntityType = Player[Troll.0]Enable = false

Первая запись даёт Драугру 25% шанс выронить один-два железных лома, без умножения на уровень звёзд, и только когда убивает игрок. Вторая отключает первое ванильное выпадение тролля. ChanceToDrop - процент от 0 до 100 в текущих версиях. Старые конфиги использовали имена вроде SetAmountMin и SetChanceToDrop; Drop That всё ещё их читает, но в новых файлах следует использовать текущие имена. Другие полезные опции выпадений - DropOnePerPlayer, AmountLimit и условия вроде ConditionBiomes, ConditionGlobalKeys, ConditionMinLevel и ConditionKilledWithStatus.

Таблицы выпадений работают иначе, и конфиг это показывает. Раздел [EntityName] должен задавать собственные правила таблицы, а затем у записей есть Weight:

drop_that.drop_table.cfg
[TreasureChest_forestcrypt]DropChance = 100DropOnlyOnce = trueDropMin = 3DropMax = 6[TreasureChest_forestcrypt.8]PrefabName = SurtlingCoreWeight = 0.5AmountMin = 1AmountMax = 2

Поскольку записи выбираются по весу, добавление тяжёлой записи делает всё остальное в таблице реже. DropOnlyOnce убирает запись после выбора, это и держит сундуки разнообразными.

В drop_that.cfg две настройки для поддержания здоровья сервера: DropLimit (по умолчанию -1, без ограничения) ограничивает, сколько предметов может создать одно выпадение, а AlwaysAutoStack складывает выпадения в меньшее число объектов на земле. При масштабировании по звёздам и множителях стоит использовать обе; почему кучи предметов обходятся серверу дорого, объясняет статья о выпавших предметах и очистке мира. dropthat:reload перезагружает конфиги в работающем мире для тестов, но документация предупреждает, что он предназначен для быстрых проверок и может вызывать проблемы - для настоящих изменений перезапускайте.

Custom Raids: частота, новые рейды и отключение старых#

custom_raids.cfg управляет системой рейдов в целом. Документированные значения по умолчанию:

НастройкаПо умолчаниюДействие
EventCheckInterval46Минут между проверками рейда (ванильный интервал)
EventTriggerChance20Процент шанса за проверку (ванильный шанс)
RemoveAllExistingRaidsfalseУбирает ванильные случайные рейды; события боссов остаются
OverrideExistingtrueВаш рейд заменяет ванильный с тем же именем
UseIndividualRaidChecksfalseПозволяет каждому рейду иметь свои RaidFrequency и RaidChance
PauseEventTimersWhileOfflinetrueТаймеры рейдов замирают, пока никого нет онлайн
GeneratePresetRaidstrueЗаписывает два примера рейдов для поздней стадии, отключённых

EventTriggerChance = 0 полностью выключает рейды, и это тот случай, когда моду достаточно быть только на сервере, потому что сервер решает, когда начинаются рейды. Два готовых рейда - Ragnarok и Deathsquitoseason; оставьте их отключёнными, пока не прочтёте.

Рейд - это раздел для рейда и нумерованные подразделы для его спавнов в custom_raids.raids.cfg или в дополнительном файле:

custom_raids.supplemental.draugr_siege.cfg
[DraugrSiege]Name = draugr_siegeEnabled = trueRandom = trueDuration = 120NearBaseOnly = trueBiomes = Meadows, BlackForest, SwampRequiredGlobalKeys = defeated_bonemassCanStartDuringDay = falseStartMessage = The dead are marchingEndMessage = The dead fall silent[DraugrSiege.0]PrefabName = DraugrHuntPlayer = trueMaxSpawned = 6SpawnInterval = 5SpawnChancePerInterval = 50GroupSizeMin = 1GroupSizeMax = 2[DraugrSiege.1]PrefabName = Draugr_EliteHuntPlayer = trueMaxSpawned = 1SpawnInterval = 20SpawnChancePerInterval = 25

Чтобы выключить ванильный рейд, назовите его и отключите:

custom_raids.raids.cfg
[foresttrolls]Name = foresttrollsEnabled = false

Имена ванильных рейдов есть в выгрузке WriteDefaultEventDataToDisk. Другие условия рейдов включают ConditionPlayersOnlineMin, ConditionWorldAgeDaysMin и ConditionDistanceToCenterMin, а также условия по игрокам, работающие с модификатором мира playerevents. Заметьте, что StopTouchingMyConfigs в custom_raids.cfg по умолчанию true начиная с версии 1.7.10, так что мод больше не переписывает ваши файлы рейдов комментариями и недостающими опциями; вики всё ещё показывает старое значение по умолчанию.

Проверка изменений без вреда для мира#

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

  1. Сделайте резервную копию мира сервера.
  2. Внесите изменение на копии: в своём одиночном мире с теми же модами или в мире сервера, скачанном и загруженном локально.
  3. Используйте команды отладки. С правами админа и devcommands ванильная event draugr_siege запускает именованное событие там, где вы стоите, а stopevent его завершает; randomevent запускает случайное. На выделенном сервере devcommands требуют мод Server Devcommands - см. Server Devcommands.
  4. Проверьте в логе BepInEx предупреждения о ваших файлах.
  5. И только потом скопируйте файл на сервер, перезапустите и скажите группе.

На RE:NODE резервные копии делаются по запросу и восстанавливаются одной кнопкой, а вкладка Schedules может делать копию перед плановым перезапуском - хорошее сочетание, когда вы меняете таблицы спавна вечером и хотите иметь проверенную копию на случай, если группе не понравится.

Почему кастомные спавны и рейды не работают#

Сообщение о рейде появилось, но ничего не спавнится. Рейд начался, но собственные условия записей спавна не выполнились: не тот биом, дневной спавн ночью, слишком крутая земля или не установлен нужный глобальный ключ. Документация Custom Raids называет это обычной причиной. Сначала ослабьте условия спавна.

Рейд никогда не начинается. Условия рейда его исключают (NearBaseOnly без базы рядом, нет ключей), Enabled равно false, или при включённом UseIndividualRaidChecks его собственные частота и шанс слишком малы. Проверьте отладочный вывод после изменений.

Изменения ничего не делают. Вы редактировали клиентскую копию, а не серверную, или не перезапустили сервер. Клиенты используют конфиги сервера.

Записи игнорируются. Опечатки в именах опций или prefab. Имена prefab чувствительны к регистру и являются внутренними именами, а не отображаемыми; частые из них перечислены в статье о команде spawn и ID предметов.

Выпадения множатся вне контроля. Включён ScaleByLevel, а у существ высокие уровни звёзд, или другой мод тоже умножает добычу. Задайте ScaleByLevel = false для этой записи или используйте DropLimit.

Ванильный спавн всё ещё появляется после замены. Вы добавили новый ID вместо того, чтобы переопределить ванильный. Найдите ванильный ID в выгрузке и используйте его.

FAQ#

Нужны ли эти моды игрокам, если они есть на сервере?

Да, почти для всего. Спавн происходит на клиентах, а моды отправляют конфиги сервера клиентам, у которых есть мод. Исключение - отключение рейдов, которое работает и с одним Custom Raids на сервере.

Куда класть дополнительные файлы?

В BepInEx/config рядом с основными файлами, с именем по шаблону мода, например spawn_that.world_spawners.wolves.cfg. Custom Raids также находит свои дополнительные файлы в подпапках. Spawn That и Drop That загружают дополнительные файлы до основного, поэтому основной выигрывает любой конфликт; дайте каждому рейду уникальное имя раздела, чтобы в Custom Raids вопрос вообще не стоял.

Можно ли менять таблицы спавна в мире, в котором мы уже играем?

Да. Эти моды меняют правила, а не рельеф, поэтому они применяются со следующего перезапуска. Уже появившиеся существа остаются, пока не погибнут или не исчезнут, а локальные спавнеры в уже посещённых подземельях используют новый шаблон при следующем спавне.

Можно ли просто сделать рейды реже, а не убирать?

Да. Увеличьте EventCheckInterval или уменьшите EventTriggerChance в custom_raids.cfg. Ванильный модификатор мира raids тоже меняет частоту рейдов без мода; его значения перечислены в статье о модификаторах и пресетах мира.

Переживут ли эти конфиги обновление игры?

Файлы переживут. Загрузятся ли моды на новой версии, зависит от их автора, а новый игровой контент может добавить или перенумеровать ванильные записи. После патча обновите моды, заново создайте выгрузки и сравните, прежде чем доверять старым ID.