Files
Learn_System/plans/quantik-game/CONTEXT.md
T
Maxim Dolgolyov 351251d652 @
feat(quantik-game): фаза 1 — оболочка игры + физ-уровень + прогресс (MVP)

Страница /quantik монтирует уровень-спеку в SimEngine (игровой режим: HUD из
Ф0 + слайдеры закона + play/reset), на победу шлёт результат и показывает
экран успеха (звёзды/время/попытки, inline SVG). Уровень phys-artillery-1
как данные (levels.js): гравитация + запуск тела из угла/скорости, портал,
бонус-звезда. Бэкенд: миграция 076 game_progress (UNIQUE user+level),
/api/game/progress (GET свой / POST upsert best time/stars, attempts++,
auth-only, валидация входа), клиент LS.gameProgress*, пункт сайдбара.
game.test.js 13/13; npm test 251 pass/8 baseline; lint:routes 0.
Уровень проверен на реальном интеграторе (311 выигрышных комбо, 31 на 3★).

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

7.9 KiB
Raw Blame History

Feature Context: Квантик — Законы Мира

Current State

  • Ветка feature/quantik-game ответвлена от feature/sim-builder (движок P1–P3 там, не в master).
  • При ответвлении унаследован чужой uncommitted WIP sim-builder: frontend/js/sim-builder.js, frontend/sim-builder.html, .claude/settings.json + множество untracked tmp_*/мусорных файлов. НЕ трогать и НЕ коммитить этот WIP — стейджить только свои файлы поимённо.
  • Phase 0 реализован (pending review): слой целей в движке _sim_engine.js (блок goal, компиляция when/fail/stars через SimExpr, состояние результата, HUD-оверлей, API onGoal/getResult/resetResult) + серверный гейт validateSpec пропускает goal/game. Изменены: frontend/js/labs/_sim_engine.js, backend/src/controllers/customSimController.js. Аддитивно: спека без goal ведёт себя ровно как раньше (HUD не создаётся, побед не считается). Смоук 40/40; npm test 238 pass / 8 baseline fail; lint:routes 0.
  • Phase 1 реализован (pending review): сквозной играбельный срез. Страница /quantik (frontend/quantik.html + frontend/js/game/quantik-game.js) монтирует уровень-спеку через SimEngine.mount; «игровой режим» = HUD из Ф0 (сам по наличию goal) + слайдеры params + play/reset. Уровень phys-artillery-1 — данные в frontend/js/game/levels.js (window.QuantikLevels): physics-гравитация + body-запуск под углом θ/скоростью v, портал-цель, бонус-звезда. На победу onGoalLS.gameProgressSubmit + DOM-оверлей успеха (звёзды/время/попытки). Прогресс: таблица game_progress (мигр.076), API /api/game/progress (GET/POST, gameController.js+routes/game.js, смонтировано в server.js после /api/custom-sims), клиент LS.gameProgressList/Submit. Сайдбар: /quantik (icon rocket) виден всем. Новые: 076_game_progress.sql, gameController.js, routes/game.js, quantik.html, js/game/levels.js, js/game/quantik-game.js, tests/game.test.js. Изменены: server.js, js/api.js, js/sidebar.js. npm test 251 pass / 8 baseline fail (game.test.js 13/13); lint:routes 0; миграция применяется чисто.

Key Architecture Decisions

  • «Атом» = блок goal в спеке (булево SimExpr). Любой уровень = спека SimForge + goal. Движок вычисляет goal.when каждый кадр; победа → result + callback. Нет goal → no-op.
  • Уровни хранятся в custom_sims (cat='game'), а не в новой таблице. Реюз авторинга/шаринга/embed. Новые таблицы — только под ПРОГРЕСС игрока и лидерборд (мигр.).
    • Уточнение Ф1: для MVP уровни — ВСТРОЕННЫЕ ДАННЫЕ в frontend/js/game/levels.js (window.QuantikLevels, форма { id, title, subject?, hint?, spec }), а не записи custom_sims. custom_sims cat='game' остаётся целевым хранилищем для авторённых уровней (Ф5); реестр тогда станет асинхронным (загрузка опубликованных + слияние со встроенными той же формы записи).
  • Герой Квантик: в уровне = engine point с body + glow + trail (визуал P2). На карте/в диалогах = PetSprite.render(level, mood, accessories, colorKey, streak, pattern) (DOM SVG).
  • Управление = чинить закон, а не WASD: игрок крутит params-слайдеры движка (угол/скорость/ гравитация) или собирает f(x); затем «Запуск» — симуляция проигрывается к цели.
  • Безопасность: цвета — только в canvas-стоки; текст спеки — escape (& < >); выражения — только длина на сервере, исполняет безопасный SimExpr на клиенте.

Engine touch-points (Phase 0)

  • Спека v1 формат — в шапке _sim_engine.js. Добавить goal/game СЮДА (документировать).
  • rAF-цикл _renderFrame (вычисляет env). Добавить _evalGoal() после построения env.
  • mount() возвращает инстанс — добавить onGoal, getResult, resetResult.
  • HUD — DOM-оверлей _labelLayer/новый слой (как readout-бейджи). Без эмодзи, inline SVG.
  • Серверный гейт customSimController.validateSpec (:93) — разрешить goal/stars/hint/game.

Cross-Phase Dependencies

  • Phase 1+ зависят от goal/getResult/onGoal из Phase 0.
  • Phase 2 (XP/скины) зависит от прогресса Phase 1.
  • Phase 4 (туннелирование) зависит от флешкарт-SR API.
  • Phase 5 (авторинг) трогает sim-builder — к этому моменту чужой P4-WIP должен быть смержен в sim-builder; свериться перед стартом фазы (возможен мерж base-ветки).
  • Phase 6 (живая гонка) зависит от моста sim_state (Ф7 sim-builder) — он на base-ветке.

Temporary Workarounds

(пока нет)

Phase 0 — API/гочи (для следующих фаз)

  • Движковое API цели: inst.onGoal(cb) (1 раз при победе, cb получает getResult()), inst.getResult(){won,failed,timeMs,attempts,stars:{got,total}} (без goal → null), inst.resetResult() (сброс результата, НЕ считается попыткой). inst.reset() = полный перезапуск уровня + attempts++ (пользовательская попытка; первый авто-reset при mount НЕ считается).
  • HUD появляется автоматически при наличии goal в спеке (отдельного флага «game mode» нет).
  • timeMs = мировое время t от старта (max(1, round(t*1000))), детерминизм; не wallclock.
  • Env цели = весь env кадра + единственный доп.идентификатор tries (= attempts). Других не вводить.
  • Серверный validateSpec принимает goal{when,title,hint,hold,fail,stars≤3} и game{...} (резерв Ф1/5); выражения не исполняются (только длина ≤500), текст escape+обрезка.
  • Победа делает pause() в кадре; следующий queued-rAF выходит рано → onGoal не задвоится.

Open Questions / Notes

  • Категория cat='game' — проверить список CATS в customSimController.js, расширить при необходимости.
  • Ассеты: разрешены CC0/открытые из интернета (выбор пользователя) — фиксировать источник+лицензию в коммите/доке; визуальная база остаётся in-house (PetSprite/canvas/FLUX).
  • Маршрут страницы игры: clean URL /quantik (паттерн /sim-builder, /lab).