Проверено вживую в 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>
- scripts/build-art.mjs: все спрайты игры собираются из исходников,
а не кладутся руками. Лица карт растеризуются из векторов,
рубашка/стол/панели/кнопки нарисованы SVG-ом прямо в скрипте
- 36 лиц 220x320 + рубашка, автоатлас 2048x2048, обрезка выключена
(раскладка рассчитывает на точный размер карты)
- девятипатчевые плитки 120x120 с рамкой 40
- фон стола 540x960, рисуется в 2x — градиенту детализация не нужна,
а памяти под текстуру уходит вчетверо меньше
- исходные векторы перенесены из local/ в art-src/cards
- ATTRIBUTION.md: LGPL-3.0, атрибуция обязательна; там же написано,
что менять, если такая лицензия не подходит для релиза
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- PlayerView: проекция состояния, в которой боту видно только то,
что видно живому игроку (своя рука, стол, размеры чужих рук, счётчики)
- BasicBot: политика из GAMEPLAY.md, полностью детерминированная
- Match: обёртка с состоянием и подпиской на события (её же возьмёт UI)
- runMatch: прогон матча без движка и без таймеров
- soak-тесты: 3500 полных матчей (боты и случайные легальные ходы,
2-4 игрока), инварианты состояния проверяются после каждого действия
- npm run stats:bot — распределение исходов самоигры
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>