Files
pinball-duel/README.md
aevgarik bfdb24294a Implement defensive setup scoring v3.10
Реализует финальную модель scoring из data-contracts.md v3.10:
fixed center bumpers — по last-touch; setup-bumpers — defensive trap
(награждают владельца только когда мяч принадлежит сопернику).
Self-farm запрещён. Neutral ball не даёт очков нигде.

Code changes:
- types/index.ts: BumperScoreSource union ('fixed_last_touch' |
  'player_setup' | 'ai_setup'); MatchResult.aiBumperPointsEarned +
  aiBumperHitsCount.
- Bumper.ts: новый required field source: BumperScoreSource;
  передаётся в onHit callback через bumper.source.
- scoring/MatchTracker.ts: pure helper computeCreditedTo(source, ballOwner)
  → реализует 9-cell credit matrix; recordBumperHit принимает
  (rawPoints, source, ballOwner, type, ...) и возвращает {creditedTo,
  pointsEarned}; новые getter'ы getAIBumperHits + getUncreditedBumperHits.
- scenes/MatchScene.ts:
  * Fixed bumpers создаются с source='fixed_last_touch'
  * placeSetupBumpers передаёт source per side
  * handleBumperHit (новая сигнатура: bumper, points) рутит в tracker,
    emit'ит spawn-particles + telemetry bumper_hit event с полным
    набором полей per telemetry-spec.md v3.10
  * MatchResult заполняется с AI BP/hits
  * match_end telemetry также включает aiBumperPointsEarned/HitsCount
  * HUD: BP теперь сравнительный «P x / AI y»
- scenes/ResultScene.ts: breakdown показывает обе стороны BP и hits.

Particle effects (DoD v3.10):
- 12 псевдо-частиц радиально от bumper'а (cubic ease-out, 320ms)
- цвет: player=magenta, ai=cyan, null=grey
- screenshake 80ms/0.0025 ТОЛЬКО на credited hit
  (иначе экран дрожит на каждом нейтральном отскоке)

Tests: scoring/MatchTracker.test.ts — 21 теста:
- 9-cell credit matrix (computeCreditedTo, все source × ballOwner)
- recordBumperHit с counter assertions
- многократные hits (накопление BP per сторона)
- симметрия player/AI defensive trap scenarios
- fixed bumpers через смену владения
- events log для telemetry
- recordGoal с autogoal-flag

Итого 50/50 unit-тестов (16 calculateScores + 13 flipperGeometry +
21 MatchTracker). typecheck/lint/build все зелёные.

Несоответствия с docs остающиеся:
- DoD: «12 частиц per credited side» — done; SFX bumper hit (DoD line 247)
  — TODO Phase 4 (asset pack).
- Particle effects через psecdoupartials (Arc + tween), не через
  ParticleEmitter — упрощение, визуально эквивалентно.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 07:27:01 +03:00

95 lines
4.0 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.
# 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** | Бустер «Захват» (cradle), Hard AI, cloud-save, achievements |
| **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.