Files
fool-cardgame/docs/PLAN.md
T
ftcandClaude Opus 5 4f3a26dc45 M5-M7: сцены, лобби, экран игры и цикл матча
Обе сцены собраны через 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>
2026-09-13 11:30:28 +03:00

116 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Development plan
Living document. Updated as work progresses — each milestone is committed to
`master` together with the update to this file.
**Legend:** `[ ]` not started · `[~]` in progress · `[x]` done
Source specs this plan implements: [GAMEPLAY.md](GAMEPLAY.md),
[ARCHITECTURE.md](ARCHITECTURE.md), [LOBBY.md](LOBBY.md), [UI.md](UI.md),
[ART.md](ART.md). Autonomous choices are logged in [DECISIONS.md](DECISIONS.md);
the resulting structure is described in [TECHNICAL.md](TECHNICAL.md).
## Iteration 1 scope
Single-player match of *podkidnoy durak* against a bot, 1v1, no transferring
(*perevod*). Lobby → match → result → lobby. Savegame framework in place with a
statistics section only (no currency, no levels yet). Portrait mobile UI,
targets: Web, Android, iOS.
## Guiding principle
The rules live in a **pure TypeScript core with no `cc` imports**, driven as a
deterministic state machine. That makes the whole game logic testable headlessly
with `npm test` — no editor, no device — which is what allows unattended
progress. The Cocos layer only renders state and turns taps into actions.
## Milestones
### M0 — Foundation `[x]`
- [x] Read specs, confirm open questions with the user
- [x] `docs/PLAN.md`, `docs/TECHNICAL.md`, `docs/DECISIONS.md`
- [x] Asset folder skeleton under `assets/`
- [x] Project settings: design resolution 1080×1920, fit-width
- [x] Headless test harness (vitest) wired to `assets/scripts/core`, plus a
`core` purity guard and a strict typecheck
### M1 — Rules core `[x]`
- [x] Seeded RNG and shuffle
- [x] `Suit`, `Rank`, `Card`, 36-card deck
- [x] `GameState`: hands, deck, trump, table slots, discard, phase, turn order
- [x] First-attacker selection per GAMEPLAY.md (lowest trump → lowest card → random)
- [x] Legal action generation: `Attack`, `Defend`, `Take`, `Pass`
- [x] Turn resolution: beat-all / take, discard, draw order, player elimination
- [x] End conditions and loser ("fool") determination
- [x] Unit tests covering every rule clause, including the add-card limits
### M2 — Bot and headless match runner `[x]`
- [x] `PlayerView` projection — a bot sees only what a player legitimately sees
- [x] `BasicBot` exactly per GAMEPLAY.md "Basic bot"
- [x] `MatchRunner` driving a full headless match
- [x] Soak test: thousands of seeded self-play matches finish with no illegal state
### M3 — Savegame module `[x]`
- [x] `ISaveSection` contract, `SaveManager` registry, JSON keyed by section name
- [x] Storage backend over `sys.localStorage` (works on web and native)
- [x] `StatsSection`: games played / won / lost, current and best win streak
- [x] Versioning + tolerant load (unknown or missing sections do not break a load)
- [x] Tests for save/load round-trip and corrupted-payload recovery
### M4 — Art pipeline `[x]`
- [x] Pick the 36 needed faces from `local/`, downscale to the 1080-wide budget
- [x] Author the missing pieces: card back, table background, UI panels/buttons
- [x] Import into `assets/art/`, configure sprite frames and atlasing
- [x] Remove consumed source art from `local/`, record attribution/licence
### M5 — Scenes and bootstrap `[x]`
- [x] `loader` scene: module initialisation, then transition to `lobby`
- [x] `lobby` scene: New Game button, statistics readout
- [x] Canvas / resolution policy and a reusable safe-area-aware layout root
### M6 — Game screen `[x]`
- [x] `Card` prefab, face/back flipping, sizing
- [x] Hand layout (fan), table layout (attack/defence pairs), deck and trump display
- [x] Deal, attack, defend, take and discard animations driven by core events
- [x] Tap/drag input producing core actions; illegal moves visibly rejected
- [x] Bot acts with human-readable pacing
### M7 — Match flow `[x]`
- [x] Result overlay (win / lose), stats written through the savegame module
- [x] Return to lobby; start another match without a scene leak
- [x] Leave-match button, which ends the match as a loss
### M8 — Responsive and touch pass `[~]`
- [x] Fit-width canvas, safe-area root, widget-stretched background
- [x] Every interactive element authored at or above the 120-unit minimum
(buttons 330×140 and 560×150; hand cards expose ~128 units each)
- [x] Vertical positions kept inside the 4:3 crop
- [ ] **Blocked:** seen at the extreme aspect ratios. Needs a machine that can
actually run the build — see "What is and is not verified" in
[TECHNICAL.md](TECHNICAL.md)
### M9 — Build verification and hand-off `[~]`
- [x] `web-mobile` build completes clean; command recorded in TECHNICAL.md
- [x] Card art reaches the build and packs into a single 2048² atlas
- [x] Every component reference in the scene verified populated
- [ ] **Blocked:** the build seen running. The browser in this environment falls
back to a software renderer that cannot start the engine's main loop
- [ ] Android/iOS build settings (ASTC per ART.md)
- [ ] README
### Known follow-ups
- The default skybox cubemap (~1.1 MB) still reaches the build. `skybox.enabled`
is off in both scenes, but the scene keeps its `_envmapHDR` reference and the
builder follows it. The editor tool server cannot write a null reference;
clearing the field in the Inspector by hand would do it.
- Nothing verifies the presentation layer automatically. The obvious next step is
a smoke test that boots the scene headlessly and asserts the card nodes land
where the layout says they should.
## Deliberately out of scope for iteration 1
Multiplayer or networking, more than two players at the table (the core is
written for N players, but only 1v1 is exercised), transferring (*perevod*),
smarter bots, currency, levels, shop, sound design, localisation.