Skip to content

Руководство по устранению неполадок

Главная | Устранение неполадок


Когда что-то идёт не так, начните здесь. Это руководство организовано по тому, что вы видите (симптому), а не по системе. Найдите свою проблему, прочитайте причину, примените исправление.


Содержание

  1. Мод не загружается
  2. Ошибки скриптов
  3. Проблемы с RPC и сетью
  4. Проблемы с интерфейсом
  5. Проблемы сборки и PBO
  6. Проблемы производительности
  7. Проблемы с предметами, транспортом и сущностями
  8. Проблемы с конфигурацией и types
  9. Проблемы с персистентностью
  10. Блок-схемы принятия решений
  11. Краткая справка по командам отладки
  12. Расположение файлов логов
  13. Где получить помощь

1. Мод не загружается

Это проблемы, при которых мод не появляется, не активируется или отклоняется игрой при запуске.

СимптомПричинаИсправление
Ошибка "Addon requires addon X" при запускеОтсутствует или неверная запись requiredAddons[]Добавьте точное имя класса CfgPatches зависимости в ваш requiredAddons[]. Имена чувствительны к регистру. См. Главу 2.2.
Мод не виден в лаунчереФайл mod.cpp отсутствует или содержит синтаксические ошибкиСоздайте или исправьте mod.cpp в корне мода. Он должен содержать поля name, author и dir. См. Главу 2.3.
"Config parse error" при запускеСинтаксическая ошибка в config.cppПроверьте отсутствующие точки с запятой после закрытия классов (};), незакрытые фигурные скобки или несбалансированные кавычки. Каждое тело класса заканчивается };, каждое свойство --- ;.
Нет записей в логе скриптов вообщеБлок defs в CfgMods указывает на неверный путьУбедитесь, что запись CfgMods в config.cpp содержит правильный dir и что файл определений скриптов соответствует структуре папок. Движок молча игнорирует неверные пути.
Мод загружается, но ничего не происходитСкрипты компилируются, но никогда не выполняютсяПроверьте, что у вашего мода есть точка входа: modded class MissionServer или MissionGameplay, зарегистрированный модуль или плагин. Скрипты не запускаются сами по себе. См. Главу 7.2.
"Cannot register cfg class X"Дублирующееся имя класса CfgPatchesДругой мод уже использует это имя класса. Переименуйте ваш класс CfgPatches на уникальное имя с префиксом мода.
Мод загружается только в одиночной игреНа сервере не установлен модУбедитесь, что параметр запуска -mod= сервера включает путь к вашему моду, и PBO находится в папке @YourMod/Addons/ сервера.
"Addon X is not signed"Сервер требует подписанные аддоныПодпишите ваши PBO закрытым ключом и предоставьте .bikey в папку keys/ сервера. См. Главу 4.6.

2. Ошибки скриптов

Они появляются в логе скриптов как строки SCRIPT (E): или SCRIPT ERROR:.

СимптомПричинаИсправление
Null pointer accessОбращение к переменной, которая равна nullДобавьте проверку на null перед использованием переменной: if (myVar) { myVar.DoSomething(); }. Это самая распространённая ошибка времени выполнения.
Cannot convert type 'X' to type 'Y'Прямое приведение между несовместимыми типамиИспользуйте Class.CastTo() для безопасного приведения типов вниз: Class.CastTo(result, source);. Никогда не предполагайте, что приведение удастся. См. Главу 1.9.
Undefined variable 'X'Опечатка, неверная область видимости или неверный слойСначала проверьте правописание. Если переменная --- это класс из другого файла, убедитесь, что он определён в том же или нижнем слое. 3_Game не видит типы из 4_World. См. Главу 2.1.
Method 'X' not foundВызов метода, которого не существует у данного классаПроверьте имя метода и родительский класс. Возможно, нужно сначала привести к более конкретному типу. Проверьте ванильные скрипты в P:\DZ\scripts\ для корректного API.
Division by zeroДеление на переменную, равную 0Добавьте проверку: if (divisor != 0) result = value / divisor;. Это также относится к операциям модуля (%).
Redeclaration of variable 'X'Одно и то же имя переменной объявлено в соседних блоках else ifОбъявите переменную один раз перед цепочкой if/else, затем присваивайте значение внутри каждой ветки. См. Главу 1.12.
Member already definedДублирующееся имя переменной или метода в классеПроверьте на ошибки копирования/вставки. Каждое имя члена должно быть уникальным в иерархии классов (включая родительские классы).
Cannot create instance of type 'X'Попытка new для абстрактного класса или интерфейсаПроверьте, что класс не абстрактный (нет методов proto без тела). Создайте экземпляр конкретного подкласса.
Stack overflowБесконечная рекурсияМетод вызывает сам себя без базового случая, или переопределение в modded class не имеет должной защиты от повторного входа. Добавьте проверку глубины или исправьте рекурсивный вызов.
Index out of rangeОбращение к массиву с недопустимым индексомВсегда проверяйте array.Count() или используйте array.IsValidIndex(idx) перед обращением по индексу.
String conversion errorИспользование string.ToInt() или string.ToFloat() для нечислового текстаПроверяйте содержимое строки перед конвертацией. Поскольку try/catch отсутствует, проверка должна быть ручной.
Error: Serializer X mismatchПорядок чтения/записи не совпадает при сериализацииУбедитесь, что OnStoreSave() и OnStoreLoad() записывают и читают одни и те же типы в одном и том же порядке, включая проверки версий.
Синтаксическая ошибка без ясного сообщенияОбратная косая черта \ или экранированная кавычка \" в строковом литералеCParser Enforce Script не поддерживает \\ или \". Используйте прямые косые черты для путей ("my/path/file"). Для кавычек используйте одинарные кавычки. См. Главу 1.12.
JsonFileLoader возвращает nullПрисвоение возвращаемого значения JsonLoadFile()JsonLoadFile() возвращает void. Предварительно создайте объект и передайте его по ссылке: ref MyConfig cfg = new MyConfig(); JsonFileLoader<MyConfig>.JsonLoadFile(path, cfg);. См. Главу 6.8.
Object.IsAlive() не существуетВызов IsAlive() на базовом ObjectIsAlive() есть только у EntityAI. Сначала приведите тип: EntityAI entity; if (Class.CastTo(entity, obj) && entity.IsAlive()) { ... }
Тернарный оператор не поддерживаетсяИспользование синтаксиса condition ? a : bВ Enforce Script нет тернарного оператора. Используйте блок if/else. См. Главу 1.12.
Ошибка цикла do...whileИспользование do { } while(cond)Enforce Script не поддерживает do...while. Используйте цикл while с условием break. См. Главу 1.12.
Многострочный вызов метода не работаетНеправильное разделение одного вызова метода на несколько строкИзбегайте разделения цепочек вызовов с комментариями или директивами препроцессора между строками. Держите цепочки вызовов на одной строке или используйте промежуточные переменные.

3. Проблемы с RPC и сетью

Проблемы с удалёнными вызовами процедур и коммуникацией клиент-сервер.

СимптомПричинаИсправление
RPC отправлен, но не полученНесовпадение регистрацииОтправитель и получатель должны зарегистрировать один и тот же ID RPC. Убедитесь, что ID точно совпадает на клиенте и сервере. См. Главу 6.9.
RPC получен, но данные поврежденыНесовпадение параметров чтения/записиВызовы Write() отправителя и Read() получателя должны иметь одинаковые типы в одинаковом порядке. Одно несовпадение повреждает все последующие чтения.
RPC вызывает краш сервераNull-сущность как цель или неверные типы параметровУбедитесь, что целевая сущность существует на обеих сторонах. Никогда не отправляйте null как цель RPC. Проверяйте все прочитанные параметры перед использованием.
Данные не синхронизируются с клиентамиОтсутствует SetSynchDirty()После изменения любой переменной, зарегистрированной для синхронизации, вызовите SetSynchDirty() на сущности. Без этого движок не рассылает изменения.
Работает в одиночной игре / listen server, не работает на выделенномРазные пути кода для listen vs. выделенногоНа listen server клиент и сервер работают в одном процессе, скрывая проблемы таймингов и null. Всегда тестируйте на выделенном сервере. Проверяйте GetGame().IsServer() и GetGame().IsMultiplayer().
Флуд RPC и лаг сервераОтправка RPC каждый кадр или в тесных циклахОграничивайте вызовы RPC таймерами или аккумуляторами. Группируйте несколько мелких обновлений в один RPC. Используйте Net Sync Variables для часто меняющихся данных.
Клиент получает RPC, предназначенный для всехИспользование RPCSingleParam с неверной цельюИспользуйте null как параметр identity для широковещания или укажите конкретный PlayerIdentity для отправки одному клиенту.
OnRPC() никогда не вызываетсяПереопределение в неверном классе или слоеOnRPC() должен быть переопределён на сущности, которая получает RPC. При переопределении на PlayerBase убедитесь, что вызываете super.OnRPC(), чтобы другие моды продолжали работать.
Net Sync Variables не обновляются на клиентеОтсутствует RegisterNetSyncVariable*() или неверный типЗарегистрируйте каждую переменную в конструкторе с правильным методом (RegisterNetSyncVariableInt, RegisterNetSyncVariableFloat, RegisterNetSyncVariableBool). Переопределите OnVariablesSynchronized() для реакции на изменения на стороне клиента.
RPC работает для хоста, но не для других игроковИспользование ссылки на объект игрока вместо identityНа выделенных серверах хост-игрок не является особенным. Убедитесь, что используете PlayerIdentity для адресации, а не локальные ссылки на игрока, которые существуют только на машине отправителя.

4. Проблемы с интерфейсом

Проблемы с макетами GUI, виджетами, меню и вводом.

СимптомПричинаИсправление
Макет загружается, но ничего не видноРазмер виджета равен нулюПроверьте значения hexactsize и vexactsize. Оба должны быть больше нуля. Не используйте отрицательные размеры. См. Главу 3.3.
CreateWidgets() возвращает nullПуть к файлу макета неверен или файл отсутствуетУбедитесь, что путь к .layout файлу корректен (прямые косые черты, без опечаток). Движок молча возвращает null при неверных путях, ошибка не логируется.
Виджеты существуют, но не кликаютсяДругой виджет перекрывает кнопкуПроверьте priority виджета (z-порядок). Виджеты с более высоким приоритетом отрисовываются поверх и первыми перехватывают ввод. Также проверьте, что кнопка имеет ButtonWidget в качестве ScriptClass или является типом ButtonWidget.
Ввод в игре заблокирован / нельзя двигаться после закрытия UIНесбалансированные вызовы ChangeGameFocus()Каждый GetGame().GetInput().ChangeGameFocus(1) должен быть сопровождён ChangeGameFocus(-1). Отслеживайте смену фокуса и обеспечьте очистку даже при принудительном закрытии UI.
Текст показывает #STR_some_key буквальноЗапись в stringtable отсутствует или файл не загруженДобавьте ключ в ваш stringtable.csv. Проверьте, что CSV находится в корне мода и имеет правильный формат заголовка Language,Key,Original. См. Главу 5.1.
Курсор мыши не появляетсяНе вызван ShowUICursor()Вызовите GetGame().GetUIManager().ShowUICursor(true) при открытии UI. Вызовите с false при закрытии.
UI мерцает или отрисовывается за игровым миромМакет прикреплён к неверному родительскому виджетуПрикрепите макет к правильному родителю. Для полноэкранных оверлеев используйте GetGame().GetWorkspace() как родитель.
Содержимое ScrollWidget не прокручиваетсяСодержимое не внутри WrapSpacer или дочернего виджетаScrollWidget нужен один дочерний элемент (обычно WrapSpacer или FrameWidget), который больше области прокрутки. Поместите виджеты содержимого внутрь него. См. Главу 3.3.
Изображение или иконка не показываетсяПуть использует обратные косые черты или неверное расширениеИспользуйте прямые косые черты в путях к изображениям. Убедитесь, что файл существует и имеет распознаваемый формат (.paa, .edds). Используйте ImageWidget для изображений, а не TextWidget.
Слайдер не реагирует на вводОтсутствует скриптовый обработчик или неверный тип виджетаУбедитесь, что виджету слайдера назначен ScriptClass и что ваш обработчик обрабатывает события OnChange. Инициализируйте диапазон слайдера в скрипте.
UI выглядит иначе при других разрешенияхИспользование жёстко заданных пиксельных значенийИспользуйте пропорциональное масштабирование (halign, valign, hfill, vfill) вместо фиксированных пиксельных значений. Тестируйте при разных разрешениях. См. Главу 3.3.

5. Проблемы сборки и PBO

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

СимптомПричинаИсправление
"Include file not found" при бинаризацииКонфигурация ссылается на несуществующий файлПроверьте, что все пути #include в конфигурациях моделей и rvmat корректны. Убедитесь, что диск P: смонтирован и исходные файлы доступны.
PBO собирается успешно, но мод крашится при загрузкеОшибка бинаризации config.cppПопробуйте сборку с отключённой бинаризацией для изоляции проблемы. Если без бинаризации работает, проблема в конфигурации, которую бинаризатор отклоняет молча.
"Signature check failed" при подключении к серверуPBO не подписан или подписан неверным ключомПовторно подпишите PBO закрытым ключом с помощью DSSignFile. Убедитесь, что на сервере есть соответствующий .bikey в папке keys/.
Изменения file patching не применяютсяНе используется диагностический исполняемый файлFile patching работает только с DayZDiag_x64.exe, а не с розничным DayZ_x64.exe. Запускайте с параметром -filePatching.
Предупреждение "Prefix mismatch"Префикс PBO не совпадает с config.cppУбедитесь, что содержимое файла $PBOPREFIX$ совпадает с префиксом аддона, определённым в вашем config.cpp CfgPatches.
Addon Builder завершается молчаПуть содержит специальные символы или пробелыПереместите проект по пути без пробелов и специальных символов. Используйте короткие имена папок.
Бинаризованная модель выглядит неправильно в игреПроблемы с LOD или геометрией в P3DПроверьте LOD модели в Object Builder. Убедитесь, что LOD Fire Geometry и View Geometry корректны. Пересоберите модель.
Загружается старая версия мода несмотря на измененияКешированный PBO или версия Workshop перекрываетУдалите старый PBO. Проверьте, что игра не загружает кешированную версию из Workshop. Убедитесь, что путь -mod= указывает на папку разработки, а не на папку Workshop.
Addon Builder сообщает о предупреждениях "no entry"Конфигурация ссылается на несуществующее свойствоЭти предупреждения обычно не фатальны. Проверьте, что все базовые классы CfgVehicles существуют. Отсутствующие записи в унаследованных конфигурациях вызывают каскадные предупреждения.
PBO упаковывает ненужные файлыНет .pboignore или фильтраAddon Builder упаковывает всё в исходной папке. Используйте файл .pboignore или явно исключите типы файлов (.psd, .blend, .bak) в настройках сборщика.

6. Проблемы производительности

Падение FPS сервера или клиента, проблемы с памятью и медленные операции.

СимптомПричинаИсправление
Низкий FPS сервера (ниже 20)Тяжёлая обработка в OnUpdate() или покадровых методахИспользуйте аккумулятор delta-time для ограничения нагрузки: выполняйте логику только каждые N секунд. Перенесите дорогие операции на таймеры или отложенные обратные вызовы. См. Главу 7.7.
Память растёт со временем (утечка памяти)Циклы ссылок ref, препятствующие сборке мусораКогда два объекта держат ссылки ref друг на друга, ни один из них никогда не освобождается. Сделайте одну сторону обычной (не ref) ссылкой. Разрывайте циклы в методах очистки. См. Главу 1.8.
Медленный запуск сервераТяжёлая инициализация в OnInitОткладывайте некритичную инициализацию с помощью GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(). Загружайте конфигурации лениво при первом использовании вместо загрузки всех при старте.
FPS клиента падает возле определённых объектовСложная модель с слишком большим количеством полигонов или плохими LODДобавьте правильные уровни LOD к вашей модели. Движок использует LOD для уменьшения количества полигонов на расстоянии. Убедитесь, что переходы между LOD плавные.
Подёргивания каждые несколько секундПериодические пики сборки мусораУменьшите оборот объектов. Переиспользуйте объекты через пулинг вместо постоянного создания и уничтожения. Предварительно выделяйте массивы.
Сетевые лагиСлишком много RPC или большие полезные нагрузки RPCГруппируйте мелкие обновления в меньшее число RPC. Используйте Net Sync Variables для часто меняющихся значений. Сжимайте данные по возможности.
Файл лога растёт очень быстроИзбыточное использование Print() или отладочного логированияУдалите или оградите отладочные вызовы Print() за #ifdef DEVELOPER или флагом отладки. Большие файлы логов могут замедлять дисковый ввод-вывод.
Большое количество сущностей вызывает лаг сервераСлишком много заспавненных сущностей в миреУменьшите значения nominal в types.xml. Очищайте динамические объекты с управлением временем жизни. Ограничьте плотность спавна ИИ.

7. Проблемы с предметами, транспортом и сущностями

Проблемы с пользовательскими предметами, транспортными средствами и мировыми сущностями.

СимптомПричинаИсправление
Предмет не спавнится (админ-инструменты говорят "cannot create")scope=0 в конфигурации или отсутствие в types.xmlУстановите scope=2 в конфигурации CfgVehicles вашего предмета для предметов, которые должны быть доступны для спавна. Добавьте запись в types.xml сервера, если предмет должен появляться в луте.
Предмет спавнится, но невидимПуть к модели (.p3d) неверен или отсутствуетПроверьте путь model в вашем классе CfgVehicles. Используйте прямые косые черты. Убедитесь, что файл .p3d существует и упакован в PBO.
У предмета нет иконки в инвентареОтсутствует или неверный inventorySlot или конфигурация иконкиОпределите путь picture в конфигурации, указывающий на валидный файл иконки .paa или .edds. Проверьте rotationFlags для правильной ориентации иконки.
Транспорт спавнится, но не едетОтсутствует двигатель, колёса или деталиУбедитесь, что все необходимые детали установлены. Используйте OnDebugSpawn() для спавна полностью собранного транспорта для тестирования. Проверьте правильность типа симуляции в конфигурации.
Предмет нельзя подобратьНеправильная геометрия или неверный inventorySlotУбедитесь, что у предмета есть правильная Fire Geometry в модели. Проверьте, что itemSize[] установлен корректно и предмет помещается в доступные слоты инвентаря.
Сущность немедленно удаляется после спавнаlifetime равен нулю в types.xml или проблема с scopeУстановите подходящее значение lifetime в types.xml. Убедитесь, что scope=2 в конфигурации. Проверьте настройки очистки сервера в globals.xml.
Пользовательское животное/зомби не двигаетсяКонфигурация ИИ отсутствует или поврежденаПроверьте AIAgentType в конфигурации. Убедитесь, что сущность имеет геометрию, совместимую с NavMesh. Сначала протестируйте с ванильными конфигурациями ИИ.
Вложения не крепятся к предметуНеверные имена inventorySlotИмена слотов вложений должны точно совпадать между attachments[] родительского предмета и inventorySlot[] дочернего предмета. Имена чувствительны к регистру.
Зоны урона предмета не работаютНесоответствие конфигурации DamageSystem и моделиКаждое имя DamageZone должно совпадать с именованным выделением в LOD Fire Geometry модели. Проверьте в Object Builder. См. Главу 6.1.
Пользовательский звук не воспроизводитсяНеверный звуковой шейдер или путь в конфигурацииПроверьте имя класса звукового шейдера в CfgSoundShaders и CfgSoundSets. Убедитесь, что путь к файлу .ogg корректен и файл упакован в PBO.
У предмета неправильный вес или размерЗначения weight и itemSize[] в конфигурацииweight указывается в граммах (целое число). itemSize[] определяет ячейки сетки инвентаря как {ширина, высота}. Проверьте значения родительского класса при наследовании.
Рецепт крафта не появляетсяНеверная конфигурация рецепта или условияПроверьте регистрацию CfgRecipes. Убедитесь, что оба ингредиента имеют корректные свойства canBeSplit, isMeleeWeapon или другие необходимые. Тестируйте с ванильными конфигурациями рецептов как образцом.

8. Проблемы с конфигурацией и types

Проблемы с config.cpp, types.xml и другими конфигурационными файлами.

СимптомПричинаИсправление
Значения конфигурации не применяютсяИспользуется бинаризованная конфигурация, но редактируется исходникПересоберите PBO после изменений конфигурации. При использовании file patching убедитесь, что активны DayZDiag_x64.exe и -filePatching.
Изменения в types.xml игнорируютсяРедактируется неправильный файл types.xmlСервер загружает types из mpmissions/your_mission/db/types.xml. Редактирование файла types в другом месте не даёт эффекта. Проверьте активную папку миссии сервера.
"Error loading types" при запуске сервераСинтаксическая ошибка XML в types.xmlПроверьте XML. Частые проблемы: незакрытые теги, отсутствующие кавычки у значений атрибутов или & вместо &amp;. Используйте XML-валидатор.
Предметы спавнятся с неверным количествомНеверные значения quantmin/quantmaxЗначения указываются в процентах (0-100) в types.xml, а не в абсолютных числах. -1 означает "использовать значение по умолчанию".
Таблица лута не спавнит предметыnominal равен 0 или отсутствует category/usage/tagУстановите nominal больше 0. Добавьте хотя бы один тег <usage> и <category>, чтобы Центральная экономика знала, где спавнить предметы.
JSON-файл конфигурации не загружаетсяНекорректный JSON или неверный путьПроверьте синтаксис JSON (нет висящих запятых, правильное кавычение). Используйте префикс $profile: для путей серверного профиля. Проверьте существование файла с помощью FileExist().
Изменения cfgGameplay.json игнорируютсяФайл не включён или находится в неверном местеПоместите файл в папку миссии. Установите enableCustomGameplay в 1 в serverDZ.cfg. Перезапустите сервер (не просто перезагрузку).
Наследование классов не работает в конфигурацииbaseClass написан с ошибкой или не загруженРодительский класс должен существовать в том же или более раннем аддоне. Проверьте, что requiredAddons[] включает аддон, определяющий родительский класс.

9. Проблемы с персистентностью

Проблемы с сохранением и загрузкой данных между перезапусками сервера.

СимптомПричинаИсправление
Данные игрока потеряны после перезапускаНе сохраняется в каталог $profile:Используйте JsonFileLoader<T>.JsonSaveFile() с путём $profile:. Сохраняйте при отключении игрока (PlayerDisconnected) и периодически во время игры.
Сохранённый файл пуст или повреждёнКраш во время записи или ошибка сериализацииСначала записывайте во временный файл, затем переименовывайте в итоговый путь. Проверяйте данные перед сохранением. Всегда обрабатывайте проверки FileExist() при загрузке.
Несовпадение OnStoreSave/OnStoreLoadВерсия изменилась, но миграция не выполненаВсегда записывайте номер версии первым. При загрузке читайте версию и обрабатывайте старые форматы: if (version < CURRENT) { /* чтение старого формата */ }.
Предметы исчезают из хранилищаlifetime истёк в types.xmlУвеличьте lifetime для персистентных предметов. Значение по умолчанию часто слишком короткое для контейнеров строительства баз. Проверьте значение cleanupLifetimeRuin в globals.xml.
Пользовательские переменные сбрасываются при перезаходеПеременные не синхронизированы или не сохраненыЗарегистрируйте переменные для сетевой синхронизации с помощью RegisterNetSyncVariable*(). Для персистентности сохраняйте/загружайте в OnStoreSave()/OnStoreLoad().

10. Блок-схемы принятия решений

Пошаговые диагностические процессы для распространённых ситуаций "это не работает".

"Мой мод вообще не работает"

  1. Проверьте лог скриптов на наличие ошибок SCRIPT (E). Исправьте первую найденную ошибку. (Раздел 2)
  2. Мод отображается в лаунчере? Если нет, проверьте существование и валидность mod.cpp. (Раздел 1)
  3. Лог упоминает ваш класс CfgPatches? Если нет, проверьте синтаксис config.cpp, requiredAddons[] и параметр запуска -mod=.
  4. Скрипты компилируются? Ищите ошибки компиляции в RPT. Исправьте все синтаксические ошибки. (Раздел 2)
  5. Есть ли точка входа? Вам нужен modded class MissionServer/MissionGameplay, зарегистрированный модуль или плагин. Скрипты без точки входа никогда не запускаются.
  6. Всё ещё ничего? Добавьте Print("MY_MOD: Init reached"); в вашу точку входа для подтверждения выполнения.

"Работает офлайн, но не на выделенном сервере"

  1. Мод установлен на сервере? Проверьте, что -mod= включает путь к моду и PBO находится в @YourMod/Addons/.
  2. Клиентский код на сервере? GetGame().GetPlayer() возвращает null во время инициализации сервера. Добавьте проверки GetGame().IsServer() / GetGame().IsClient().
  3. RPC работают? Добавьте Print() на обеих сторонах --- отправки и получения. Проверьте совпадение ID RPC и существование целевой сущности на обеих сторонах. (Раздел 3)
  4. Данные синхронизируются? Убедитесь, что SetSynchDirty() вызывается после изменений. Проверьте совпадение порядка параметров чтения/записи.
  5. Проблемы таймингов? Listen server скрывает состояния гонки, потому что клиент и сервер делят один процесс. Выделенные серверы выявляют их. Добавьте проверки на null и условия готовности.

"Мой UI сломан"

  1. CreateWidgets() возвращает null? Путь к макету неверен или файл отсутствует. Проверьте прямые косые черты, убедитесь, что .layout упакован в PBO.
  2. Виджеты существуют, но невидимы? Проверьте размеры (должны быть > 0, без отрицательных значений). Проверьте вызов Show(true). Проверьте, что альфа текста/виджета не 0.
  3. Видимы, но не кликаются? Проверьте priority виджета (z-порядок). Убедитесь, что ScriptClass назначен. Подтвердите установку обработчика.
  4. Ввод заблокирован после закрытия UI? Несбалансированные вызовы ChangeGameFocus(). Каждый ChangeGameFocus(1) требует парного ChangeGameFocus(-1). Проверьте, что очистка выполняется даже при принудительном закрытии.

11. Краткая справка по командам отладки

Используйте их в отладочной консоли DayZDiag или админ-инструментах.

ДействиеКоманда
Заспавнить предмет на землеGetGame().CreateObject("AKM", GetGame().GetPlayer().GetPosition());
Заспавнить транспорт (собранный)EntityAI car = EntityAI.Cast(GetGame().CreateObject("OffroadHatchback", GetGame().GetPlayer().GetPosition())); if (car) car.OnDebugSpawn();
Заспавнить зомбиGetGame().CreateObject("ZmbM_Normal_00", GetGame().GetPlayer().GetPosition());
Телепорт по координатамGetGame().GetPlayer().SetPosition("6543 0 2114".ToVector());
Полное исцелениеGetGame().GetPlayer().SetHealth("", "", 5000);
Полная кровьGetGame().GetPlayer().SetHealth("", "Blood", 5000);
Остановить потерю сознанияGetGame().GetPlayer().SetHealth("", "Shock", 0);
Установить полденьGetGame().GetWorld().SetDate(2024, 9, 15, 12, 0);
Установить ночьGetGame().GetWorld().SetDate(2024, 9, 15, 2, 0);
Ясная погодаGetGame().GetWeather().GetOvercast().Set(0,0,0); GetGame().GetWeather().GetRain().Set(0,0,0);
Сильный дождьGetGame().GetWeather().GetOvercast().Set(1,0,0); GetGame().GetWeather().GetRain().Set(1,0,0);
Вывести позициюPrint(GetGame().GetPlayer().GetPosition());
Проверить сервер/клиентPrint("IsServer: " + GetGame().IsServer().ToString());
Вывести FPSPrint("FPS: " + (1.0 / GetGame().GetDeltaT()).ToString());

Известные локации Черноруси: Электро "10570 0 2354", Черно "6649 0 2594", СЗАФ "4494 0 10365", Тиси "1693 0 13575", Березино "12121 0 9216"

Параметры запуска

ПараметрНазначение
-filePatchingЗагрузка распакованных файлов (требуется DayZDiag)
-scriptDebug=trueВключение функций отладки скриптов
-doLogsВключение подробного логирования
-adminLogВключение админ-лога на сервере
-freezeCheckОбнаружение и логирование зависаний скриптов
-noSoundОтключение звука (быстрее тестирование)
-noPauseСервер не приостанавливается, когда пуст
-profiles=<path>Пользовательский каталог профиля/логов
-connect=<ip>Автоматическое подключение к серверу при запуске
-port=<port>Порт сервера (по умолчанию 2302)
-mod=@Mod1;@Mod2Загрузка модов (разделённых точкой с запятой)
-serverMod=@ModСерверные моды (не отправляются клиентам)

12. Расположение файлов логов

Знать, где искать --- это половина дела.

Клиентские логи

ЛогРасположениеСодержимое
Лог скриптов%localappdata%\DayZ\ (последний файл .RPT)Ошибки скриптов, предупреждения, вывод Print()
Дампы крашей%localappdata%\DayZ\ (файлы .mdmp)Данные для анализа крашей
Лог WorkbenchПанель вывода Workbench IDEОшибки компиляции во время разработки

Серверные логи

ЛогРасположениеСодержимое
Лог скриптов<server_root>\profiles\ (последний файл .RPT)Ошибки скриптов, серверный Print()
Админ-лог<server_root>\profiles\ (файл .ADM)Подключения игроков, убийства, чат
Дампы крашей<server_root>\profiles\ (файлы .mdmp)Данные крашей сервера
Пользовательские логи<server_root>\profiles\Любые логи, записанные через FileHandle

Эффективное чтение логов

  • Ищите SCRIPT (E) для нахождения ошибок скриптов
  • Ищите SCRIPT ERROR для нахождения фатальных проблем со скриптами
  • Ищите имя вашего мода или классов для фильтрации релевантных записей
  • Ошибки часто каскадируются --- исправляйте первую ошибку в логе, а не последнюю
  • Отмечайте время каждого чтения лога: последний файл .RPT содержит данные последней сессии

13. Где получить помощь

Когда это руководство не решает вашу проблему, вот лучшие ресурсы.

Ресурсы сообщества

РесурсURLЛучше всего для
DayZ Modding Discorddiscord.gg/dayzmodsПомощь в реальном времени от опытных моддеров
Форумы Bohemia Interactiveforums.bohemia.net/forums/forum/231-dayz-modding/Официальные форумы, объявления
DayZ Feedback Trackerfeedback.bistudio.com/tag/dayz/Официальные отчёты об ошибках
DayZ WorkshopSteam Workshop (DayZ)Просмотр опубликованных модов для справки
Bohemia Wikicommunity.bistudio.com/wiki/DayZ:Modding_BasicsОфициальные основы моддинга

Справочный исходный код

Изучайте эти моды для освоения паттернов от опытных моддеров:

МодЧему можно научиться
Community Framework (CF)Жизненный цикл модулей, управление RPC, логирование, управляемые указатели
DayZ ExpansionМасштабная архитектура мода, система маркета, транспорт, группы
Community Online Tools (COT)Админ-инструменты, права доступа, паттерны UI, управление игроками
VPP Admin ToolsАдминистрирование сервера, права доступа, ESP, телепортация
Dabs FrameworkПаттерн MVC, привязка данных, фреймворк UI-компонентов
BuilderItemsПростая структура мода предметов (хороший начальный пример)
BaseBuildingPlusСистема строительства, механика размещения, персистентность

Справочник ванильных скриптов

Авторитетный справочник по всем классам и методам движка:

  • Смонтируйте диск P: через DayZ Tools
  • Перейдите к P:\DZ\scripts\
  • Организовано по слоям: 3_Game/, 4_World/, 5_Mission/
  • Используйте поиск вашего редактора для нахождения любого ванильного класса, метода или перечисления

Краткий чек-лист перед обращением за помощью

Прежде чем публиковать вопрос на форуме или в Discord, соберите эту информацию:

  1. Что вы ожидали --- что должно было произойти
  2. Что произошло на самом деле (точные сообщения об ошибках, поведение)
  3. Фрагмент лога скриптов (соответствующие строки SCRIPT (E), а не весь лог)
  4. Ваш код (соответствующий фрагмент, а не весь мод)
  5. Что вы уже попробовали (экономит время всем)
  6. Версия DayZ и список модов (совместимость имеет значение)
  7. Клиент или сервер (укажите, на какой стороне проблема)

Алфавитный указатель симптомов

Не можете найти свою проблему в разделах выше? Попробуйте этот алфавитный указатель.

Симптом (что вы видите)Перейти к
Addon Builder не работаетРаздел 5
Array index out of rangeРаздел 2
Кнопки не кликаютсяРаздел 4
Cannot convert typeРаздел 2
Cannot create instanceРаздел 2
Config parse errorРаздел 1
Курсор отсутствуетРаздел 4
Division by zeroРаздел 2
Данные потеряны после перезапускаРаздел 9
Сущность удаляется после спавнаРаздел 7
File patching не работаетРаздел 5
Падение FPSРаздел 6
Ввод в игре заблокированРаздел 4
Изображение не отображаетсяРаздел 4
Предмет невидимРаздел 7
Предмет не спавнитсяРаздел 7
JSON не загружаетсяРаздел 8
Макет возвращает nullРаздел 4
Лут не спавнитсяРаздел 8
Member already definedРаздел 2
Утечка памятиРаздел 6
Method not foundРаздел 2
Мод не в лаунчереРаздел 1
Null pointer accessРаздел 2
Данные игрока потеряныРаздел 9
PBO подпись не прошлаРаздел 5
Prefix mismatchРаздел 5
RPC не полученРаздел 3
Прокрутка не работаетРаздел 4
Файл сохранения повреждёнРаздел 9
Краш сервера при запускеРаздел 2
Слайдер не реагируетРаздел 4
Stack overflowРаздел 2
Текст показывает STR-ключРаздел 4
Types.xml игнорируетсяРаздел 8
Undefined variableРаздел 2
Variable redeclarationРаздел 2
Транспорт не едетРаздел 7
Виджет невидимРаздел 4
Работает офлайн, не работает онлайнРаздел 3

Проблема всё ещё не решена? Проверьте ЧаВо для дополнительных ответов, Шпаргалку для справки по синтаксису или спросите в DayZ Modding Discord.

Released under CC BY-SA 4.0 | Code examples under MIT License