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> @
50 lines
4.0 KiB
Markdown
50 lines
4.0 KiB
Markdown
# Phase 5: Авторинг уровней в sim-builder + раздача классу
|
||
|
||
**Status:** ⬜ Not Started
|
||
**Parent plan:** [PLAN.md](./PLAN.md)
|
||
**Domain:** fullstack
|
||
|
||
## Objective
|
||
Дать учителю собирать **игровые уровни без кода** в существующем sim-builder: задать цель/звёзды/
|
||
подсказку/главу/норматив, сохранить как `custom_sims` с `cat='game'`, опубликовать и раздать
|
||
классу. Игра начинает грузить уровни из БД (а не только встроенные).
|
||
|
||
⚠️ ПЕРЕД СТАРТОМ: свериться с base-веткой `feature/sim-builder` — чужой P4-WIP билдера должен
|
||
быть смержен. При необходимости влить base в `feature/quantik-game` и разрешить конфликты.
|
||
|
||
## Tasks
|
||
- [ ] Task 1: Режим «Игровой уровень» в `sim-builder.js`/`.html`: панель цели (`goal.when`,
|
||
`title`, `hint`, `hold`, `fail`), список звёзд (add/del: `when`+`label`), глава/порядок/`par_ms`.
|
||
Inline-проверка выражений через `SimExpr.compile().error` (как остальные поля билдера).
|
||
- [ ] Task 2: `buildSpec()` материализует блок `goal`/`game`; `loadFromSim()` раскладывает обратно
|
||
(round-trip), как сделано с plot-range в Ф4 билдера.
|
||
- [ ] Task 3: Кнопка «Играть» в билдере — открыть текущую спеку в игровом режиме (тест уровня автором).
|
||
- [ ] Task 4: Каталог уровней: игра грузит `custom_sims` c `cat='game'` (свои+published) — реюз
|
||
`LS.customSimsList`/`Get`. Категория `game` в списке `CATS` (customSimController) + фильтр.
|
||
- [ ] Task 5: Раздача классу: реюз паттерна Ф6 sim-builder (авто-публикация + `pushNotif` ученикам,
|
||
ссылка `/quantik?level=custom:<id>`); привязка к программе через `lab_sim_links` (`sim_id='custom:<id>'`).
|
||
- [ ] Task 6: Deep-link `/quantik?level=custom:<id>` (паттерн Ф5/Ф7 sim-builder, доступ own|published|admin).
|
||
- [ ] Task 7: Тесты: round-trip goal в билдере (headless как Ф4 sim-builder); доступ к чужому
|
||
draft запрещён; published-уровень виден; раздача шлёт уведомление.
|
||
|
||
## Files to Modify/Create
|
||
- `frontend/sim-builder.html`, `frontend/js/sim-builder.js` — режим игрового уровня (аддитивно).
|
||
- `backend/src/controllers/customSimController.js` — `CATS` += 'game'; (goal уже в validateSpec из Ф0).
|
||
- `frontend/js/game/quantik-game.js` — загрузка уровней из custom_sims + deep-link.
|
||
- тест(ы).
|
||
|
||
## Acceptance Criteria
|
||
- Учитель собирает уровень с целью/звёздами, тестирует «Играть», сохраняет/публикует.
|
||
- Игра грузит уровни из БД; deep-link открывает конкретный уровень с проверкой доступа.
|
||
- Раздача классу публикует + уведомляет; round-trip спеки без потерь; тесты зелёные; lint baseline 0.
|
||
|
||
## Notes
|
||
- Билдер — зона, где мог идти параллельный P4-WIP; правки строго аддитивны, свериться с base.
|
||
- Санитизация goal-полей — уже на сервере (Ф0). Клиентская валидация зеркалит её (как в Ф4 билдера).
|
||
|
||
## Review Checklist
|
||
- [ ] Все задачи; аддитивность билдера; ownership/доступ корректны; без эмодзи/eval; тесты зелёные
|
||
|
||
## Handoff to Next Phase
|
||
<!-- Заполняет агент-имплементер. -->
|