# Playtest Protocol — Phase 2 AI Distinguishability **Цель.** Закрыть Phase 2 DoD «тестер различает 4 AI-личности после 5 матчей» через blind attribution. Требуется внешний тестер (НЕ разработчик и НЕ автор AI кода). **Pass-bar:** ≥ 75 % правильных attribution-ответов (≥ 15 / 20) ИЛИ ≥ 1 distinct tell per личность, названный тестером без подсказки. --- ## Подготовка | Шаг | Команда / действие | |---|---| | Build | `npm run build && npm run preview` (production build на `localhost:4173`) | | Difficulty | **Medium** — Easy скрывает поведение за reaction-задержкой; Hard не реализован (Phase 3) | | Mode | Quick Match → выбор личности → Medium | | Device | Минимум 1 desktop + 1 mobile session (mobile важно — touch zones там единственный input) | | Telemetry | Mock adapter логирует `trackEvent` в консоль — оставить открытой DevTools для пост-анализа | --- ## Per-match observation rubric После каждого матча тестер заполняет строку: | Поле | Что фиксировать | Источник | |---|---|---| | `match_index` | 1..20 | manual | | `setup_pattern` | Какие bumper-типы AI поставил, где (углы / центр / далеко) | визуально, AI половина | | `reaction_distance` | «early / normal / late» — насколько близко мяч долетает до AI-флипперов | субъективно | | `miss_rate` | «низкий / средний / высокий» — как часто AI пропускает свой удар | визуально | | `special_behaviour` | Любой характерный приём (двойной свинг, странный угол отскока, агрессивная атака центром) | free-text | | `final_score` | Player : AI | HUD post-match | | `duration_sec` | Длина матча | HUD timer / `match_end` telemetry | | `personality_guess` | Бэтти / Турбо / Хитрый Хо / Эхо | blind по завершению ВСЕХ 20 матчей | --- ## Expected tells (для оценщика; тестеру НЕ показывать до конца сессии) | Личность | Tells | |---|---| | **Defensive (Бэтти)** | Setup: 2 slingshot в углах ворот + 1 турбо центр + 1 curve + 1 пусто. Поведение: реакция надёжная (`reliabilityMul: 1.1`, capped 1.0 = почти 100 %), чуть быстрее (`reactionMul: 0.9`). AI пропускает редко; матчи длиннее обычного. | | **Aggressive (Турбо)** | Setup: 2 турбо в своей зоне (defensive trap против мяча игрока) + 1 slingshot угол + 1 curve + 1 standard. Поведение: реагирует с большего расстояния (`triggerDistBonus: +80px`), чаще промахивается (`reliabilityMul: 0.85`). Быстрые матчи; игрок, застрявший в setup Турбо, быстро отдаёт ему очки. | | **Trickster (Хитрый Хо)** | Setup: 4 curve bumper'а (лабиринт) + 1 турбо центр. Поведение: 15 % случайный спайк jitter (×1.3) — реакция «дёргается». Непредсказуемый счёт; необычные траектории мяча. | | **Ghost (Эхо)** | Setup: balanced (2 slingshot + 1 турбо + 1 curve + 1 standard). Поведение: 15 % «echo double-swing» — обе стороны активируются одновременно, даже если мяч идёт только в одну. Медианный счёт; характерный двойной flip. | --- ## Процедура 1. **Randomize order.** Использовать random.org pick из `[defensive, aggressive, trickster, ghost]`, 5 раз для каждой → 20 матчей. **Не группировать по личности** — рассыпать. Пример последовательности: `[T, D, G, A, T, A, D, G, T, A, D, G, A, T, D, G, A, D, G, T]`. 2. **Играть в выбранном порядке.** После каждого матча — заполнить строку рубрики. НЕ смотреть expected tells между матчами. 3. **Blind attribution.** По завершении всех 20 матчей — для каждой строки заполнить `personality_guess` без обращения к памяти о выборе перед матчем. 4. **Score.** Сравнить `personality_guess` с фактическим выбором. Подсчитать accuracy. 5. **Subjective rating.** Тестер ставит общую оценку «AI feels different» по 5-балльной шкале (≥ 4 = pass). 6. **Report.** Заполнить шаблон ниже, приложить к Phase 2 sign-off. --- ## Failure modes & follow-ups | Результат | Что делать | |---|---| | Accuracy < 50 % | Модификаторы слишком слабые. Удвоить `triggerDistBonus`, опустить `reliabilityMul` ниже 0.7. | | Accuracy 50-74 % | Две личности путаются между собой. Развести их setup'ом сильнее (например, поменять Defensive curve → second slingshot для большего «защитного» паттерна). | | Accuracy ≥ 75 %, subjective < 4 | Поведение различимо, но не интересно. Это не блокер Phase 2, но завести задачу на «character polish» в Phase 4. | | Тестер жалуется «AI слишком сложный/лёгкий на Medium» | Тюнить `reactionMs` в `src/config/defaults.ts` — не personality-specific. | --- ## Codex automation (опционально) `codex exec` потенциально может прогнать матчи через headless Phaser и replay-log; но для Phase 2 sign-off **достаточно ручного playtest'а**. Маппинг рубрики в telemetry events: | Поле рубрики | Telemetry source | |---|---| | `setup_pattern` (AI) | `MatchResult.aiSetup.slots` | | `reaction_distance` | derivable: ball trajectory + `goal_scored.ballOwnershipBeforeGoal` | | `miss_rate` | `1 − (AI flipper hit count / ball-passes-through-AI-zone count)` (нужен новый event `flipper_hit` — не в Phase 2 scope) | | `final_score` | `match_end.goalsScored / goalsAgainst` | | `duration_sec` | `match_end.durationSeconds` | Автоматизация — backlog Phase 5+. --- ## Report template ```markdown # Playtest Report — Phase 2 AI Distinguishability **Tester:** <имя / handle> **Date:** **Build:** HEAD **Devices:** desktop=, mobile= ## Match log | # | Personality (actual) | Setup observed | Reaction | Miss rate | Special | Score | Duration | Guess | Match? | |---|---|---|---|---|---|---|---|---|---| | 1 | trickster | 4 curve + turbo | normal | medium | hectic angles | 5:3 | 4m12s | trickster | ✅ | | 2 | ... | | | | | | | | | ## Results - Accuracy: __ / 20 = __ % - Subjective rating: __ / 5 - Per-personality breakdown: - Defensive: __ / 5 - Aggressive: __ / 5 - Trickster: __ / 5 - Ghost: __ / 5 ## Free-text observations <распознанные tells, неожиданные моменты, баги> ## Verdict - [ ] Phase 2 AI DoD PASS (≥75% accuracy + ≥4/5 subjective) - [ ] Phase 2 AI DoD FAIL — see follow-ups ```