CLAUDE.md — движок v2 (воксельный)
Всегда общайся с пользователем на русском.
Направление и решения — docs/plan.md (в корне репо), разделы «Уроки черновика → видение движка v2» и «Направление v2». Открытые вопросы v2 — дописывать туда, не решать молча.
Что v2 есть (решено)
- Воксельный движок как продолжение пиксель-арта: рендер сцены в низкое разрешение (nearest-апскейл), палитра вокселей = арт-библии v1 (
docs/art-style.md), shadow map + воксельный AO.
- three.js — только низкоуровневый рендер-бэкенд (роль Pixi в v1); ядро движка о бэкенде не знает — рендер за узким интерфейсом.
- Формат моделей: внутренний JSON (валидация агентом) + импорт/экспорт
.vox (MagicaVoxel).
- Генерация моделей: процедурные генераторы кодом (основной путь), image-to-3D + вокселизация с апрув-гейтом, ручной MagicaVoxel для героев; визуальный гейт — turntable-листы.
- Анимация = данные: рига + кривые ключевых кадров в JSON, процедурная локомоция; валидация числовая (непрерывность цикла, контакт стопы) + снапшоты поз в агентный мост.
- Агентный мост и CLI-проверки — часть ядра v2, не надстройка. Демка — изометрия с фиксированной камерой; фокус работы — движок и инструментарий.
Уроки v1, обязательные к соблюдению (docs/plan.md)
- Все позиции/направления — в одном мировом пространстве; проекция на границе рендера. Не смешивать пространства (главный источник багов v1).
- Визуальная подсистема считается готовой только со скриншот-гейтом, не только снапшот-ассертами.
- Чистая математика — отдельно от вьюх, тестируется без рендера.
- Не оставлять подключённый, но неиспользуемый путь; удалять или связывать.
Команды (из v2/)
npm install # установка зависимостей (workspaces)
npm test # юнит-тесты (Vitest)
npm run typecheck # tsc --noEmit (движок + демка)
npm run check:fast # typecheck + тесты
node apps/demo/tools/checks/render.mjs # скриншот-гейт рендера (Chromium, /tmp/v2_render_*.png)
npx vite --port 5299 # демка (в apps/demo), http://localhost:5299
Структура
packages/engine (@rpg/engine) — ядро:
src/voxel/grid.ts — воксельная сетка (Uint8, 0 = пусто, иначе индекс палитры);
src/voxel/mesher.ts — culled-меш + классический AO 0..3 (схема 0fps, флип диагонали), чистая математика, тестируется без рендера;
src/render/voxelRenderer.ts — three.js-бэкенд: ортокамера диметрии 2:1, dirLight + shadow map + hemisphere, низкое разрешение (480×270);
tools/agent-lib.mjs — браузерный каркас проверок (launchBrowser/ startDevServer/openGame/AgentClient/Checks), swiftshader в headless;
tools/png.mjs — PNG-кодек (colorType 6 и 2 — скриншоты Chromium RGB).
apps/demo — демо-полигон: src/main.ts (сценка «пепельный луг» в палитре арт-библии), tools/checks/render.mjs — скриншот-гейт: нет pageerror, меш собран, тени ползут (кадры утро/вечер различаются), апскейл кратен 2×2, картинка многокрасочная. Мост демки: window.__agent.setSun(k)/stats().
Известные грабли (уже собранные)
- Знак Y в изо-направлении камеры: вектор «target → камера» должен иметь y = +1. С минусом камера встаёт под землю — сцена рендерится «из-под», верхние грани без света и всё почти чёрное (снапшоты при этом зелёные — ловится только скриншот-гейтом).
- Скриншоты headless Chromium — RGB (colorType 2), без альфы — декодер
tools/png.mjs v2 это умеет (у v1 умел только RGBA).
- three без типов: нужен
@types/three в devDependencies движка.
Рабочие привычки
- Для задач из 3+ шагов веди список задач и иди автономно.
- Комментарии и докстринги — по-русски; хелперы до ~70 строк.
- Изменения API — с доками в том же коммите.