Руководство по устранению неполадок
Главная | Устранение неполадок
Когда что-то идёт не так, начните здесь. Это руководство организовано по тому, что вы видите (симптому), а не по системе. Найдите свою проблему, прочитайте причину, примените исправление.
Содержание
- Мод не загружается
- Ошибки скриптов
- Проблемы с RPC и сетью
- Проблемы с интерфейсом
- Проблемы сборки и PBO
- Проблемы производительности
- Проблемы с предметами, транспортом и сущностями
- Проблемы с конфигурацией и types
- Проблемы с персистентностью
- Блок-схемы принятия решений
- Краткая справка по командам отладки
- Расположение файлов логов
- Где получить помощь
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() на базовом Object | IsAlive() есть только у 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. Частые проблемы: незакрытые теги, отсутствующие кавычки у значений атрибутов или & вместо &. Используйте 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. Блок-схемы принятия решений
Пошаговые диагностические процессы для распространённых ситуаций "это не работает".
"Мой мод вообще не работает"
- Проверьте лог скриптов на наличие ошибок
SCRIPT (E). Исправьте первую найденную ошибку. (Раздел 2) - Мод отображается в лаунчере? Если нет, проверьте существование и валидность
mod.cpp. (Раздел 1) - Лог упоминает ваш класс CfgPatches? Если нет, проверьте синтаксис
config.cpp,requiredAddons[]и параметр запуска-mod=. - Скрипты компилируются? Ищите ошибки компиляции в RPT. Исправьте все синтаксические ошибки. (Раздел 2)
- Есть ли точка входа? Вам нужен
modded class MissionServer/MissionGameplay, зарегистрированный модуль или плагин. Скрипты без точки входа никогда не запускаются. - Всё ещё ничего? Добавьте
Print("MY_MOD: Init reached");в вашу точку входа для подтверждения выполнения.
"Работает офлайн, но не на выделенном сервере"
- Мод установлен на сервере? Проверьте, что
-mod=включает путь к моду и PBO находится в@YourMod/Addons/. - Клиентский код на сервере?
GetGame().GetPlayer()возвращаетnullво время инициализации сервера. Добавьте проверкиGetGame().IsServer()/GetGame().IsClient(). - RPC работают? Добавьте
Print()на обеих сторонах --- отправки и получения. Проверьте совпадение ID RPC и существование целевой сущности на обеих сторонах. (Раздел 3) - Данные синхронизируются? Убедитесь, что
SetSynchDirty()вызывается после изменений. Проверьте совпадение порядка параметров чтения/записи. - Проблемы таймингов? Listen server скрывает состояния гонки, потому что клиент и сервер делят один процесс. Выделенные серверы выявляют их. Добавьте проверки на null и условия готовности.
"Мой UI сломан"
CreateWidgets()возвращает null? Путь к макету неверен или файл отсутствует. Проверьте прямые косые черты, убедитесь, что.layoutупакован в PBO.- Виджеты существуют, но невидимы? Проверьте размеры (должны быть > 0, без отрицательных значений). Проверьте вызов
Show(true). Проверьте, что альфа текста/виджета не 0. - Видимы, но не кликаются? Проверьте
priorityвиджета (z-порядок). Убедитесь, чтоScriptClassназначен. Подтвердите установку обработчика. - Ввод заблокирован после закрытия 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()); |
| Вывести FPS | Print("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 Discord | discord.gg/dayzmods | Помощь в реальном времени от опытных моддеров |
| Форумы Bohemia Interactive | forums.bohemia.net/forums/forum/231-dayz-modding/ | Официальные форумы, объявления |
| DayZ Feedback Tracker | feedback.bistudio.com/tag/dayz/ | Официальные отчёты об ошибках |
| DayZ Workshop | Steam Workshop (DayZ) | Просмотр опубликованных модов для справки |
| Bohemia Wiki | community.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, соберите эту информацию:
- Что вы ожидали --- что должно было произойти
- Что произошло на самом деле (точные сообщения об ошибках, поведение)
- Фрагмент лога скриптов (соответствующие строки
SCRIPT (E), а не весь лог) - Ваш код (соответствующий фрагмент, а не весь мод)
- Что вы уже попробовали (экономит время всем)
- Версия DayZ и список модов (совместимость имеет значение)
- Клиент или сервер (укажите, на какой стороне проблема)
Алфавитный указатель симптомов
Не можете найти свою проблему в разделах выше? Попробуйте этот алфавитный указатель.
| Симптом (что вы видите) | Перейти к |
|---|---|
| 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.
