12 KiB
🐛 Отладка мода RimWorld
Способы отладки
1. 🔴 Attach to Process (Рекомендуется)
Это самый удобный способ для отладки модов RimWorld.
Visual Studio
- Измените .csproj для включения отладочных символов:
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<LangVersion>latest</LangVersion>
<OutputPath>..\..\Assemblies</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<DebugType>portable</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
- Соберите проект в Debug режиме:
cd Source/AIImages
dotnet build -c Debug
-
Запустите RimWorld
-
В Visual Studio:
- Меню:
Debug→Attach to Process...(илиCtrl+Alt+P) - Найдите процесс
RimWorldWin64.exe - Нажмите
Attach
- Меню:
-
Установите breakpoint:
- Откройте файл с кодом (например,
PawnGizmoPatch.cs) - Кликните слева от номера строки (появится красная точка)
- Откройте файл с кодом (например,
-
Триггерьте код в игре:
- Выберите пешку → код остановится на breakpoint!
JetBrains Rider
-
Настройте Run Configuration:
Run→Edit Configurations...+→.NET Executable- Имя:
RimWorld Debug - Exe path:
D:\SteamLibrary\steamapps\common\RimWorld\RimWorldWin64.exe - Working directory:
D:\SteamLibrary\steamapps\common\RimWorld
-
Соберите проект в Debug:
dotnet build -c Debug
-
Запустите через Rider:
Run→Debug 'RimWorld Debug'(илиShift+F9)- Игра запустится с подключенным отладчиком
-
Breakpoints:
- Работают так же, как в Visual Studio
2. 📝 Логирование (Простой способ)
Если не нужна полная отладка, используйте логирование.
Добавьте в код:
using Verse;
// Информационное сообщение
Log.Message("[AI Images] Pawn selected: " + __instance.Name);
// Предупреждение
Log.Warning("[AI Images] Something suspicious");
// Ошибка
Log.Error("[AI Images] Something went wrong!");
Просмотр логов:
В игре:
- Нажмите
Ctrl+F12→ откроется окно логов - Ищите строки с
[AI Images]
Файл лога:
- Windows:
C:\Users\YourName\AppData\LocalLow\Ludeon Studios\RimWorld by Ludeon Studios\Player.log - Или в папке RimWorld:
RimWorld\LogOutput\
3. 🎮 Dev Mode в игре
Включите режим разработчика для дополнительных инструментов.
Как включить:
- Запустите RimWorld
Options→Settings→ включитеDevelopment mode- Перезапустите игру
Что даёт Dev Mode:
Debug Actions Menu (верхняя панель):
- Можно создавать своих debug actions
- Быстрое тестирование функций
Debug Inspector (Top bar → Tools → Debug inspector):
- Кликните на любой объект
- Просмотр всех полей и свойств в реальном времени
Debug Log (Ctrl+F12):
- Расширенная информация
- Трассировка стека
Создание Debug Action:
using Verse;
using RimWorld;
namespace AIImages
{
public static class DebugActions
{
[DebugAction(
"AI Images",
"Test Window",
actionType = DebugActionType.ToolMapForPawns,
allowedGameStates = AllowedGameStates.PlayingOnMap
)]
public static void TestWindow(Pawn pawn)
{
Find.WindowStack.Add(new Window_AIImage(pawn));
Log.Message($"[AI Images] Opened window for {pawn.Name}");
}
}
}
Теперь в игре:
- Верхняя панель →
Debug Actions - Категория
AI Images→Test Window - Кликните на пешку → окно откроется
4. 🔍 Продвинутая отладка
dnSpy - декомпилятор с отладчиком
Установка:
- Скачайте dnSpy: https://github.com/dnSpy/dnSpy/releases
- Распакуйте и запустите
dnSpy.exe
Использование:
File→Open→ выберитеRimWorld\RimWorldWin64_Data\Managed\Assembly-CSharp.dll- Изучайте код RimWorld!
- Можно ставить breakpoints прямо в коде игры
Attach to Process:
- Запустите RimWorld
- В dnSpy:
Debug→Attach to Process - Выберите
RimWorldWin64.exe - Ставьте breakpoints в коде игры или вашего мода
⚙️ Настройка проекта для отладки
Обновите AIImages.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<LangVersion>latest</LangVersion>
<OutputPath>..\..\Assemblies</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<!-- Настройки отладки -->
<DebugType>portable</DebugType>
<DebugSymbols>true</DebugSymbols>
<Optimize>false</Optimize>
</PropertyGroup>
<!-- Release конфигурация (без отладочных символов) -->
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<DebugType>None</DebugType>
<DebugSymbols>false</DebugSymbols>
<Optimize>true</Optimize>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Krafs.Rimworld.Ref" Version="1.5.4104" />
<PackageReference Include="Lib.Harmony" Version="2.3.3" />
</ItemGroup>
</Project>
Создайте .pdb файлы:
После сборки в Debug режиме в папке Assemblies/ появится:
AIImages.dll- ваш модAIImages.pdb- отладочные символы ✨
🎯 Практические примеры
Пример 1: Отладка Harmony патча
PawnGizmoPatch.cs:
[HarmonyPostfix]
public static IEnumerable<Gizmo> Postfix(IEnumerable<Gizmo> __result, Pawn __instance)
{
Log.Message($"[AI Images] GetGizmos called for: {__instance.Name}"); // 👈 Лог
foreach (Gizmo gizmo in __result)
{
yield return gizmo;
}
if (__instance.IsColonist && __instance.Spawned && __instance.Faction == Faction.OfPlayer)
{
Log.Message($"[AI Images] Adding button for: {__instance.Name}"); // 👈 Лог
yield return new Command_Action
{
defaultLabel = "AI Image",
defaultDesc = "Open AI Image window",
icon = ContentFinder<Texture2D>.Get("UI/Commands/AttackMelee", true),
action = delegate()
{
Log.Message($"[AI Images] Button clicked!"); // 👈 Лог
Find.WindowStack.Add(new Window_AIImage(__instance));
}
};
}
}
Пример 2: Отладка окна
Window_AIImage.cs:
public override void DoWindowContents(Rect inRect)
{
try
{
Log.Message($"[AI Images] Drawing window for: {pawn.Name}"); // 👈 Лог
Text.Font = GameFont.Medium;
Widgets.Label(new Rect(0f, 0f, inRect.width, 40f), "AI Image Window");
Text.Font = GameFont.Small;
Widgets.Label(new Rect(0f, 50f, inRect.width, 30f), "Pawn: " + pawn.NameShortColored.Resolve());
Widgets.DrawBoxSolid(
new Rect(10f, 100f, inRect.width - 20f, inRect.height - 150f),
new Color(0.2f, 0.2f, 0.2f, 0.5f)
);
Log.Message("[AI Images] Window drawn successfully"); // 👈 Лог
}
catch (System.Exception ex)
{
Log.Error($"[AI Images] Error drawing window: {ex}"); // 👈 Отлов ошибок
}
}
Пример 3: Try-Catch для отлова ошибок
public static IEnumerable<Gizmo> Postfix(IEnumerable<Gizmo> __result, Pawn __instance)
{
foreach (Gizmo gizmo in __result)
{
yield return gizmo;
}
if (__instance.IsColonist && __instance.Spawned)
{
Command_Action button = null;
try
{
button = new Command_Action
{
defaultLabel = "AI Image",
defaultDesc = "Open AI Image window",
icon = ContentFinder<Texture2D>.Get("UI/Commands/AttackMelee", true),
action = delegate()
{
try
{
Find.WindowStack.Add(new Window_AIImage(__instance));
}
catch (System.Exception ex)
{
Log.Error($"[AI Images] Failed to open window: {ex}");
}
}
};
}
catch (System.Exception ex)
{
Log.Error($"[AI Images] Failed to create button: {ex}");
}
if (button != null)
{
yield return button;
}
}
}
🚀 Быстрая отладка - Workflow
Вариант 1: С Breakpoints (Visual Studio/Rider)
# 1. Сборка в Debug
cd Source/AIImages
dotnet build -c Debug
# 2. Запустите RimWorld
# 3. Attach отладчик (Ctrl+Alt+P в VS)
# 4. Поставьте breakpoint в коде
# 5. Триггерьте код в игре → останавливается на breakpoint
Вариант 2: С логированием (быстрый)
# 1. Добавьте Log.Message() в код
# 2. Соберите
dotnet build
# 3. Запустите RimWorld
# 4. Ctrl+F12 → смотрите логи в реальном времени
📊 Полезные советы
1. Используйте префикс в логах
Log.Message("[AI Images] Your message");
Так проще искать в логе: Ctrl+F → [AI Images]
2. Логируйте важные переменные
Log.Message($"[AI Images] Pawn: {pawn.Name}, Age: {pawn.ageTracker.AgeBiologicalYears}");
3. Conditional compilation
#if DEBUG
Log.Message("[AI Images] Debug info");
#endif
Эти строки будут работать только в Debug сборке!
4. Проверяйте null
if (pawn?.health?.hediffSet != null)
{
// Безопасно использовать
}
5. Используйте Debug Actions для тестирования
Создавайте тестовые функции с [DebugAction] - это быстрее, чем играть вручную.
⚠️ Частые проблемы
Breakpoint не срабатывает
✅ Убедитесь, что:
- Проект собран в Debug (
dotnet build -c Debug) - Файл
.pdbсуществует рядом с.dll - Отладчик подключен к правильному процессу
- Код действительно выполняется (добавьте Log.Message для проверки)
"Symbols not loaded"
✅ Решение:
- Удалите
Assemblies/*.dllиAssemblies/*.pdb - Пересоберите:
dotnet clean && dotnet build -c Debug
Игра тормозит с отладчиком
✅ Это нормально. Отладчик замедляет выполнение.
🎓 Дополнительные материалы
- Visual Studio Debugging Guide: https://docs.microsoft.com/en-us/visualstudio/debugger/
- Rider Debugging: https://www.jetbrains.com/help/rider/Debugging_Code.html
- dnSpy: https://github.com/dnSpy/dnSpy
✅ Готово!
Теперь вы можете:
- ✅ Подключать отладчик к RimWorld
- ✅ Ставить breakpoints и смотреть переменные
- ✅ Использовать логирование
- ✅ Создавать Debug Actions для тестирования
Удачной отладки! 🐛→✨