Конфигурация
Все модули адаптера читают ключи из одной цепочки источников, отдельно для каждого ключа:
- Файл из системного свойства JVM
-Dl2nx.config-file=<path>; если оно не задано —l2nx.propertiesв рабочей директории JVM. - Системные свойства JVM
-Dl2nx.<key>=<value>— только для ключей, которых нет в файле.
Переменные окружения не поддерживаются. Подробности поиска файла — в быстром старте.
Правила для значений:
- Файл читается в UTF-8. Значения обрезаются по краям; пустое значение считается незаданным, и действует значение по умолчанию.
- Ключи читаются один раз при старте. Изменение вступает в силу после перезапуска сервера. Единственное исключение — отдельный файл настроек приложения, который перечитывается на работающем сервере.
- Неверное значение (не число, вне диапазона, неизвестный вариант) никогда не заменяется значением по умолчанию:
адаптер пишет в лог ошибку с именем ключа, и часть, которая его читает, не стартует. Для ключей core адаптер
переходит в
FAILED. - Булевы значения —
trueилиfalse, перечисления не зависят от регистра. coresв значениях по умолчанию ниже — число процессоров, доступных JVM.
nx-gs-adapter-core
Заголовок раздела «nx-gs-adapter-core»Подключение
Заголовок раздела «Подключение»| Ключ | Тип | По умолчанию | Обязателен | Смысл |
|---|---|---|---|---|
l2nx.config-file |
путь | не задан | нет | Путь к файлу свойств. Читается только как системное свойство JVM. Задан, но не читается — адаптер падает при старте. |
l2nx.enabled |
boolean | false |
нет | Главный выключатель. При false адаптер переходит в DISABLED: нет подключения, heartbeat и синхронизации. |
l2nx.platform-url |
URL | — | да | Базовый URL вашего тенанта на платформе, например https://<tenant>.api.l2nx.app. Должен быть https, с хостом, без query и fragment; завершающий слэш отбрасывается. |
l2nx.host-type |
gs/ls |
gs |
нет | Где работает адаптер: gs — игровой сервер, ls — логин-сервер. Определяет, какой из ключей ниже читается. |
l2nx.gs-key |
строка | — | для gs |
Ключ игрового сервера: начинается с nx_sk_, всего 38 символов. Нельзя задавать вместе с l2nx.ls-key. |
l2nx.ls-key |
строка | — | для ls |
Ключ логин-сервера, тот же формат, что у l2nx.gs-key. Нельзя задавать вместе с l2nx.gs-key. |
| Ключ | Тип | По умолчанию | Обязателен | Смысл |
|---|---|---|---|---|
l2nx.io.workers |
int | max(2, cores/2) |
нет | Размер пула адаптера для блокирующей работы модулей и обработчиков команд (JDBC, HTTP). Потоки называются nx-io-N. ≥ 1. |
Kafka producer
Заголовок раздела «Kafka producer»Адаптер публикует через Kafka producer, настройки подключения и безопасности которого приходят с платформы. Настраиваются три параметра:
| Ключ | Тип | По умолчанию | Обязателен | Смысл |
|---|---|---|---|---|
l2nx.kafka.producer.batch.size |
байты | 16384 |
нет | Размер батча producer. Больше — меньше round trip и быстрее массовая синхронизация, меньше — ниже задержка. |
l2nx.kafka.producer.linger.ms |
мс | 10 |
нет | Сколько producer ждёт заполнения батча. Большие значения сокращают round trip на больших первичных синхронизациях, 0 даёт минимальную задержку. |
l2nx.kafka.producer.compression.type |
строка | gzip |
нет | Сжатие батчей: none, gzip, lz4, snappy или zstd. gzip не требует ничего дополнительно; для lz4, snappy и zstd нужен JAR библиотеки в classpath. |
События
Заголовок раздела «События»События, которые публикует хост, идут через одну ограниченную очередь, которую разбирает один поток.
| Ключ | Тип | По умолчанию | Обязателен | Смысл |
|---|---|---|---|---|
l2nx.events.queue-capacity |
int | 10000 |
нет | Максимум событий в очереди. Меньше — меньше heap, но больше потерь на всплесках. ≥ 1. |
l2nx.events.drop-policy |
newest/oldest |
newest |
нет | Что происходит при полной очереди. newest отбрасывает входящее событие и сохраняет порядок очереди (рекомендуется); oldest вытесняет самое старое событие — когда свежесть важнее полноты. |
l2nx.events.shutdown-drain-timeout-ms |
мс | 5000 |
нет | Сколько адаптер продолжает доставлять события из очереди после начала остановки; остаток отбрасывается и учитывается. Увеличьте, если события теряются при остановке. ≥ 0. |
Команды
Заголовок раздела «Команды»Команды с платформы передаются обработчикам, которые зарегистрировал хост. Offsets коммитятся батчами, поэтому незакоммиченный батч доставляется повторно после перезапуска: обработчики должны быть идемпотентными.
| Ключ | Тип | По умолчанию | Обязателен | Смысл |
|---|---|---|---|---|
l2nx.commands.poll-timeout-ms |
мс | 100 |
нет | Сколько блокируется каждый опрос новых команд. Меньше — быстрее остановка и больше холостых пробуждений. ≥ 1. |
l2nx.commands.shutdown-timeout-ms |
мс | 5000 |
нет | Сколько остановка ждёт работающие обработчики. Команды, не переданные к этому моменту, доставляются повторно при следующем старте. ≥ 0. |
l2nx.commands.host-sync-timeout-ms |
мс | 30000 |
нет | Лимит на синхронный вызов обработчика в игровую сторону через host executor. По истечении команда завершается с UNAVAILABLE. Не даёт перегруженному игровому пулу остановить consumer команд. ≥ 1. |
l2nx.commands.deferred-reply-max-ms |
мс | 300000 |
нет | Лимит на отложенный ответ: обработчик, который отложил ответ и не завершил его, получает INTERNAL_ERROR. Должен превышать самую долгую легитимную отложенную команду на сервере. ≥ 1. |
l2nx.commands.kafka.<property> |
строка | — | нет | Передаётся как есть в Kafka consumer команд как <property>. Значения по умолчанию max.poll.records=50 и auto.offset.reset=earliest так можно переопределить; bootstrap.servers, client.id, group.id, enable.auto.commit, security.protocol и sasl.* адаптер фиксирует — их нельзя. |
nx-gs-db-sync-core
Заголовок раздела «nx-gs-db-sync-core»Движок синхронизации БД (l2nx.cdc-engine.*). Значения по умолчанию рассчитаны на таблицу предметов примерно в
12 миллионов строк.
| Ключ | Тип | По умолчанию | Обязателен | Смысл |
|---|---|---|---|---|
l2nx.cdc-engine.tick-interval-seconds |
с | 60 |
нет | Период между циклами синхронизации каждой сущности. Меньше — свежее данные и выше нагрузка на БД. ≥ 1. |
l2nx.cdc-engine.rows-per-window |
int | 500000 |
нет | Строк за одно окно запроса; большие сущности читаются в несколько окон. Больше — быстрее первичная синхронизация, но дольше чтение и больше heap. От 1 до 10000000. |
l2nx.cdc-engine.query-timeout-seconds |
с | 10 |
нет | JDBC-таймаут каждого запроса. Окно, превысившее таймаут, прерывается и повторяется в следующем цикле. Увеличьте для больших таблиц на медленных дисках. ≥ 1. |
l2nx.cdc-engine.publish-flush-seconds |
с | 5 |
нет | Сколько конец цикла ждёт подтверждений публикации. Неподтверждённые строки публикуются снова в следующем цикле. Увеличьте при предупреждениях publishes still pending. ≥ 1. |
l2nx.cdc-engine.workers |
int | max(2, min(entities, cores/2)) |
нет | Размер общего пула движка. 0 — формула по умолчанию. |
l2nx.cdc-engine.fetch-size |
int | 10000 |
нет | Подсказка JDBC fetch size. На MySQL Connector/J игнорируется (адаптер читает строки потоком); MariaDB использует её как батч курсора только с useCursorFetch=true в URL; другие драйверы — как размер батча курсора. ≥ 1. |
l2nx.cdc-engine.persist.dir |
путь | nx-cdc-snapshot |
нет | Директория кэша снапшотов на диске; относительный путь — от рабочей директории JVM. См. ниже. |
l2nx.cdc-engine.persist.checkpoint-min-interval-seconds |
с | 300 |
нет | Минимальный интервал между перезаписями файла снапшота одной сущности. ≥ 0. |
Кэш снапшотов включён всегда. Он хранится как <persist.dir>/<schema>/<entity>.snap и загружается при старте,
поэтому первый цикл после перезапуска сообщает и о строках, удалённых из базы, пока сервер был выключен. Lock-файл в
директории не даёт второму адаптеру с той же схемой её использовать: каждому серверу с общей рабочей директорией
задайте свой l2nx.cdc-engine.persist.dir. Запись снапшотов идёт на пуле движка; на медленном хранилище увеличьте
l2nx.cdc-engine.workers.
nx-gs-runtime-sync-core
Заголовок раздела «nx-gs-runtime-sync-core»Движок синхронизации состояния из памяти (l2nx.runtime-sync.*). Его ключи не зависят от l2nx.cdc-engine.*.
| Ключ | Тип | По умолчанию | Обязателен | Смысл |
|---|---|---|---|---|
l2nx.runtime-sync.tick-interval-seconds |
с | 10 |
нет | Период между чтениями состояния из памяти; каждое сравнивается с предыдущим. ≥ 1. |
l2nx.runtime-sync.publish-flush-seconds |
с | 5 |
нет | То же, что l2nx.cdc-engine.publish-flush-seconds, на каждый тик. ≥ 1. |
l2nx.runtime-sync.workers |
int | max(2, min(entities, cores/2)) |
нет | Размер общего пула движка. Если задан — ≥ 1. |
nx-gs-gd-sync-core
Заголовок раздела «nx-gs-gd-sync-core»| Ключ | Тип | По умолчанию | Обязателен | Смысл |
|---|---|---|---|---|
l2nx.gd-sync.resync-interval-hours |
часы | 0 |
нет | Период плановой полной переотправки каталогов игровых данных. 0 выключает расписание. ≥ 0. |
Игровые данные переотправляются и тогда, когда хост запрашивает это после перезагрузки датапака, и когда это запрашивает платформа, поэтому расписание — лишь страховка.
Файл настроек приложения
Заголовок раздела «Файл настроек приложения»l2nx-app.properties задаёт поведение сервера для того, что персонаж делает в игре по команде из приложения, пока
игрок вне клиента. l2nx.properties подключает сервер к платформе, а этот файл — продуктовое поведение сервера, его
правит гейм-дизайнер. nx-gs-adapter-core читает его только на игровом сервере (логин-сервер его игнорирует).
- Расположение. Рядом с
l2nx.properties: в рабочей директории JVM или, если-Dl2nx.config-fileуказывает в другое место, в директории этого файла. Нет файла — действуют все значения по умолчанию. Системные свойства JVM эти ключи не переопределяют. - Эталонный файл.
l2nx-app.propertiesперечисляет все ключи со значениями по умолчанию и комментариями. Скопируйте его и измените нужное. - Значения по умолчанию. Отсутствующий ключ принимает значение по умолчанию. Все типы сессий и чат с приложением по умолчанию выключены; возрождение включено.
- Значения. Обрезаются по краям;
true/falseи имена перечислений точные (регистр важен). Файл в UTF-8; метка порядка байтов (BOM) в начале файла игнорируется. - Проверка. Сначала проверяется весь файл. Одно неверное значение или неизвестный ключ (в том числе опечатка) не
применяет ничего: прежние значения остаются, а в логе по одной строке
app settings not applied, previous values stay: <key>: <reason>на каждую проблему. В отличие от ключейl2nx.*, неверное значение никогда не останавливает сервер. - Перезагрузка. Адаптер проверяет файл примерно раз в 5 секунд и применяет изменение без перезапуска; в логе
app settings updated: <key>: <old> -> <new>. - Идущие сессии. Новые значения действуют на новые старты. Сессия сохраняет порог возврата, с которым начата; отключённый тип сессии даёт идущим сессиям завершиться и отклоняет новые старты.
Хост читает актуальные значения через типизированный NxAppRules (NxAdapter.appRules(),
ConnectContext.appRules(), CommandContext.appRules()); current() возвращает неизменяемый снимок AppRules.
| Ключ | Тип | По умолчанию | Смысл |
|---|---|---|---|
app.phantom.title.text |
строка | l2nx.app |
Титул над персонажем, которого приложение поставило в мир, вместо его собственного; только отображение, не сохраняется. 1-16 символов; пусто — без подмены. |
app.phantom.title.color |
6 hex-цифр RGB | FFFF00 |
Цвет этого титула. Используется, только когда задан текст титула. |
app.session.recent-logout-minutes |
минуты | 2 |
Нет старта из приложения в течение этого времени после выхода персонажа из игры с клиентом. 0 отключает правило. 0-60. |
app.session.restart-window-minutes |
минуты | 15 |
Нет старта из приложения, если плановый рестарт ближе этого времени. 0-120. |
app.session.return-threshold-minutes |
минуты | 30 |
Сессия, завершившаяся с меньшим временем в мире, возвращает персонажа туда, откуда он начал; при равном или большем времени персонаж остаётся на месте. Один порог для всех типов сессий. ≥ 0. |
app.private-store.enabled |
boolean | false |
Частный магазин из приложения на этом сервере. false: старт отклоняется как отключённый. |
app.private-store.start-cooldown-minutes |
минуты | 5 |
Нет нового старта частного магазина (продажа или покупка) персонажа в течение этого времени после фактического старта предыдущего магазина этого персонажа из приложения; не даёт сбивать цены перезапуском магазина. Другие персонажи того же игрока не ждут; закрытие магазина не ограничено. 0 отключает правило. 0-1440. |
app.fishing.enabled |
boolean | false |
Офлайн-рыбалка на этом сервере. false: старт отклоняется как отключённый. true требует app.fishing.spot-pool. |
app.fishing.start-cooldown-minutes |
минуты | 15 |
Нет нового старта рыбалки ни для одного персонажа мастер-аккаунта в течение этого времени после фактического старта предыдущей рыбалки этого мастер-аккаунта из приложения. 0-1440. |
app.fishing.min-duration-minutes |
минуты | 30 |
Самая короткая рыбалка, которую может запросить старт. ≥ 1. |
app.fishing.max-duration-minutes |
минуты | 1440 |
Самая долгая рыбалка, которую может запросить старт; не меньше app.fishing.min-duration-minutes. Собственный суточный лимит сервера может завершить сессию раньше. |
app.fishing.float-distance |
игровые единицы | 170 |
Расстояние от рыбака до поплавка по направлению точки. 90-250. |
app.fishing.spot-order |
RANDOM/FIRST_FREE |
RANDOM |
Как выбирается свободная точка пула: любая свободная или свободная с наименьшим id. |
app.fishing.spot-pool |
строка | пусто | Имя пула точек, которым рыбалка пользуется на сервере; сам пул (id точек, координаты, направление) — данные игрового сервера. 1-32 символа a-z, 0-9 и _; пусто — пула нет. Изменённый пул действует только на новые старты. |
app.revive.enabled |
boolean | true |
Возрождение мёртвого персонажа в точке возрождения из приложения, с ещё подключённым или уже закрытым клиентом. false: возрождение отклоняется как отключённое. С NATIVE других ключей не требует. |
app.revive.town.mode |
NATIVE/SPOT_POOL |
NATIVE |
Куда возрождение «в город» ставит персонажа: как сама игра при «В деревню» или на точку из пулов app.revive.town.spot-pool, которую не занимает ни одна идущая сессия приложения (любую из них, если свободных нет). Персонаж с кармой всегда получает место NATIVE. |
app.revive.town.spot-pool |
список имён пулов | пусто | Пулы точек, из которых выбирает возрождение SPOT_POOL, через запятую; каждое имя — 1-32 символа a-z, 0-9 и _, без повторов; можно указать пул из app.fishing.spot-pool. Сами пулы — данные игрового сервера. SPOT_POOL с пустым списком — ошибка. |
app.chat.enabled |
boolean | false |
Игровой чат в приложении и отправка в него из приложения. false: игровой чат не публикуется на платформу, любая отправка от персонажа из приложения отклоняется как отключённая (объявления и строки от имени стаффа уходят как раньше), а шёпот из игры на Name* (персонажу не в игре) получает ответ как на неизвестное имя. |
app.chat.online-send-channels |
список каналов | CLAN,ALLIANCE,PARTY,WHISPER |
Каналы, в которые приложение может писать, пока персонаж в игре: CLAN, ALLIANCE, PARTY, WHISPER через запятую, без повторов. Пусто — в этом состоянии приложение только читает чат. Отправка в канал вне списка отклоняется. |
app.chat.offline-send-channels |
список каналов | CLAN,ALLIANCE,WHISPER |
Каналы, в которые приложение может писать, пока персонаж не в игре, так же; PARTY здесь недопустим (вне игры группы нет). Пусто — в этом состоянии приложение только читает чат. |
app.restore.batch-size |
int | 10 |
Сколько сессий восстанавливается за пачку после рестарта. Ограничено половиной l2nx.io.workers. ≥ 1. |
app.restore.batch-pause-millis |
мс | 1000 |
Пауза между пачками восстановления. ≥ 0. |
app.shutdown.result-millis-per-session |
мс | 20 |
Сколько добавляется на открытую сессию к 5 с, которые штатная остановка ждёт результаты сессий. ≥ 1. |
app.history.retention-days |
дни | 90 |
Закрытые сессии старше этого срока удаляются из таблицы адаптера при старте сервера. ≥ 7. |
Остальные модули
Заголовок раздела «Остальные модули»У nx-gs-adapter-api, nx-gs-kafka, nx-gs-commons, nx-gs-db-migrations и nx-gs-db-migrator-liquibase5 своих
ключей нет. Мигратор использует тот же JdbcConnectionSource, что и остальной адаптер.
