Files
Learn_System/plans/quantik-game/CONTEXT.md
T
Maxim Dolgolyov 4b5c8077d3 @
feat(quantik-game): фаза 0 — слой целей в движке (goal/HUD/result)

Декларативный блок goal в спеке SimForge (булево SimExpr-условие победы),
вычисляемый каждый кадр: фиксация результата (победа/время/попытки/звёзды),
callback onGoal, HUD-оверлей (цель/звёзды/подсказка/баннер, inline SVG).
API инстанса: onGoal/getResult/resetResult. Серверный validateSpec
пропускает goal/game (длина выражений + escape текста, без исполнения).
Аддитивно: спека без goal ведёт себя как раньше. Смоук 40/40; npm test
238 pass/8 baseline; lint:routes 0. План фичи (7 фаз) + CONTEXT.

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

5.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.

Key Architecture Decisions

  • «Атом» = блок goal в спеке (булево SimExpr). Любой уровень = спека SimForge + goal. Движок вычисляет goal.when каждый кадр; победа → result + callback. Нет goal → no-op.
  • Уровни хранятся в custom_sims (cat='game'), а не в новой таблице. Реюз авторинга/шаринга/embed. Новые таблицы — только под ПРОГРЕСС игрока и лидерборд (мигр.).
  • Герой Квантик: в уровне = 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).