Проверено вживую в 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>
Fool
A mobile card game: durak, one player against a bot. Built with Cocos Creator 3.8.8, targeting Web, Android and iOS, portrait only.
Getting around
| What the game is | docs/GAMEPLAY.md — the rules, and the bot's policy |
| How it is built | docs/TECHNICAL.md — layers, folders, workflows |
| What is planned | docs/PLAN.md — milestones and their state |
| Why it is like that | docs/DECISIONS.md — choices the specs left open |
| Driving the editor | docs/CODE_MODE_SETUP.md |
Working on it
npm install
npm test # the rules, the bot and the save format, headless
npm run typecheck # strict tsc over core/, modules/ and the tests
npm run check:core-purity # fails if the game logic reaches for the engine
npm run build:art # regenerate every sprite from source
npm run stats:bot # BasicBot self-play distribution — a tool, not a test
npm test needs no editor and no device. That is deliberate: the rules live in a
pure TypeScript core with no cc import, driven as a deterministic state
machine, so the entire rule set is verifiable in a couple of seconds. The soak
specs play several thousand complete matches and re-check every state invariant
after every single action.
To see it, open the project in Cocos Creator and press Preview, or build and serve it — see Builds in docs/TECHNICAL.md.
Layout
assets/scripts/core/ the rules, the bot — no engine dependency
assets/scripts/modules/ savegame
assets/scripts/app/ bootstrap and services
assets/scripts/ui/ scenes, screens, card rendering
assets/resources/cards/ 36 faces + back, packed into one atlas
art-src/cards/ vector sources for the faces
tests/ vitest specs and the state invariant checker
scripts/ art build and the architecture guard
Credits
Card faces are from Vector Playing Cards by Chris Aguilar, LGPL-3.0. Attribution is required by that licence — see assets/resources/cards/ATTRIBUTION.md, which also explains what to change if that licence does not suit the release.