Спавн NPC в Lineage 2: как добавлять, исправлять и удалять спавны

Редактирование спавна NPC в Lineage 2 кажется простой задачей, пока поставленный вами NPC не исчезает после рестарта, а удалённый стражник наутро снова не стоит в городе. Почти всегда проблема в двух вещах: вы не знаете, какая админ-команда делает спавн постоянным, или правите не то хранилище. В этом гайде разберём оба момента для эмуляторов семейства L2J. Команды и пути к файлам меняются от сборки к сборке, поэтому прежде чем доверять любому названию отсюда, сверьтесь с исходниками своего пака.
Где ваш эмулятор хранит спавны
Прежде чем что-то трогать в игре, выясните, что сервер читает при запуске. Решает это не хроника, а ветка эмулятора.
- Классический L2J (спавны в SQL). Спавны лежат в двух таблицах базы данных:
spawnlistиcustom_spawnlist. Каждая строка содержитcount, npc_templateid, locx, locy, locz, heading, respawn_delay, respawn_random, loc_id, periodOfDay. Строки в кастомной таблице могут использовать те же ID, что и в стандартной. - L2J Mobius и более новые ветки (спавны в XML). Спавны хранятся в XML-файлах в
dist/game/data/spawns/<Region>/и проверяются по схемеxsd/spawns.xsd. - Другие форки (aCis и подобные). У них своя структура. Откройте загрузчик спавнов в исходниках и проследите, какие файлы он разбирает, вместо того чтобы гадать.
Запись спавна в стиле Mobius выглядит так (пример из диффа 2022 года, эпохи Fafurion, так что ваша схема может немного отличаться):
<list>
<spawn name="BalthusKnights">
<group>
<npc id="34359" x="190569" y="168057" z="-11228" heading="29292" respawnTime="60sec" />
</group>
</spawn>
</list>
| Хранилище | Где | Переживёт обновление датапака? |
|---|---|---|
spawnlist (SQL) | Игровая база данных | Нет. Обновления её перезаписывают. |
custom_spawnlist (SQL) | Игровая база данных | Да. Обновления её не трогают. |
| XML-файлы спавнов | data/spawns/<Region>/ | Только если вы отслеживаете свои правки (отдельный файл или своя ветка в git) |

Добавление NPC в игре: //spawn или //spawn_once
На L2J Server (датапак High Five) расстановкой занимается AdminSpawn.java. Базовый синтаксис:
//spawn <id> [count] [respawnTime]
Порядок аргументов важен. Время респавна читается только если указано и количество, поэтому //spawn 20001 60 означает не «респавн каждые 60», а 60 мобов. Пишите //spawn 20001 1 60.
Варианты команды отличаются тем, насколько спавн постоянный:
//spawnи//spawn_monsterдобавляют спавн как постоянный, то есть он должен вернуться после рестарта.//spawn_onceдобавляет непостоянный спавн и отключает его респавн. Убили его, и он больше не появится. Подходит для ивент-боссов, тестовых мобов и разовых GM-шоу.- Всё, что заспавнено, пока вы находитесь в инстансе, всегда непостоянно, какой бы командой вы ни пользовались. Если новый NPC пропал, проверьте, не стояли ли вы в инстансе, когда его ставили.
Тот же обработчик регистрирует //show_spawns, //list_spawns, //list_positions, //unspawnall, //respawnall, //spawnday и //spawnnight. Перед расстановкой запустите //list_spawns: так вы увидите, что уже стоит на месте, и не поставите второго NPC поверх первого.
Совет: встаньте ровно туда, где должен стоять NPC, и повернитесь в нужную сторону, прежде чем вводить команду. Большинство криво поставленных NPC появляется, когда координаты потом перебивают вручную.
Таймеры респавна и дневные или ночные спавны
Респавн задаётся задержкой и необязательным случайным разбросом. В SQL-структуре это respawn_delay и respawn_random. В XML у Mobius это атрибут respawnTime с единицей измерения, например respawnTime="60sec".
Два правила, которые стоит запомнить (по документации менеджера спавнов на базе Mobius):
- Респавн включается, только если задержка больше 0. Задержка 0 означает, что после смерти NPC не вернётся.
- Если минимальная и максимальная задержка различаются, сервер выбирает случайное значение между ними. Именно этот разброс не даёт кемперам выставлять таймер на моба до секунды.
Для NPC, которые появляются только ночью или только днём, в SQL-версиях L2J используйте periodOfDay: 0 означает всегда, 1 только днём, 2 только ночью. Команды //spawnday и //spawnnight названы в честь этих дневных и ночных наборов спавнов. Прежде чем полагаться на них при тестах, проверьте, что именно они делают в вашей сборке.

Удаление NPC, которые возвращаются
Возьмите NPC в таргет и введите //delete. На L2J Server AdminDelete.java удаляет живой экземпляр, вызывает stopRespawn() и убирает спавн из SpawnTable, а если это рейд-босс, то из RaidBossSpawnManager.
Нам не удалось подтвердить, удаляет ли эта команда в текущих сборках ещё и строку из базы. А в ветках на XML при запуске загружается файл с диска. Поэтому если удалённый NPC вернулся после рестарта, считайте, что запись в хранилище уцелела, и удалите её в источнике:
- Перед удалением запишите ID NPC и примерные координаты (поможет
//list_spawns). - Найдите соответствующую строку в
spawnlistилиcustom_spawnlistлибо строку<npc>в XML-файле региона. - Удалите её там, затем перезапустите сервер или перезагрузите спавны.
- Если запись была в
spawnlist, зафиксируйте изменение. Следующее обновление датапака может вернуть её обратно.
Перезагрузка после правки: что применяется на лету
На этом спотыкаются многие. На L2J Server //reload npc перезагружает шаблоны NPC через NpcData.load(). Позиции спавнов она не перезагружает, а типа spawn у //reload вообще нет. Среди поддерживаемых типов: config, npc, quest, htm, multisell, buylist, skill, item, door, zone и effect.
Для спавнов есть отдельная команда //spawn_reload. Примерное правило:
- Изменили шаблон NPC:
//reload npc(и//reload htm, если правили его HTML-страницы). - Изменили строки или файлы спавнов:
//spawn_reload. - Поменяли много всего сразу на живом сервере: делайте это в техработы и перезапускайте сервер. Массовая перезагрузка при игроках онлайн легко оборачивается задвоенными мобами, которых потом приходится чистить вручную.
Безопасный порядок работы со спавнами
- Перед каждой сессией правок делайте бэкап таблиц спавнов или папки
data/spawns. - Своих NPC держите в
custom_spawnlistили в отдельном собственном XML-файле, а не вписывайте прямо в стандартные файлы. - Ставьте NPC в игре через
//spawn, проверьте респавн, убив его, затем перезапустите тестовый сервер и убедитесь, что спавн сохранился. - Ведите журнал добавленных и удалённых ID и координат, чтобы повторить правки после обновления эмулятора.
Когда мир вычищен, а кастомные NPC работают стабильно, игрокам всё ещё нужно найти ваш сервер. Добавьте сервер в L2Calendar бесплатно, чтобы он появился в календаре открытий. Если хотите больше внимания в неделю запуска, VIP-размещение поднимет его выше в списках.
