Проверено вживую в Chrome: лобби -> матч -> бот ходит -> результат ->
статистика в лобби. Полный матч отыгран, оба исхода видел.
Баги, которые собирались и типизировались, но падали только в рантайме:
1. Canvas не менял размер под экран. Своего cc.Widget у него не было,
а alignCanvasWithScreen правит только камеру. Canvas оставался
1280x720, и все растянутые по нему дети — тоже.
2. [...map.values()] превращается сборкой в [].concat(map.values()),
а concat не разворачивает итератор, а кладёт его одним элементом.
Отсюда "view.cancelAnimations is not a function" на первой же уборке
карт. Теперь Array.from.
3. Рубашка козыря рисовалась поверх колоды, а не под ней.
Вёрстка переделана под требование UI.md (4:3 .. 21:9):
- fitWidth даёт постоянную ширину, но не высоту: на 4:3 видно только
±720 юнитов. Кнопка "Leave" на y=840 и низ руки на -860 были за
экраном именно там, где это важнее всего
- рука и панель действий считаются от нижней границы экрана,
"Leave" прибит виджетом к левому верхнему углу
- стол — один ряд до шести карт вместо двух рядов по три: экономит
~215 юнитов высоты, которых на 4:3 нет. Ряд центрируется по тем
картам, что реально на столе
- затемнение под окном результата рисуется непрозрачным спрайтом:
тонировать и без того полупрозрачный спрайт почти ничего не даёт
Инструменты:
- npm run serve — отдаёт сборку и роут /_aspects: игра в трёх
фиксированных iframe-ах 4:3 / 16:9 / 21:9. Движок подгоняет себя
под окно, поэтому iframe — единственный простой способ увидеть
вёрстку в форме, которой окно не имеет
- npm run check:spreads — ловит спред неитерируемого в массив
- npm run check — чистота core, спреды, сцены, типы, тесты
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
nodeCreate кладёт узел на слой DEFAULT, а камера Canvas рисует только
UI_2D. Поэтому сборка показывала цвет очистки камеры и больше ничего.
В редакторе это не видно вообще: камера вида сцены рисует все слои,
так что сцена выглядит правильной, а билд — пустым.
- 45 узлов в обеих сценах и префабе переведены на слой UI_2D
- scripts/check-scenes.mjs: headless-проверка сцен и префабов —
слои, наличие камеры у Canvas, видимость UI_2D у камеры,
незаполненные ссылки в наших компонентах. Проверено, что она
действительно падает на подсунутом неверном слое
- npm run check — всё разом (чистота core, сцены, типы, тесты)
- Bootstrap теперь докладывает каждый шаг в лейбл и в консоль
и через 10 секунд уходит в лобби даже если арт не догрузился:
молча висящий загрузчик — худший вид бага в отчёте
- ловушка со слоями описана в docs/CODE_MODE_SETUP.md
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Обе сцены собраны через Code Mode, не руками.
- loader: поднимает модули, прогревает арт карт, уходит в lobby
- lobby: обе UI-ветки в одной сцене (по ARCHITECTURE.md), матч — это
смена видимого корня, а не загрузка сцены
- GameScreen рисует текущее состояние и доводит узлы твинами, а не
проигрывает поток событий: узел карты живёт вместе со своей картой,
поэтому "шестёрка ушла из руки на стол" не требует отдельного случая
- один тап = ход целиком; логика вынесена в core/rules/intent.ts
и покрыта тестами, в том числе проверкой, что она никогда не предложит
ход, который правила отвергнут
- арт карт переехал в assets/resources: .pac — это инструкция упаковки
на сборке, а не рантайм-ассет, и без ссылок на кадры в сборку
не попадало ничего. Теперь все 37 спрайтов в одной текстуре 2048x2048
- клики кнопок подписываются в коде, а не через clickEvents сцены
- строки интерфейса собраны в одном файле
Сборка web-mobile проходит чисто, все ссылки в сцене проверены.
Вживую не запускалось: браузер в этом окружении не поднимает
главный цикл движка. Подробности — в docs/TECHNICAL.md.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- docs/PLAN.md — план по этапам, обновляется по мере работы
- docs/TECHNICAL.md — слои, карта папок, контракты, рабочие процессы
- docs/DECISIONS.md — журнал решений, принятых самостоятельно
- разрешение 1080x1920, fit-width (портрет, 4:3..21:9)
- каркас assets/scripts (core / modules / app / ui)
- headless-тесты на vitest + strict typecheck + защита чистоты core
- Rng: детерминированный генератор и перемешивание
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>