Instruction file imported from Kaliguri/Guildmaster-Autobattler (
.cursor/rules/agent-workflows.mdc). Copyright stays with the author.
Рабочие процессы агента
Обновление этого файла
Если в ходе работы над проектом возникла систематическая ошибка или кейс, который пришлось решать нестандартно — добавить его сюда как новый раздел. Формат: описание кейса + конкретный порядок действий или пример кода.
Критерии для добавления:
- Ошибка или нюанс, который неочевиден и может повториться
- Решение, которое отличается от стандартного поведения
- Любой "подводный камень" специфичный для этого проекта
Создание новых C# скриптов
Компиляцию проверяет скрипт, а не редактор. refresh_unity для этого не зовём: перезагрузка
домена стоит от десяти секунд до минуты и дорожает по ходу сессии, идёт она в РЕДАКТОРЕ МАКСА, а
ошибка сборки замораживает ему весь тулинг. Полное правило и замеры — в CLAUDE.md.
Порядок действий:
- Записать
.csфайл(ы). ./scripts/compile-check.ps1 -Meta— отвечает «компилируется ли» за пару секунд и заодно заводит.metaновым скриптам. Без аргументов проверяются сборки, задетые правками;-All— все.- Добавить в коммит и
.cs, и.metaвместе.
Без .meta Unity не считает файл скриптом: тип не появляется, а поле SerializeReference молча
становится null-компонентом — поэтому шаг 2 обязателен даже тогда, когда «и так понятно, что
компилируется».
Редактор остаётся нужен для того, что без него не делается: импорт и создание ассетов, префабы, сцены, анимации, превью UI.
# Неправильно — коммитить .cs без .meta
git add Assets/_Project/Scripts/Core/IUnit.cs
# Правильно — коммитить вместе
git add Assets/_Project/Scripts/Core/IUnit.cs
git add Assets/_Project/Scripts/Core/IUnit.cs.meta
Unity MCP — группы инструментов
Установка, версии и проверка коннекта описаны в CLAUDE.md (раздел «MCP-инструменты») — здесь
только то, что нужно делать по ходу задачи.
MCP for Unity держит инструменты группами (tool groups), и по умолчанию включена только core.
Остальные активируются на время сессии. Зависимости под них в проекте уже стоят: Cinemachine даёт
камерные инструменты, ProBuilder — свою группу, Roslyn — семантическую валидацию в validate_script.
Как активировать нужную группу в начале задачи:
manage_tools(action="activate", group="probuilder")
manage_tools(action="activate", group="testing")
manage_tools(action="list_groups") // посмотреть все доступные группы и их статус
Полный список групп: core (всегда), animation, ui, vfx, scripting_ext, testing, probuilder, profiling, docs.
Если feature/* смёрджен в master вместо dev
Симптом: dev отстаёт от master, в master есть коммиты которых нет в dev.
Порядок исправления:
- Проверить расхождение:
git log --oneline origin/dev..origin/master - Переключиться на
dev:git checkout dev - Смёрджить master в dev:
git merge origin/master --no-edit - Если на фиче-ветке остались коммиты после точки мёрджа в master — смёрджить и их:
git merge <feature-branch> --no-edit - Запушить:
git push origin dev
Конфликтов обычно нет — это fast-forward или чистый merge, так как ветки расходятся только по истории, не по содержимому.
Нарезка спрайт-листов (sprite slicing)
Область: вендорные покадровые паки и временная оснастка, НЕ наш арт. Наши персонажи собраны на костях (
Prefabs/Bones/), покадровые виды удалены 2026-08-04, а части рига импортируются по своему правилу —Bilinearбез мипмапов, пресетBonePartSprite.preset. Причина: части экспортируются из Aseprite в ×10 как запас разрешения под вращение костей, иPointэтот запас обнуляет. См. журнал2026-07-30-sprite-filtering-bilinear-no-mips.
Никогда не использовать Automatic slicing — Unity нарезает по непрозрачным пикселям и даёт неверные размеры кадров. У «Pixel Art Heroes»-паков (и аналогичных) все кадры одного размера в одну строку.
Правильный метод: Grid by Cell Count.
Алгоритм для агента:
- Определить количество кадров:
frameCount = textureWidth / frameHeight(кадры квадратные). - Установить нарезку через
execute_code(Unity MCP):
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
string path = "Assets/_Project/Art/Sprites/.../AnimName.png"; // путь к файлу
var importer = AssetImporter.GetAtPath(path) as TextureImporter;
int frameCount = 8; // посчитать из ширины / высоты текстуры
int frameSize = 150; // ширина == высота одного кадра
importer.spriteImportMode = SpriteImportMode.Multiple;
importer.filterMode = FilterMode.Point;
importer.textureCompression = TextureImporterCompression.Uncompressed;
var rects = new List<SpriteMetaData>();
for (int i = 0; i < frameCount; i++)
{
rects.Add(new SpriteMetaData
{
name = $"AnimName_{i}",
rect = new Rect(i * frameSize, 0, frameSize, frameSize),
alignment = 0,
pivot = new Vector2(0.5f, 0.5f),
});
}
importer.spritesheet = rects.ToArray();
EditorUtility.SetDirty(importer);
importer.SaveAndReimport();
Debug.Log($"[SliceSprites] Нарезано {frameCount} кадров: {path}");
Параметры нарезки:
filterMode: Point— только для низкоразрешённых вендорных листов, нарисованных попиксельно: сглаживать нечего, и Point сохраняет кромку. Наш арт идёт по правилу выше (Bilinear, без мипов)textureCompression: Uncompressed— без артефактов сжатия- Pivot:
(0.5, 0.5)— центр кадра - Offset и Padding:
0 - Имена кадров:
AnimationName_0,AnimationName_1, …
Как узнать frameCount и frameSize без открытия файла:
// Сначала получить размеры текстуры:
var tex = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
int w = tex.width; int h = tex.height;
// frameSize = h (кадры квадратные); frameCount = w / h
Почему не Automatic: автонарезка разбивает кадр персонажа на несколько частей если между пикселями есть прозрачные зазоры внутри анимации (плащ, копьё). Результат — юнит отображается как один пиксель или исчезает.
Новые Markdown-файлы в docs/wiki
Файлы не должны начинаться с пустой строки, за которой следует ---. Quartz интерпретирует такой --- как начало YAML frontmatter и падает при парсинге.
Правильная структура (по конвенции Obsidian):
**Статус:** 🟡 Draft
---
Содержимое документа.
Неправильно — вызовет ошибку в Quartz:
---
> Текст документа...