Реализует 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>
100 lines
5.7 KiB
Markdown
100 lines
5.7 KiB
Markdown
# Known Issues
|
||
|
||
Каталог известных проблем и плановых работ. Обновляется при каждом codex/external review.
|
||
|
||
## Toolchain (build-time, dev-only — НЕ попадает в production bundle)
|
||
|
||
### `npm audit`: 4 moderate vulnerabilities в цепочке vite@5.4.21
|
||
**Дата фиксации:** 2026-05-24 (codex review #3, HEAD `bb9f720`).
|
||
|
||
**Затронуто:** `esbuild ≤ 0.24.2`, транзитивно через `vite@5.x` и `vitest@1.x`.
|
||
|
||
**CVE / advisories:**
|
||
- [GHSA-67mh-4wv8-2f99](https://github.com/advisories/GHSA-67mh-4wv8-2f99) — esbuild dev-server CORS:
|
||
встроенный esbuild dev-server отражает произвольный `Origin`, что позволяет cross-origin
|
||
чтение source-кода во время разработки.
|
||
|
||
**Impact analysis:**
|
||
- **Production bundle:** не затронут. Vite/Rollup собирают финальный бандл во время
|
||
`npm run build`; esbuild-код не отгружается клиенту. На YG/RuStore/Play
|
||
загружается только `dist/` (см. `vite.config.ts`, `build` section).
|
||
- **Dev-server:** уязвим только при запуске `npm run dev` И биндинге на доступный
|
||
по сети адрес. Vite по умолчанию слушает `127.0.0.1`.
|
||
|
||
**Mitigation (текущий):**
|
||
- НЕ запускать dev-server с флагом `--host 0.0.0.0` или `--host` в untrusted
|
||
сетях. Команда `npm run dev` дефолтно safe.
|
||
- В CI и production builds esbuild dev-server не запускается вовсе.
|
||
|
||
**Resolution plan:**
|
||
Контролируемый апгрейд toolchain перед **Phase 5** (YG SDK integration),
|
||
когда build chain в любом случае пересматривается:
|
||
- `vite 5.x → 8.x` — major upgrade, ломает API:
|
||
- `build.rollupOptions.output` — изменён shape
|
||
- Plugin lifecycle hooks (`buildStart`, `transform`) — сигнатуры
|
||
- Возможны проблемы с `base: './'` на YG (требует проверки)
|
||
- `vitest 1.x → 3.x` — major upgrade, ломает API:
|
||
- Test runner v3 API (`setupFiles`, `globals`)
|
||
- Coverage provider config (`@vitest/coverage-v8` обязателен)
|
||
|
||
Текущий ETA: ~ конец июня 2026 (вместе с Phase 5 prep). Не блокирует Phase 3-4.
|
||
|
||
---
|
||
|
||
## Phase 2 — game-side
|
||
|
||
### AI personality distinguishability — codified, требует внешней валидации
|
||
**Дата фиксации:** 2026-05-24 (codex review #3).
|
||
|
||
Поведенческие отличия 4 личностей реализованы (`PersonalityModifier` в
|
||
`src/ai/AIPlayer.ts`, специальные хуки в `DefensiveAI`/`AggressiveAI`/`GhostAI`/`TricksterAI`).
|
||
Однако **Phase 2 DoD #X** — «тестер различает 4 личности после 5 матчей» —
|
||
не доказуем code-only проверкой; требует blind playtest.
|
||
|
||
**Resolution plan:**
|
||
Прогон по [`playtest-protocol.md`](./playtest-protocol.md) с внешним тестером
|
||
(не разработчик) до закрытия Phase 2. Pass-bar: ≥75% blind-attribution accuracy.
|
||
|
||
---
|
||
|
||
## Phase 3 — partial DoD coverage (sprint-mode scope)
|
||
|
||
**Дата фиксации:** 2026-05-24 (post Phase 3 implementation).
|
||
|
||
### AI booster (cradle) — wishlist Phase 3.5 / Phase 4
|
||
DoD `definition-of-done.md:166-171` требует:
|
||
- `Defensive Hard — cradle при защите`
|
||
- `Aggressive Hard — прицельный бустер в углы ворот игрока`
|
||
- `Trickster Hard — прицел через bumper-кластер (3-5 отскоков)`
|
||
|
||
В текущей реализации Hard difficulty работает на уровне reactionMs/jitterMs
|
||
(80ms/20ms через config). Полноценный AI cradle (с ray-tracing solver, прицеливанием,
|
||
shot direction) — не реализован. Hard subjectively сложнее Medium через быструю
|
||
реакцию, но без cradle-aim solver не отличается тактически.
|
||
|
||
**Resolution plan:** Phase 3.5 polish или Phase 4 (вместе с Hard playtest tuning).
|
||
Базовая инфраструктура (Booster class с reusable state machine) уже готова — нужен
|
||
второй instance Booster для AI side + ray-tracing solver (~3 сек × 12 углов
|
||
имитация траектории до flipper-зоны игрока).
|
||
|
||
### Ghost adaptation — sprint-mode (без profile-tracking)
|
||
Per `scope-lock.md` и `definition-of-done.md:395-419` sprint-mode alternative
|
||
DoD активирован. `GhostProfile` остаётся `null` в SaveState; `GhostAI` использует
|
||
balanced setup без EMA-updates. Это **сознательное** решение для MVP — full
|
||
adaptation добавляется как live-ops feature через 4-8 недель после launch'а.
|
||
|
||
### `defender_20` achievement — proxy эвристика
|
||
DoD требует «20+ BP через свои setup-bumpers за матч». В Phase 3 у `MatchResult`
|
||
нет отдельного breakdown по source (только total `bumperPointsEarned`). Используется
|
||
proxy: total BP ≥ 20. Точный source-breakdown добавляется в Phase 4 через extension
|
||
`MatchResult` (poля `bumperPointsBySource: {fixed, setup}`).
|
||
|
||
---
|
||
|
||
## Cross-references
|
||
|
||
- Phase roadmap: [`README.md#фазовый-план`](./README.md#фазовый-план)
|
||
- Concept docs: `~/Knowledge/Projects/pinball-duel/`
|
||
- Audit history: `~/Knowledge/Projects/pinball-duel/index.md` (10 раундов до `dc53623`,
|
||
затем codex rounds #1-3 в git log с тегом `Post-codex-review-*`)
|