1. Инструментарий разработчика: Конфигурация IDE и системные зависимости .NET
Скомпилированный мод скопирован в папку игры, Pathfinder: Wrath of the Righteous запущен, но ничего не происходит. В логах Unity Mod Manager (UMM) нет ни ошибок, ни предупреждений — игра просто проигнорировала файл. Причина кроется не в логике C#-кода, а в фундаментальном несовпадении сред выполнения. Бинарный файл собран с параметрами, которые игровой движок не способен прочитать.
Анатомия среды выполнения WotR
Pathfinder: Wrath of the Righteous базируется на движке Unity версии 2020.3. За выполнение скриптов и серверной логики отвечает бэкенд Mono, который жестко привязан к стандарту .NET Framework 4.7.2.
Экосистема .NET разделена на две несовместимые на бинарном уровне ветви:
Если при создании проекта использовать современный .NET 8, компилятор создаст библиотеку с метаданными, непонятными среде выполнения WotR. Движок не найдет ожидаемых сигнатур старого стандарта и молча прервет загрузку мода. Задача разработчика — заставить современную IDE работать по правилам устаревшего .NET Framework 4.7.2.
!Архитектура зависимостей мода: от движка Unity до пользовательской DLL
Настройка рабочей среды в JetBrains Rider (Windows 11)
Для разработки в ОС Windows 11 с использованием JetBrains Rider наличия самой IDE недостаточно. Операционной системе требуется пакет разработчика (Developer Pack) для целевой версии фреймворка.
Среда выполнения (Runtime) позволяет только запускать готовые программы. Пакет разработчика содержит эталонные сборки (Reference Assemblies) и заголовочные файлы, необходимые Rider для проверки синтаксиса и компиляции. Если пакет для 4.7.2 отсутствует в системе, Rider не предложит эту версию в диалоге создания проекта. Скачать .NET Framework 4.7.2 Developer Pack необходимо с официального сайта Microsoft.
Инициализация проекта
Мод для WotR — это динамически подключаемая библиотека (DLL), встраиваемая в адресное пространство игры загрузчиком UMM. В коде отсутствует стандартная точка входа static void Main().
Процесс создания базового репозитория в JetBrains Rider:
WotrHelloMod). Это имя станет названием итогового DLL-файла и корневым пространством имен.Эталонная конфигурация .csproj
Вместо ручного переключения параметров через графический интерфейс Rider (свойства сборки, целевую платформу, копирование локальных файлов), профессиональный моддинг требует прямого редактирования файла конфигурации проекта — .csproj.
Современный подход использует SDK-style формат файла. Он лаконичен, скрывает дефолтные настройки MSBuild и автоматически управляет рутинными процессами. Чтобы открыть его в Rider, дважды кликните по названию проекта в окне Solution Explorer.
Ниже представлен эталонный листинг .csproj для базового мода. Замените содержимое вашего файла этим кодом.
Разбор параметров: Целевая архитектура (x64)
Строка <PlatformTarget>x64</PlatformTarget> отвечает за архитектуру итогового бинарного файла.
Pathfinder: WotR — ресурсоемкая игра. 32-битный процесс в Windows ограничен адресным пространством в байт (ровно 4 ГБ оперативной памяти). Для современных RPG с тысячами блюпринтов и тяжелыми ассетами этого критически мало, поэтому движок скомпилирован исключительно под 64-битную архитектуру.
По умолчанию Rider использует значение AnyCPU. При такой настройке JIT-компилятор (Just-In-Time) среды выполнения сам решает, как развернуть код в памяти. Однако мод тесно взаимодействует с нативными библиотеками Unity, написанными на C++. Использование AnyCPU часто приводит к конфликтам при линковке памяти.
Если компилятор создаст 32-битную DLL (), при попытке внедрения в 64-битный процесс WotR загрузчик выбросит фатальное исключение BadImageFormatException. Жесткая фиксация <PlatformTarget>x64</PlatformTarget> гарантирует побайтовое соответствие вашей DLL адресному пространству игры.
Золотое правило зависимостей: Тег Private
Блок <ItemGroup> содержит ссылки (References) на оригинальные библиотеки. Чтобы мод мог изменить характеристики оружия или добавить реплику, компилятору необходимо знать структуру классов WotR. Главная библиотека с логикой игры — Assembly-CSharp.dll, логика движка — UnityEngine.dll, а API загрузчика — UnityModManager.dll.
Критический элемент конфигурации — тег <Private>False</Private>. В графическом интерфейсе IDE этот параметр называется Copy Local (Копировать локально).
По умолчанию при добавлении ссылки на стороннюю библиотеку IDE устанавливает этот параметр в True. Логика стандартной разработки: «взять этот DLL-файл и скопировать его в папку с готовым проектом, чтобы программа гарантированно нашла свои зависимости при запуске на другом компьютере».
В контексте моддинга копирование игровых библиотек должно быть строго отключено.
Ваш мод загружается внутрь уже работающей игры. В изолированной области оперативной памяти (AppDomain) уже загружены все оригинальные DLL. Если мод принесет в своей папке собственные копии этих гигантских файлов (размер Assembly-CSharp.dll превышает 40 МБ), загрузчик попытается поместить их в память второй раз.
Следствия дублирования библиотек в памяти:
UnitEntityData, созданный игрой из оригинальной DLL, не будет равен объекту UnitEntityData, который ожидает ваш мод из скопированной DLL. Возникает InvalidCastException.Тег <Private>False</Private> сообщает Rider: «Используй эти файлы исключительно для проверки синтаксиса и автодополнения кода во время разработки, но не прикрепляй их к итоговому артефакту сборки».
Подготовка к публикации на GitHub
Для создания качественного базового репозитория жестко закодированные пути в <HintPath> (например, C:\Program Files (x86)\...) являются плохой практикой. Если другой разработчик клонирует ваш репозиторий, а игра у него установлена на диске D:\Games, проект не скомпилируется.
Для решения этой проблемы пути к зависимостям заменяются на переменные окружения или относительные пути. В WotR-моддинге стандартом де-факто стало использование системной переменной, например (WOTR_PATH)\Wrath_Data\Managed\Assembly-CSharp.dll</HintPath>
<Private>False</Private>
</Reference>
`
Перед компиляцией достаточно добавить переменную WOTR_PATH в настройки Windows, указав путь к корневой папке игры. Это делает ваш .csproj универсальным и готовым к командной разработке.
Конфигурации сборки: Влияние на Harmony-патчи
В верхней панели Rider находится переключатель конфигураций сборки. В эталонном .csproj параметры <DebugSymbols>, <DebugType> и <Optimize> настроены для режима отладки (Debug).
| Характеристика | Debug (Отладка) | Release (Релиз) |
| :--- | :--- | :--- |
| Оптимизация кода | Отключена (<Optimize>false</Optimize>). | Включена (<Optimize>true</Optimize>). JIT-компилятор перестраивает IL-код. |
| Генерация PDB | Создается полный .pdb файл (Program Database). | Файл не создается или создается в урезанном виде. |
| Влияние на Harmony | Патчи работают стабильно. | Высокий риск отказа патчей из-за Inlining-а. |
Проблема Inlining (Встраивания методов):
В режиме Release компилятор стремится ускорить выполнение кода. Если метод небольшой, JIT-компилятор может применить оптимизацию Inlining — он берет тело метода и встраивает его напрямую в место вызова, уничтожая сам факт вызова оригинального метода в памяти.
Библиотека Harmony, которая является стандартом для изменения механик WotR, работает путем перехвата адресов методов в оперативной памяти. Если метод был «встроен» компилятором, его адрес исчезает. Harmony рапортует об успешном патче, но ваш код никогда не выполняется. Именно поэтому на этапе разработки и тестирования механик тег <Optimize>false</Optimize> абсолютно необходим.
Важность PDB-файла:
Когда в логике мода возникает ошибка (например, NullReferenceException), Unity Mod Manager перехватывает ее и пишет в лог. Если рядом с WotrHelloMod.dll в папке мода находится файл WotrHelloMod.pdb, менеджер сможет расшифровать стек вызовов и указать точный номер строки в вашем C#-коде. Формат <DebugType>portable</DebugType>` является кроссплатформенным стандартом, который корректно считывается парсером логов UMM.
Настроенный таким образом проект генерирует пустую, но архитектурно безупречную библиотеку. Среда разработки синхронизирована с движком Unity, зависимости изолированы, а репозиторий готов к версионированию. База заложена.