Newer
Older
rpg / v2 / CLAUDE.md

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)

  1. Все позиции/направления — в одном мировом пространстве; проекция на границе рендера. Не смешивать пространства (главный источник багов v1).
  2. Визуальная подсистема считается готовой только со скриншот-гейтом, не только снапшот-ассертами.
  3. Чистая математика — отдельно от вьюх, тестируется без рендера.
  4. Не оставлять подключённый, но неиспользуемый путь; удалять или связывать.

Команды (из 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, флип диагонали); meshVoxels для сетки, meshRegion — область по функции доступа; чистая математика, тестируется без рендера;
    • src/world/chunk.ts — чанк 16×H×16; src/world/world.ts — мир-словарь чанков (get/set через границы, dirty-трекинг: правка боковой кромки помечает соседа); src/world/worldMesher.tsmeshChunk через world.get, шов чанков бесшовный (culled и AO через границы);
    • src/render/voxelRenderer.ts — three.js-бэкенд: ортокамера диметрии 2:1, dirLight + shadow map + hemisphere, низкое разрешение (480×270);
    • src/math/rng.ts — детерминированный Rng (mulberry32): next/int/range/chance/pick;
    • src/models/format.ts — формат модели (JSON: size + плотный base64 + слоты-палитра), encode/decode/validate (числовая валидация агентом);
    • src/models/generators.ts — процедурные генераторы: treeModel (варианты 0 круглая / 1 колонна / 2 ель), boulderModel (union сфер, свет на верхушках столбцов); (вид, сид) → VoxelModel, детерминировано;
    • src/models/stamp.tsstampModel: штамповка модели в мир с клиппингом (half-open прямоугольник + вертикаль мира), возвращает число вокселей;
    • 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 (мир 6×6 чанков 96×96 «пепельный луг», деревья/валуны — из генераторов через stampModel, дом — ручной путь, ремешинг по dirty-чанкам), tools/checks/render.mjs — скриншот-гейт: нет pageerror, меш собран, тени ползут (утро/вечер), апскейл кратен 2×2, многокрасочность, 36 чанков, постройка+мешинг < 2 с (замер ~0.5 с), setVoxel на шве меняет кадр, 12+ деревьев всех 3 вариантов, генератор детерминирован и варианты различаются (12 проверок). Мост демки: window.__agent.setSun(k)/stats()/setVoxel(x,y,z,c)/chunkStats()/modelStats()/stampTree(v,x,z,seed)/perf().

Известные грабли (уже собранные)

  • Знак Y в изо-направлении камеры: вектор «target → камера» должен иметь y = +1. С минусом камера встаёт под землю — сцена рендерится «из-под», верхние грани без света и всё почти чёрное (снапшоты при этом зелёные — ловится только скриншот-гейтом).
  • Скриншоты headless Chromium — RGB (colorType 2), без альфы — декодер tools/png.mjs v2 это умеет (у v1 умел только RGBA).
  • three без типов: нужен @types/three в devDependencies движка.
  • VoxelGrid.count() — метод, а не геттер: в тестах легко написать g.count без скобок и получить функцию (дважды ловили).

Рабочие привычки

  • Для задач из 3+ шагов веди список задач и иди автономно.
  • Комментарии и докстринги — по-русски; хелперы до ~70 строк.
  • Изменения API — с доками в том же коммите.