Files
ai-images/DEBUGGING_RU.md
2025-10-26 17:02:04 +03:00

12 KiB
Raw Blame History

🐛 Отладка мода RimWorld

Способы отладки

1. 🔴 Attach to Process (Рекомендуется)

Это самый удобный способ для отладки модов RimWorld.

Visual Studio

  1. Измените .csproj для включения отладочных символов:
<PropertyGroup>
  <TargetFramework>net472</TargetFramework>
  <LangVersion>latest</LangVersion>
  <OutputPath>..\..\Assemblies</OutputPath>
  <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
  <DebugType>portable</DebugType>
  <DebugSymbols>true</DebugSymbols>
</PropertyGroup>
  1. Соберите проект в Debug режиме:
cd Source/AIImages
dotnet build -c Debug
  1. Запустите RimWorld

  2. В Visual Studio:

    • Меню: DebugAttach to Process... (или Ctrl+Alt+P)
    • Найдите процесс RimWorldWin64.exe
    • Нажмите Attach
  3. Установите breakpoint:

    • Откройте файл с кодом (например, PawnGizmoPatch.cs)
    • Кликните слева от номера строки (появится красная точка)
  4. Триггерьте код в игре:

    • Выберите пешку → код остановится на breakpoint!

JetBrains Rider

  1. Настройте Run Configuration:

    • RunEdit Configurations...
    • +.NET Executable
    • Имя: RimWorld Debug
    • Exe path: D:\SteamLibrary\steamapps\common\RimWorld\RimWorldWin64.exe
    • Working directory: D:\SteamLibrary\steamapps\common\RimWorld
  2. Соберите проект в Debug:

dotnet build -c Debug
  1. Запустите через Rider:

    • RunDebug 'RimWorld Debug' (или Shift+F9)
    • Игра запустится с подключенным отладчиком
  2. 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 в игре

Включите режим разработчика для дополнительных инструментов.

Как включить:

  1. Запустите RimWorld
  2. OptionsSettings → включите Development mode
  3. Перезапустите игру

Что даёт Dev Mode:

Debug Actions Menu (верхняя панель):

  • Можно создавать своих debug actions
  • Быстрое тестирование функций

Debug Inspector (Top barToolsDebug 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 ImagesTest Window
  • Кликните на пешку → окно откроется

4. 🔍 Продвинутая отладка

dnSpy - декомпилятор с отладчиком

Установка:

  1. Скачайте dnSpy: https://github.com/dnSpy/dnSpy/releases
  2. Распакуйте и запустите dnSpy.exe

Использование:

  1. FileOpen → выберите RimWorld\RimWorldWin64_Data\Managed\Assembly-CSharp.dll
  2. Изучайте код RimWorld!
  3. Можно ставить breakpoints прямо в коде игры

Attach to Process:

  1. Запустите RimWorld
  2. В dnSpy: DebugAttach to Process
  3. Выберите RimWorldWin64.exe
  4. Ставьте 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

Игра тормозит с отладчиком

Это нормально. Отладчик замедляет выполнение.


🎓 Дополнительные материалы


Готово!

Теперь вы можете:

  • Подключать отладчик к RimWorld
  • Ставить breakpoints и смотреть переменные
  • Использовать логирование
  • Создавать Debug Actions для тестирования

Удачной отладки! 🐛