Глава 2.4: Ваш первый мод — минимально жизнеспособный
Главная | << Назад: mod.cpp и Workshop | Минимально жизнеспособный мод | Далее: Организация файлов >>
Краткое описание: Эта глава проведёт вас через создание наименьшего возможного мода DayZ с нуля. К концу у вас будет работающий мод, который выводит сообщение в скриптовый лог при запуске игры. Три файла, ноль зависимостей, менее пяти минут.
Содержание
- Что вам нужно
- Цель
- Шаг 1: Создание структуры каталогов
- Шаг 2: Создание mod.cpp
- Шаг 3: Создание config.cpp
- Шаг 4: Создание вашего первого скрипта
- Шаг 5: Сборка и тестирование
- Шаг 6: Проверка работоспособности
- Что произошло
- Следующие шаги
- Устранение неполадок
Что вам нужно
- Установленная игра DayZ (розничная версия или DayZ Tools/Diag)
- Текстовый редактор (VS Code, Notepad++ или любой текстовый редактор)
- Установленные DayZ Tools (для упаковки PBO) — ИЛИ вы можете тестировать без упаковки (см. Шаг 5)
Цель
Мы создадим мод под названием HelloMod, который:
- Загружается в DayZ без ошибок
- Выводит
"[HelloMod] Mission started!"в скриптовый лог - Использует правильную стандартную структуру
Это DayZ-эквивалент «Hello World».
Шаг 1: Создание структуры каталогов
Создайте следующие папки и файлы. Вам нужно ровно 3 файла:
HelloMod/
mod.cpp
Scripts/
config.cpp
5_Mission/
HelloMod/
HelloMission.cЭто полная структура. Давайте создадим каждый файл.
Шаг 2: Создание mod.cpp
Создайте HelloMod/mod.cpp с таким содержимым:
name = "Hello Mod";
author = "YourName";
version = "1.0";
overview = "My first DayZ mod - prints a message on mission start.";Это минимальные метаданные. Лаунчер DayZ покажет «Hello Mod» в списке модов.
Шаг 3: Создание config.cpp
Создайте HelloMod/Scripts/config.cpp с таким содержимым:
class CfgPatches
{
class HelloMod_Scripts
{
units[] = {};
weapons[] = {};
requiredVersion = 0.1;
requiredAddons[] =
{
"DZ_Data"
};
};
};
class CfgMods
{
class HelloMod
{
dir = "HelloMod";
name = "Hello Mod";
author = "YourName";
type = "mod";
dependencies[] = { "Mission" };
class defs
{
class missionScriptModule
{
value = "";
files[] = { "HelloMod/Scripts/5_Mission" };
};
};
};
};Разберём, что делает каждая часть:
- CfgPatches объявляет мод движку.
requiredAddonsуказывает, что мы зависим отDZ_Data(базовые данные ванильного DayZ), что гарантирует загрузку после базовой игры. - CfgMods сообщает движку, где находятся наши скрипты. Мы используем только
5_Mission, потому что именно там доступны хуки жизненного цикла миссий. - dependencies перечисляет
"Mission", потому что наш код подключается к скриптовому модулю миссий.
Шаг 4: Создание вашего первого скрипта
Создайте HelloMod/Scripts/5_Mission/HelloMod/HelloMission.c с таким содержимым:
modded class MissionServer
{
override void OnInit()
{
super.OnInit();
Print("[HelloMod] Mission started! Server is running.");
}
};
modded class MissionGameplay
{
override void OnInit()
{
super.OnInit();
Print("[HelloMod] Mission started! Client is running.");
}
};Что это делает:
modded class MissionServerрасширяет ванильный класс серверной миссии. Когда сервер запускает миссию, вызываетсяOnInit()и выводится наше сообщение.modded class MissionGameplayделает то же самое для клиентской стороны.super.OnInit()вызывает оригинальную (ванильную) реализацию первой — это критически важно. Никогда не пропускайте этот вызов.Print()записывает в файл скриптового лога DayZ.
Шаг 5: Сборка и тестирование
У вас два варианта тестирования:
Вариант A: File Patching (без PBO — только для разработки)
DayZ поддерживает загрузку неупакованных модов во время разработки. Это самый быстрый способ итерации.
- Поместите вашу папку
HelloMod/в каталог установки DayZ (или используйте диск P: с Workbench) - Запустите DayZ с параметром
-filePatchingи загрузите ваш мод:
DayZDiag_x64.exe -mod=HelloMod -filePatchingЭто загружает скрипты напрямую из папки без упаковки в PBO.
Вариант B: Упаковка в PBO (обязательно для распространения)
Для публикации в Workshop или развёртывания на сервере нужна упаковка в PBO:
- Откройте DayZ Tools (из Steam)
- Откройте Addon Builder
- Установите исходный каталог на
HelloMod/Scripts/ - Установите выходной путь на
@HelloMod/Addons/HelloMod_Scripts.pbo - Нажмите Pack
Или используйте упаковщик командной строки вроде PBOConsole:
PBOConsole.exe -pack HelloMod/Scripts @HelloMod/Addons/HelloMod_Scripts.pboРазместите mod.cpp рядом с папкой Addons/:
@HelloMod/
mod.cpp
Addons/
HelloMod_Scripts.pboЗатем запустите DayZ:
DayZDiag_x64.exe -mod=@HelloModШаг 6: Проверка работоспособности
Поиск скриптового лога
DayZ записывает вывод скриптов в файлы логов в каталоге вашего профиля:
Windows: C:\Users\YourName\AppData\Local\DayZ\Ищите самый свежий .RPT или .log файл. Скриптовый лог обычно называется:
script_<дата>_<время>.logЧто искать
Откройте файл лога и найдите [HelloMod]. Вы должны увидеть:
[HelloMod] Mission started! Server is running.или (если вы подключились как клиент):
[HelloMod] Mission started! Client is running.Если вы видите это сообщение — поздравляем, ваш мод работает.
Если вы видите ошибки
Если лог содержит строки, начинающиеся с SCRIPT (E):, что-то пошло не так. Смотрите раздел Устранение неполадок ниже.
Что произошло
Вот последовательность событий при загрузке вашего мода в DayZ:
1. Движок запускается, читает файлы config.cpp из всех PBO
2. CfgPatches "HelloMod_Scripts" зарегистрирован
--> requiredAddons гарантирует загрузку после DZ_Data
3. CfgMods "HelloMod" зарегистрирован
--> Движок знает о пути missionScriptModule
4. Движок компилирует скрипты 5_Mission всех модов
--> HelloMission.c скомпилирован
--> "modded class MissionServer" патчит ванильный класс
5. Сервер запускает миссию
--> Вызывается MissionServer.OnInit()
--> Ваш override запускается, сначала вызывая super.OnInit()
--> Print() записывает в скриптовый лог
6. Клиент подключается и загружается
--> Вызывается MissionGameplay.OnInit()
--> Ваш override запускается
--> Print() записывает в клиентский логКлючевое слово modded — ключевой механизм. Оно говорит движку «возьми существующий класс и добавь мои изменения поверх». Так каждый мод DayZ интегрируется с ванильным кодом.
Следующие шаги
Теперь, когда у вас есть работающий мод, вот естественные направления развития:
Добавление слоя 3_Game
Добавьте конфигурационные данные или константы, не зависящие от мировых сущностей:
HelloMod/
Scripts/
config.cpp <-- Добавить запись gameScriptModule
3_Game/
HelloMod/
HelloConfig.c <-- Класс конфигурации
5_Mission/
HelloMod/
HelloMission.c <-- Существующий файлОбновите config.cpp, чтобы включить новый слой:
dependencies[] = { "Game", "Mission" };
class defs
{
class gameScriptModule
{
value = "";
files[] = { "HelloMod/Scripts/3_Game" };
};
class missionScriptModule
{
value = "";
files[] = { "HelloMod/Scripts/5_Mission" };
};
};Добавление слоя 4_World
Создавайте пользовательские предметы, расширяйте игроков или добавляйте менеджеры мира:
HelloMod/
Scripts/
config.cpp <-- Добавить запись worldScriptModule
3_Game/
HelloMod/
HelloConfig.c
4_World/
HelloMod/
HelloManager.c <-- Логика, связанная с миром
5_Mission/
HelloMod/
HelloMission.cДобавление UI
Создайте простую игровую панель (рассматривается в Части 3 этого руководства):
HelloMod/
GUI/
layouts/
hello_panel.layout <-- Файл компоновки UI
Scripts/
5_Mission/
HelloMod/
HelloPanel.c <-- Скрипт UIДобавление пользовательского предмета
Определите предмет в Data/config.cpp и создайте его скриптовое поведение в 4_World:
HelloMod/
Data/
config.cpp <-- CfgVehicles с определением предмета
Models/
hello_item.p3d <-- 3D-модель
Scripts/
4_World/
HelloMod/
HelloItem.c <-- Скрипт поведения предметаЗависимость от фреймворка
Если вы хотите использовать возможности Community Framework (CF), добавьте зависимость:
// В config.cpp
requiredAddons[] = { "DZ_Data", "JM_CF_Scripts" };Устранение неполадок
«Addon HelloMod_Scripts requires addon DZ_Data which is not loaded»
Ваш requiredAddons ссылается на аддон, который отсутствует. Убедитесь, что DZ_Data написан правильно и базовая игра DayZ загружена.
Нет вывода в лог (мод, похоже, не загрузился)
Проверьте по порядку:
- Указан ли мод в параметре запуска? Убедитесь, что
-mod=HelloModили-mod=@HelloModесть в вашей команде запуска. - Находится ли config.cpp в правильном месте? Он должен быть в корне PBO (или в корне папки
Scripts/при использовании file-patching). - Правильны ли пути к скриптам? Пути
files[]вconfig.cppдолжны совпадать с реальной структурой каталогов."HelloMod/Scripts/5_Mission"означает, что движок ищет именно этот путь. - Есть ли класс CfgPatches? Без него PBO игнорируется.
SCRIPT (E): Undefined variable / Undefined type
Ваш код ссылается на то, что не существует на этом слое. Частые причины:
- Ссылка на
PlayerBaseиз3_Game(он определён в4_World) - Опечатка в имени класса или переменной
- Пропущенный вызов
super.OnInit()(вызывает каскадные сбои)
SCRIPT (E): Member not found
Метод или свойство, которое вы вызываете, не существует в этом классе. Перепроверьте ванильный API. Частая ошибка: вызов методов из более новой версии DayZ при запуске более старой.
Мод загружается, но скрипт не выполняется
- Проверьте, что ваш
.cфайл находится внутри каталога, указанного вfiles[] - Убедитесь, что файл имеет расширение
.c(не.txtили.cs) - Проверьте, что имя
modded classточно совпадает с ванильным классом (с учётом регистра)
Ошибки упаковки PBO
- Убедитесь, что
config.cppнаходится на корневом уровне внутри PBO - Пути внутри PBO используют прямые слеши (
/), а не обратные - Убедитесь, что в папке Scripts нет бинарных файлов (только
.cи.cpp)
Лучшие практики
- Всегда вызывайте
super.OnInit()перед вашим кодом в модифицированных классах миссий — пропуск ломает инициализацию других модов. - Используйте уникальный префикс в сообщениях
Print()(например,[HelloMod]), чтобы можно было быстро найти по логам. - Начинайте только с
5_Mission. Добавляйте слои3_Gameи4_Worldпостепенно по мере роста мода. - Используйте
-filePatchingво время разработки, чтобы не переупаковывать PBO при каждом изменении. - Держите первый мод в пределах 3 файлов, пока он не заработает, затем расширяйте. Отладка минимальной структуры гораздо проще.
Теория и практика
| Концепция | Теория | Реальность |
|---|---|---|
Print() выводит в лог | Сообщения появляются в скриптовом логе | Вывод идёт в файл .RPT, а не в отдельный скриптовый лог. На выделенных серверах проверяйте серверный RPT в папке профиля |
-filePatching загружает распакованные файлы | Неупакованные моды работают мгновенно | Некоторые ассеты (модели, текстуры) всё равно требуют упаковки в PBO; скрипты работают распакованными, но файлы .layout могут не загружаться из неупакованных папок на всех конфигурациях |
modded class патчит ванильный | Ваш override заменяет оригинал | Несколько модов могут выполнить modded class одного класса; они выстраиваются в цепочку по порядку загрузки. Если один пропускает super.OnInit(), все последующие моды ломаются |
DZ_Data — единственная нужная зависимость | Минимальный requiredAddons | Работает для чисто скриптовых модов, но если вы ссылаетесь на ванильный класс оружия/предмета, вам также нужен DZ_Scripts или конкретный ванильный PBO |
| Трёх файлов достаточно | Мод загружается с mod.cpp + config.cpp + один .c файл | Верно для чисто скриптового мода, но добавление предметов или UI требует дополнительных PBO (Data, GUI) |
Полный листинг файлов
Для справки — все три файла полностью:
HelloMod/mod.cpp
name = "Hello Mod";
author = "YourName";
version = "1.0";
overview = "My first DayZ mod - prints a message on mission start.";HelloMod/Scripts/config.cpp
class CfgPatches
{
class HelloMod_Scripts
{
units[] = {};
weapons[] = {};
requiredVersion = 0.1;
requiredAddons[] =
{
"DZ_Data"
};
};
};
class CfgMods
{
class HelloMod
{
dir = "HelloMod";
name = "Hello Mod";
author = "YourName";
type = "mod";
dependencies[] = { "Mission" };
class defs
{
class missionScriptModule
{
value = "";
files[] = { "HelloMod/Scripts/5_Mission" };
};
};
};
};HelloMod/Scripts/5_Mission/HelloMod/HelloMission.c
modded class MissionServer
{
override void OnInit()
{
super.OnInit();
Print("[HelloMod] Mission started! Server is running.");
}
};
modded class MissionGameplay
{
override void OnInit()
{
super.OnInit();
Print("[HelloMod] Mission started! Client is running.");
}
};Предыдущая: Глава 2.3: mod.cpp и WorkshopСледующая: Глава 2.5: Лучшие практики организации файлов
