FAQ
Короткие ответы на вопросы, которые читатели действительно задавали, каждый — со ссылкой на страницу с подробностями. Слова, которые здесь используются, определены в глоссарии.
Игрокам
Заголовок раздела «Игрокам»Есть кнопка Play или кнопку надо держать? Держать: Hold to play, около секунды. Отдельной кнопки Play нет. → Подключение к серверу
В чём разница между лаунчером и хелпером? Лаунчер — окно, которое вы видите. Хелпер — его
часть, которая запускает BeamNG.drive и держит соединение, пока вы играете: тот же
nodemp-launcher.exe, запущенный второй раз без окна. Всплывающие сообщения называют хелпер
«launcher»: The launcher stopped · … означает, что остановился этот фоновый процесс, и его лог —
launcher.log. → Устранение неполадок
Нужен ли аккаунт, чтобы играть? Что такое Test Drive? Не нужен. Test Drive — игра без
аккаунта: при каждом подключении вы получаете новое имя Guest…, выбрать его нельзя, и некоторые
серверы гостей не пускают (Account required в панели; фильтр No account needed их скрывает).
Аккаунт даёт постоянное проверенное имя и работает на любом сервере. Страница регистрации на сайте
обращается к хостам, но аккаунт один и тот же. Test Drive не запоминается между запусками
лаунчера; вход — запоминается. → Установка лаунчера → Аккаунты
Какая версия BeamNG нужна? 0.39.4.0, текущий релиз: клиентский мод 1.4.0 собран для неё, а эталон строгого сервера описывает одну версию игры. Копия не из Steam работает, если Settings → Game указывает на её папку. → Установка лаунчера → Требования
Windows предупреждает о неизвестном издателе. Установщик настоящий? Установщик пока не
подписан, поэтому SmartScreen предупреждает. Сравните SHA-256 файла (Get-FileHash в PowerShell)
с опубликованным — из файла .sha256 рядом с установщиком на странице релиза; страница загрузки
показывает то же значение. → Установка лаунчера
Сервер проверяет мои файлы игры? А мои моды? Каждый сервер проверяет вашу установку на том
уровне, который выбрал хост; только строгий сервер смотрит ещё и в пользовательскую папку
BeamNG. Ваши упакованные моды в mods\ никогда не причина отказа — ни один уровень туда не
заглядывает, — и во время сессии они выключены, если вы не включили Use my local mods in
multiplayer и сервер это не разрешил. Строгий сервер отказывает за то, что мод оставил вне
mods\: распакованные файлы в vehicles\, levels\, lua\, ui\, art\, scripts\
пользовательской папки или что-то добавленное в папку игры. Уберите их; zip в mods\ переносить
не нужно.
→ Подключение к серверу → Что сервер проверяет на вашем ПК
Как увидеть весь список того, что отклонил строгий сервер? Отказ показывает три примера;
встроенная в лаунчер диагностика печатает все, по причине на строку (overlay, unlisted,
hash, …) и что с каждой делать. Панель под карточкой сервера предлагает команду с кнопкой
Copy. → Устранение неполадок → Строгие серверы
Что значат «Stock content» и «Required mods»? Оба — о контенте, который сервер отправляет
вам до запуска игры: его собственные zip-архивы модов, которые лаунчер скачивает на эту сессию.
Stock content значит, что сервер ничего лишнего не отправляет. Ни то ни другое не говорит о вашей
установке. Downloading Resource 2/5 на экране загрузки — тот же контент, файл за файлом.
→ Подключение к серверу → Список серверов
Лаунчер обновляет сам себя? Нет. Клиентский мод обновляется за вас перед каждым подключением;
лаунчер — нет. Когда серверу нужен более новый, подключение останавливается с
Could not join · This server needs a newer launcher — update from the Download page, а
страница загрузки всегда предлагает текущую версию.
→ Установка лаунчера
Direct Connect «всё равно работает», пока список серверов недоступен, — как? Вы подключаетесь по адресу без билета на подключение, так что имя никто не проверяет. Сервер без ключа сервера и так берёт имена как есть; сервер из списка, разрешающий Test Drive, пускает вас как непроверенного гостя; сервер с Account required отказывает. → Устранение неполадок → Список серверов пуст
В сообщении написано «Report this if the issue persists». Моё сообщение описано? Каждый
текст, который могут показать лаунчер, хелпер или сервер, процитирован на странице
Устранение неполадок и проиндексирован на странице
Коды ошибок; ищите на любой из них точные слова. Сообщая о проблеме,
приложите launcher.log, точный текст сообщения и имя сервера.
Какую версию сервера описывают эти страницы? Текущий релиз: 1.2.1 для сервера, 1.1.0 для лаунчера, 1.4.0 для клиентского мода, сетевой протокол v18; таблица на странице Что такое NodeMP — точка отсчёта. Там, где более старый сервер вёл себя иначе, короткая фраза «до 1.2.1» говорит как.
Что нужно, чтобы мой сервер попал в список? Аккаунт NodeMP с подтверждённой почтой и
привязанным аккаунтом Discord (только такой аккаунт может создать ключ сервера), машина, доступная
на порту 30814 по TCP и UDP, и ключ, заданный в существующей таблице [Directory] файла
server.toml. Без ключа сервер работает вне списка и доступен через Direct Connect.
→ Быстрый старт, Регистрация сервера
Я вставил блок [Directory] с сайта, и сервер завершается. Почему? В server.toml уже была
таблица [Directory], так что файл теперь определяет её дважды, а TOML этого не допускает.
Удалите вставленный блок и задайте Url, HostId и HostSecret в существующей таблице. Сервер
сам об этом говорит: the table [Directory] appears twice. Put the keys into the existing [Directory] table ….
→ Регистрация → Передача ключа серверу
На Windows лог говорит TLS handshake failed: certificate verify failed в сторону
api.nodemp.com. Ключ неверный? Нет — сервер не нашёл доверенных корневых сертификатов. На
текущем сервере это значит, что хранилище сертификатов Windows пусто, а cacert.pem больше не лежит
рядом с Node-Server.exe (верните его); на 1.2.0 и 1.1.0 это случалось на каждой машине с Windows,
и выход до обновления — SSL_CERT_FILE, указывающая на PEM-набор публичных корней. Не закрепляйте
[Directory] Fingerprint.
→ Регистрация → Windows
Как узнать, что проверка директории достучалась до моего порта? Лог сервера этого не говорит. Как только достучалась, сервер появляется в списке лаунчера и на nodemp.com/servers, а TCP-соединение с вашим публичным адресом на порт 30814 извне вашей сети проходит. → Регистрация → Что сервер делает с ключом
Сервер говорит Cannot listen on port 30814 … the port is already in use и завершается. Почему?
Почти всегда всё ещё работает предыдущий экземпляр сервера; остановите его или дайте этому другой
порт. Сервер завершается с кодом 1, чтобы супервизор это заметил. (До 1.2.1 сервер печатал
bind() failed и даже server is ready, прежде чем завершиться.)
→ Запуск → Логи
Как снять бан? Остановите сервер, затем Node-Server --bans list покажет записи, а
Node-Server --bans remove <ip | account id> удалит одну (обе записи — адрес и аккаунт — для
игрока, забаненного в сессии); запустите снова. Правка bans.json руками при остановленном
сервере делает то же. Работающий сервер может снять бан и через ресурс (node.bans.remove). → Запуск → Баны
Где примеры ресурсов (chat, demo-numbers, …)? В архиве релиза в папке examples/ рядом с
Node-Server; examples/README.txt говорит, что делает каждый. Скопируйте один в resources/ и
перезапустите сервер. (В архивах 1.2.0 и старше их не было.)
→ Ресурсы и контент → Установка ресурса
Нужен ли ПК с Windows для strict? Для генерации эталонного манифеста — да: генератор
читает чистую установку BeamNG, поэтому запускается там, где установлена игра. Файл манифеста
затем копируется на сервер, в том числе на Linux или в Docker.
→ Строгая проверка
Где release notes? В описании релиза на GitHub, начиная с 1.2.1 (раздел RELEASE_NOTES.md
репозитория сервера для этого тега): что изменилось, менялось ли значение по умолчанию, двигался ли
сетевой протокол. У более старых релизов описание — одно предложение; эти страницы описывают текущий
релиз. Релиз сервера, сохраняющий сетевой протокол, не требует от ваших игроков обновлять лаунчер. → Обновление
Авторам плагинов
Заголовок раздела «Авторам плагинов»Какое правило именования событий, и что происходит со старыми именами? Уведомление —
<subject><Verb-ed> (playerJoined, vehicleSpawned, serverShutdown); запрос, который
обработчик может отклонить, — <subject><Action>Request (vehicleSpawnRequest, relayRequest);
префикса on нет. Сетевые события — <domain>:<verb> в нижнем регистре (chat:send). Написания,
которые использовали серверы до 1.2.0, — playerJoin, onVehicleSpawnRequest, canRelay и
остальные — устаревшие псевдонимы: они по-прежнему подписывают на то же событие, пишут одно
предупреждение [deprecated] на ресурс на имя и будут удалены в 2.0.
→ События → Именование
Какие HTTP-методы существуют? node.http.request(method, url, opts?, cb) принимает любой
метод; node.http.get, post, put, patch, delete и head — тот же вызов с фиксированным
методом, а node.http.fetch(url, { method = … }) — корутинная форма внутри node.async (методы,
кроме get и post, добавлены в сервере 1.2.0; до него fetch отправлял всё, кроме POST,
как GET). Заголовки ответа приходят с именами в нижнем регистре (headers["content-type"]).
Проверка TLS-сертификата выключена, пока хост не задаст [Http] CaFile; тогда каждый запрос
https:// проверяется по этому набору. → Параллелизм → HTTP
Есть ли сокеты — node.net? Пока нет. У сервера нет API сокетов для ресурсов: наружу
есть node.http, внутри — сетевые события, шина и модульный канал. API сокетов есть в планах
платформы, без даты; ничего на этих страницах его не описывает, и строить на нём пока ничего не
стоит.
Что переживает перезагрузку ресурса, и что такое resourceUnload? Перезагрузка сбрасывает
всё, что зарегистрировала серверная половина — обработчики, таймеры, корутины, подписки на шину и
модульный канал, фильтры ретрансляции, приёмники лога — и всё состояние Lua, затем снова выполняет
main.lua. node.storage, файлы в вашей папке и другие ресурсы переживают её; фоновая задача или
HTTP-запрос в полёте не отменяются, а клиентские файлы не переупаковываются до перезапуска.
node.on("resourceUnload", fn(reason)) выполняется в старом экземпляре прямо перед сбросом с
"reload" или, при остановке сервера, "shutdown": запишите, что должны, и вернитесь — ничто,
запущенное там, больше не выполнится. → Ресурсы → Перезагрузка
Что проверяет строгий сервер, а что нет? Он сравнивает всю папку игры, оглавление каждого
архива и пользовательскую папку игрока с эталоном чистой установки — перед подключением и снова
во время сессии. Он не хеширует содержимое архивов (только таблицы CRC-32), не проверяет сам
лаунчер и не заглядывает в mods\. Строгая сессия — другое: внутриигровые правила, которые
ваш ресурс включает для игрока через session:config.strict.
→ Строгая проверка,
Клиентские скрипты → Строгие сессии
Как тестировать плагин без игры? Всё серверное работает без игрока. Команду чата проверяют
через контракт шины, на котором говорит chat: опубликуйте chat:command с
{ pid, name, args, raw } (name в нижнем регистре) и смотрите ответ в chat:say. Обработчику
сетевого события нужен клиент, а клиентские файлы выполняются только внутри игры.
→ Первые шаги → Тестирование без игры
Почему /HELLO не доходит до моего обработчика, когда я публикую chat:command сам? chat
приводит набранное слово к нижнему регистру перед публикацией, а node.commands.add приводит к
нижнему регистру регистрируемое имя; сам поиск точный. chat:command, который публикуете вы,
должен нести имя в нижнем регистре. → Рецепты → Команда чата
node.on с одной и той же функцией дважды — один раз или два? Один: второй вызов заменяет
первый, а node.off(name, fn) снимает подписку. Две разные функции — два обработчика.
→ Конвенции → Формы возвращаемых значений
Почему мой колбэк таймера на 600 мс не вызвал предупреждение о зависании? На текущем сервере
вызывает: каждый обработчик, колбэк таймера, отрезок корутины и колбэк завершения измеряется
отдельно, а строка называет ресурс и вид ((resource race, timer)). До 1.2.1 измерялись только
целые задания рабочего потока, и колбэки таймеров и отрезки node.async оставались незамеченными. → Параллелизм → Один рабочий поток
Сообщает ли сервер о синтаксической ошибке в моём клиентском файле? Да, при загрузке: каждый
клиентский файл разбирается при упаковке, и тот, что не разбирается, получает строку Error с
именем ресурса, файла и сообщением Lua независимо от настройки обфускации. Файл всё равно
отправляется (сервер клиентский код не выполняет), а собственная ошибка компиляции игры — в
beamng.log игрока. До 1.2.1 единственным признаком было предупреждение Prometheus при
включённой обфускации. → Ресурсы → Обфускация
Где примеры, и где chat? В папке examples/ архива релиза рядом с исполняемым файлом
сервера (examples/README.txt их перечисляет). Протокол chat — chat:send и chat:msg по сети, chat:command и chat:say
на шине — задокументирован, так что заглушка пишется в несколько строк.
→ События → node.bus
Может ли ресурс перезаписать файл игры или клиентского мода своим клиентским файлом? Нет.
Переданные клиентские файлы компилируются в памяти под собственным именем ресурса и никогда не
пишутся на диск игрока, так что они добавляют модули и хуки рядом с оригиналами и ничего не
подменяют. Меняйте поведение во время выполнения: те же события, собственное расширение ge,
манифест модулей, который выключает встроенный клиентский модуль.
→ Клиентские скрипты → Что клиентский файл может и чего не может
Как проверить, что файл существует, создать папку, переименовать или скопировать файл через
node.fs? В node.fs есть read, write, writeAsync и list, больше ничего. Существование:
поиск имени в node.fs.list(folder). Папка: node.fs.write создаёт родителей того пути, который
пишет. Копия: node.fs.write(to, node.fs.read(from)). Переименование и удаление: стандартные
os.rename и os.remove с абсолютным путём, собранным от папки ресурса. Пути пишите через / и
на Windows, и на Linux. → Ресурсы → Чего в node.fs нет
Есть ли событие fileChanged? Нет, и сервер за файлами не следит. Опрашивайте через
node.every, сравнивая размеры из node.fs.list или хеш содержимого.
→ События → События о файлах нет
Случайные числа, время выполнения, память, операционная система — где? Первые три — стандартный
Lua: math.random() и math.random(a, b) (зерно уже посеяно), node.server.uptime() до и после
участка, collectgarbage("count") для стейта этого ресурса. Суммы по всем стейтам, статистики по
обработчикам и имени или версии ОС в node нет.
→ Соглашения → Окружение Lua
Умеет ли node.json красиво печатать или считать и применять diff двух документов? Нет.
node.json.encode пишет компактный JSON и не принимает опций; diff, patch и flatten нет.
→ Соглашения → Окружение Lua
Может ли сервер вызывать мой языковой хост из нескольких потоков? Нет. Каждая доставка
хостируемому ресурсу приходит в единственном рабочем потоке фреймворка, по одной за раз; флага для
другого в NodeLanguageHost нет, и он не запланирован. Хост с собственным циклом событий передаёт
колбэки дальше сам, как js-host; вызовы NodeApi, фильтр ретрансляции и работа submit_job уже
выполняются вне рабочего потока.
→ Нативные модули → Языковые хосты
