Files
Learn_System/plans/quantik-game/PLAN.md
T
Maxim Dolgolyov 69df2f8190 @
chore(quantik-game): полировка по финальному ревью + security-review

Финальное ревью: READY TO MERGE (0 блокеров). Security: SECURE (0 critical).
Применены дешёвые фиксы из ревью:
- validateSpec: блок game{} санитизируется ПОИМЁННО (chapter/subject →
  sanitizeText, order/par_ms/unlockStars → проверка типа, неизвестные ключи
  отбрасываются) — закрыт латентный хранимый XSS (раньше clean.game=spec.game).
- quantik.html: @media (prefers-reduced-motion) делает анимации мгновенными
  (не выключает — иначе forwards-появление узлов оставило бы их скрытыми).
- progress-logic.js: фикс комментария isUnlocked (сумма звёзд по ВСЕМ уровням
  с меньшим глобальным order, а не «той же главы»).
План: Ф6 (лидерборд/гонка) удалена (Amendment 1, решение пользователя);
финальные гейты отмечены; deferred-бэклог зафиксирован.
Затронутые тесты 45/45; lint:routes 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@
2026-06-14 17:00:13 +03:00

108 lines
9.5 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.
# Feature: Квантик — Законы Мира (образовательная 2D-игра)
**Branch:** `feature/quantik-game`
**Base branch:** `feature/sim-builder` (движок P1P3 и фазы sim-builder ещё не в master)
**Created:** 2026-06-13
**Status:** 🟡 In Progress
**Strategy:** Incremental
**Mode:** Automated
**Execution:** Orchestrator
## Summary
2D физика-головоломка-платформер поверх движка **SimForge** (`_sim_engine.js`). Герой —
**Квантик** (существующий питомец `PetSprite`): в уровне он светящаяся точка с glow и
кометной трассой (P2), на карте/в диалогах — SVG-блоб `PetSprite.render`. Игрок не рулит
героем напрямую, а **чинит «закон мира»**: задаёт скорость/угол/гравитацию (физ-уровни на
`SimPhysics`), собирает `f(x)` для движения по кривой (граф-уровни на `plot`/`SimExpr`),
открывает «ворота» уравниванием реакций/дробей. **Условие победы — булев блок `goal`
(SimExpr) в спеке** — это «атом», переиспользуемый всеми типами уровней.
Уровень = спека SimForge + блок `game/goal` → авторится в sim-builder, хранится в
`custom_sims`, открывается тем же конвейером, что и обычные симуляции. Всё новое —
**аддитивно и безопасно** (без `eval`/`Function`; нет блока `goal` → движок ведёт себя
как раньше).
Мета-слой: карта-созвездие, XP/скины Квантика, разблокировка по звёздам, класс-лидерборд
через classroom SSE. Квантовые способности: суперпозиция, коллапс/пауза, туннелирование
(энергия из быстрого SR-повторения флешкарт).
**MVP играбелен после Фазы 2.**
## Build & Test Commands
- **Build:** нет (vanilla JS, без бандлера; статика через Express)
- **Test:** `npm test` в `backend/` (`node --test tests/*.test.js`)
- **Lint:** `npm run lint:routes` в `backend/`
- ⚠️ После роутов/миграций: `npm run migrate` (живая БД `backend/data/learnspace.db`) + рестарт сервера.
- ⚠️ baseline: 3 pre-existing fail (`auth.test.js` — bcrypt/JWT в тест-окружении) + 5 page-тестов (`jsdom` не установлен). Хук толерантен.
## Project Constraints (соблюдают ВСЕ агенты)
- ⛔ Никаких эмодзи в коде — только inline SVG `.ic`.
- ⛔ Никакого `eval`/`new Function`. Выражения — ТОЛЬКО через `SimExpr` (безопасный парсер).
- Поиск по коду: `ast-index` (символы/usages/callers) + `vex` (semantic). НЕ Grep tool.
- БД — встроенный `node:sqlite` (`DatabaseSync`), НЕ better-sqlite3.
- Frontend — vanilla JS, `window.LS.*` (js/api.js), без бандлера.
- Стейджить файлы **поимённо** (НЕ `git add -A` — в репо много мусорных untracked + чужой WIP sim-builder).
- Аддитивность: новые блоки/типы в спеке не ломают существующие симуляции и каталог.
- Ассеты: база — in-house (PetSprite + canvas/SVG + встроенный FLUX `/api/imggen`).
Разрешены внешние **CC0/открытые** ассеты (звук/арт) с указанием источника/лицензии.
## Reuse Map (что переиспользуем)
- `frontend/js/labs/_sim_engine.js` — рантайм (SimPhysics, plot, glow/trails, zoom/pan, drag).
- `frontend/js/labs/_sim_expr.js``SimExpr.compile/evalSafe` для `goal`/`stars`.
- `frontend/js/pet-sprite.js``PetSprite.render(...)` Квантик + палитры → скины/нарратор.
- `custom_sims` + `customSimController.validateSpec` — хранение уровней + серверный гейт.
- `sim-builder.html`/`sim-builder.js` — авторинг уровней (Фаза 5).
- Флешкарты Tier-1 SR (мигр.074) — энергия туннелирования (Фаза 4).
- classroom SSE + мост `sim_state`/`apply_sim_state` (Ф7 sim-builder) — живая гонка (Фаза 6).
- Паттерн раздачи классу + `pushNotif` + `lab_sim_links` (Ф6 sim-builder).
## Phases
- [x] Phase 0: Слой целей в движке (goal/HUD/result) [domain: frontend] → [subplan](./phase-0-objective-layer.md)
- [x] Phase 1: Оболочка игры + 1 физ-уровень + прогресс [domain: fullstack] → [subplan](./phase-1-shell-first-level.md)
- [x] Phase 2: Карта-созвездие + мир физ-уровней + XP/скины [domain: fullstack] → [subplan](./phase-2-map-world-xp.md)
- [x] Phase 3: Граф-уровни (движение по f(x)) + зоны-препятствия [domain: fullstack] → [subplan](./phase-3-graph-levels.md)
- [x] Phase 4: Квантовые способности + SR-комнаты [domain: fullstack] → [subplan](./phase-4-quantum-abilities-sr.md)
- [x] Phase 5: Авторинг уровней в sim-builder + раздача классу [domain: fullstack] → [subplan](./phase-5-authoring-sharing.md)
- ~~Phase 6: Класс-лидерборд / живая гонка (classroom SSE)~~ — **REMOVED** (см. Amendment 1) → [subplan](./phase-6-leaderboard-live.md)
## Phase Progress Log
| Phase | Domain | Status | Review | Build | Committed |
|-------|--------|--------|--------|-------|-----------|
| Phase 0: Слой целей в движке | frontend | ✅ Done | ✅ | ✅ | ✅ |
| Phase 1: Оболочка + 1 уровень + прогресс | fullstack | ✅ Done | ✅ | ✅ | ✅ |
| Phase 2: Карта + мир + XP/скины | fullstack | ✅ Done | ✅ (1 🟡 fixed) | ✅ | ✅ |
| Phase 3: Граф-уровни + зоны | fullstack | ✅ Done | ✅ | ✅ | ✅ |
| Phase 4: Квантовые способности + SR | fullstack | ✅ Done | ✅ | ✅ | ✅ |
| Phase 5: Авторинг + раздача | fullstack | ✅ Done | ✅ | ✅ | ✅ |
| ~~Phase 6: Лидерборд / живая гонка~~ | fullstack | ❌ Removed (Amendment 1) | — | — | — |
## MVP boundary
После **Phase 2** игра играбельна и отгружаема: один полный мир физ-уровней с картой,
прогрессом, XP и скинами. Фазы 3–6 — расширение (новые типы уровней, способности,
авторинг, мультиплеер).
## Amendment Log
### Amendment 1 — 2026-06-14
**Type:** Removed phase
**What changed:** Phase 6 (Класс-лидерборд / живая гонка через classroom SSE) убрана из объёма по решению пользователя.
**Why:** Пользователь решил не реализовывать соревновательный слой; переходим к полировке и финальному ревью после Ф5.
**Impact on existing phases:** Нет. Фазы 0–5 самодостаточны и отгружаемы. `game_progress.level_id` (TEXT) уже готов под будущий лидерборд, если фичу вернут. Subplan `phase-6-leaderboard-live.md` сохранён как архив с пометкой REMOVED.
## Final Review
- [x] Comprehensive code review (final-reviewer) — ✅ READY TO MERGE, 0 блокеров (2026-06-14)
- [x] Security review (новые API/ввод) — ✅ SECURE, 0 critical (2026-06-14)
- [x] Polish-фиксы по ревью применены: game-блок санитизируется (был латентный XSS), prefers-reduced-motion guard, фикс комментария isUnlocked. Тесты 45/45 затронутых, lint 0.
- [x] `npm test` без новых регрессий (8 = baseline: 3 auth + 5 jsdom)
- [x] `npm run lint:routes` baseline 0
- [ ] Merged to `feature/sim-builder` (ожидает одобрения пользователя)
### Deferred / Backlog (не блокеры — из финального ревью)
- `QuantikLevels.ensureCustom` — N+1 `customSimGet` на загрузку /quantik; при росте числа авторённых уровней заменить на bulk-эндпоинт «список game-спек».
- Уровни 3/5/6 (отскок/орбита/манёвр): `fail` — только таймаут, «честная» механика не форсится. Точечно ужесточить `fail`-предикаты (контент-тюнинг).
- `graph-exp-11` капстоун узковат (~36–42/625) — при жалобах на сложность чуть расширить gate.
- Три похожих `starSvg`/`_starIcon` в разных модулях — консолидация не стоит связывания движка с игрой (оставлено).
- Клиентские очки прогресса фальсифицируемы (ожидаемо для single-player). ⚠️ Если когда-нибудь вернут Ф6-лидерборд — валидировать на сервере (replay/подписанные токены).