Проверено вживую в 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>
Обе сцены собраны через 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>