Files
pinball-duel/README.md
aevgarik 39056fdc74 Phase 3: Booster «Захват», cloud-save, 15 achievements
Реализует Phase 3 в sprint-mode согласно scope-lock + DoD alternative
для Ghost (без adaptation, balanced setup). Полный AI booster откладывается
в Phase 3.5/4 — см. KNOWN_ISSUES.md.

## Booster «Захват» (player-side, полная реализация)

- src/game/Booster.ts — FSM idle→armed→aiming→cooldown
  + charge tracking (100 BP=1 заряд, max 2)
  + lockout 30s от match start
  + slow-mo trigger через event callbacks
  + aim rotation ±10° per tap
  + auto-shoot через cradleDurationMs=1500ms ИЛИ повторный tap
- src/scenes/MatchScene.ts wiring:
  - charge добавляется при credited player hit (result.creditedTo='player')
  - tap BOOST zone / keyboard S → handleBoosterTap
  - handleFlipperHit при armed → attemptCradle на nearest player flipper
  - tickBooster каждый update: sticky-ball anchor, aim indicator, auto-shoot
  - slow-mo через matter.engine.timing.timeScale + time.timeScale + tweens
  - HUD: «BOOST locked/armed/aim L/R · TAP/N/2» + полоска прогресса заряда
  - L/R input в aiming-фазе перенаправляются в booster.rotateAim (не flipper)
- 18 unit-тестов src/game/Booster.test.ts:
  initial state, lockout, charge accumulation/cap, FSM transitions,
  rotateAim/shoot from non-aiming = noop, autoShoot timing, callbacks.

## SaveState v1 + cloud-save

- src/services/SaveStateService.ts:
  - defaultSaveState() — полная схема SaveState (settings, statistics,
    cosmetics, campaign, tournament, achievements={}, ghostProfile=null)
  - SaveStateService.load() / save() через PlatformAdapter.cloudLoad/Save
  - applyMatchResult() — immutable update: statistics totals + achievements
- src/main.ts: cloud-load на boot, registry.set('saveState', state) +
  'saveService'; isReturning telemetry flag из totalMatches > 0
- src/scenes/MatchScene.ts:
  - persistMatchAndUnlocks(matchResult) после endMatch
  - errors swallow'аются + telemetry save_failed (не блокер UX)

## 15 Achievements

- src/types/index.ts: AchievementId union (15 IDs), AchievementsState
- src/config/achievements.ts: 15 определений с title/description
  (first_win, defensive/aggressive/trickster/ghost_*_win, flawless_5_0,
  bumper_master_50, defender_20, cradle_first_use, cradle_goal,
  comeback_3_4, golden_goal_win, marathon_10)
- src/scoring/AchievementEvaluator.ts:
  - evaluateAchievements(ctx) — pure function, проверяет условия
  - applyAchievementUnlocks() — immutable state update
- 17 unit-тестов: basic wins, personality×difficulty, flawless,
  bumper milestones, comeback, cradle/golden goal, marathon,
  applyUnlocks idempotency
- MatchScene: после endMatch evaluate + platform.unlockAchievement(id) +
  telemetry achievement_unlocked

## Hard difficulty (config-level)

- AIDifficulty='hard' уже работает через config (80ms reaction / 20ms jitter)
- UI label fixed: "Профи — 80мс реакция, jitter ±20мс" (раньше "(cradle — Phase 3)")
- AI cradle activation — backlog, см. KNOWN_ISSUES.md

## Sprint-mode Ghost

- GhostProfile остаётся null per scope-lock alternative DoD
- GhostAI без profile-tracking; balanced setup сохранён из Phase 2

## Telemetry

- bumper_hit (Phase 2 v3.10) — уже работает
- achievement_unlocked — emit per ID
- cradle_first_use — emit раз за match
- cradle_goal — emit при scoring через cradle anchor
- save_failed — emit при cloud-save error

## Docs

- KNOWN_ISSUES.md: Phase 3 partial DoD coverage (AI booster wishlist,
  Ghost sprint-mode rationale, defender_20 proxy heuristic)
- README.md: phase plan updated (0-3 )

Tests: 85/85 (5 файлов: calculateScores 16 + flipperGeometry 13 +
MatchTracker 21 + Booster 18 + AchievementEvaluator 17). Build 387KB gzip.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 08:36:43 +03:00

95 lines
4.1 KiB
Markdown
Raw Permalink 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.
# Pinball-Duel
Single-player пинбол vs 4 AI-личности (head-to-head формат, Williams Joust 1983).
**Stack:** Phaser 4 (beta) + TypeScript + Vite + Matter.js (bundled). Capacitor добавляется в Phase 1.5.
**Platforms:**
- **MVP:** Yandex Games (web only)
- **Phase 1.5** (post-MVP-launch): Google Play + RuStore (Android, через Capacitor)
- **Post-Phase 2:** iOS (если PMF подтвердится)
**Status:** Phase 0 (pre-production) в процессе. Концепт-пакет — `~/Knowledge/Projects/pinball-duel/` (19 файлов, 10 audit-раундов).
## Development
### Requirements
- Node.js 20+
- npm
### Setup
```bash
npm install
npm run dev # localhost:5173
```
### Build & checks
```bash
npm run build # type-check + production build → dist/
npm run preview # serve build locally
npm run typecheck # tsc --noEmit
npm run lint # ESLint
npm run test # Vitest
```
## Architecture
### Game stack
- **Phaser 4** — game engine + Matter.js physics (bundled)
- **TypeScript strict** — все типы из `src/types/index.ts` (схемы из data-contracts.md)
- **Vite** — bundler + dev server (с `base: './'` для YG)
### Platform Adapter
Game-код не знает о платформе через `PlatformAdapter` interface (`src/platform/`). Реализации:
- `MockPlatformAdapter` — local dev и unit tests
- `YgPlatformAdapter` — Yandex Games SDK (MVP)
- `CapacitorAdmobAdapter` — Phase 1.5 (Play)
- `RuStorePlatformAdapter` — Phase 1.5 (RuStore)
Detection и factory в `PlatformAdapter.ts::createPlatformAdapter()`.
### Структура папок
```
src/
config/ Remote Config defaults, палитра, константы
types/ SaveState, MatchResult, RemoteConfig, etc.
platform/ PlatformAdapter interface + 4 реализации
scenes/ Phaser scenes (Boot, Preload, MainMenu, Setup, Match, Result)
game/ Game objects (Ball, Flipper, Bumper, Table, Match orchestration)
ai/ AI personalities (Defensive, Aggressive, Trickster, Ghost) + heuristics
scoring/ calculateScores + MatchTracker (defensive setup scoring + bumper points)
```
### Фазовый план
| Phase | Содержание |
|---|---|
| **0** (✅) | Vite + Phaser 4 + TS boilerplate; Platform Adapter |
| **1** (✅) | Core mechanics: матч, флипперы, мяч, last-touch, fixed bumpers, Defensive Easy AI |
| **2** (✅) | Setup-фаза, 4 BumperType, 4 AI-личности × 3 сложности |
| **3** (✅ partial, sprint-mode) | Бустер «Захват» player-side, Hard difficulty (config-driven), cloud-save, 15 achievements. AI cradle + Ghost adaptation вынесены в backlog — см. [`KNOWN_ISSUES.md`](./KNOWN_ISSUES.md) |
| **4** | Campaign + Tournament + визуальный polish (шейдеры), ассеты |
| **5** | YG SDK ads + payments + Remote Config |
| **6** | YG polish + submission + soft launch |
| **1.5** (post-MVP launch) | Capacitor: Google Play + RuStore mobile native |
## Operational docs (в репо)
- [`KNOWN_ISSUES.md`](./KNOWN_ISSUES.md) — toolchain vulnerabilities, плановые апгрейды, текущие game-side caveats
- [`playtest-protocol.md`](./playtest-protocol.md) — спека blind-attribution тестирования AI-личностей для закрытия Phase 2 DoD
## Документация (концепт-пакет)
`~/Knowledge/Projects/pinball-duel/` — 19 файлов:
- `index.md` — overview + decision-history (10 audit-раундов)
- `concepts/scope-lock.md` — что в каждой фазе (single source of truth)
- `concepts/data-contracts.md` — все schema'ы (Remote Config, MatchResult, SaveState, leaderboard formula)
- `concepts/definition-of-done.md` — DoD per фаза
- `concepts/telemetry-spec.md` — event map
- `concepts/development-roadmap.md` — план разработки
- `concepts/monetization.md` — IAP + Anti-A2W правило
- `concepts/bot-ai-design.md` — 4 AI-личности
- `player-guide.md` — narrative-руководство игрока
## License
Proprietary, all rights reserved.