# Спецификация автономных HTML-микроигр для QR / `data:` URL
## Шаблон промпта
Скопируйте этот блок, заполните известные поля и приложите данную спецификацию.
```text
Создай автономную HTML-микроигру по приложенной спецификации.
Идея: [краткое описание игры]
Сложность: [1–5, по умолчанию 3]
Ориентация: [портретная / альбомная / любая; по умолчанию портретная]
Язык интерфейса: [по умолчанию русский]
Управление: [особые пожелания или «выбери сам»]
Компактность: [максимальная / обычная; по умолчанию максимальная]
Дополнительные условия: [необязательно]
Верни только один полный HTML-документ, начиная с <!doctype html>.
Не используй Markdown и не добавляй пояснения до или после HTML.
Целевой уровень коррекции QR — M. Рассматривай L только как крайний вариант,
если законченная основная механика после упрощения действительно не помещается в M.
Если поле не заполнено, выбери самый компактный работоспособный вариант.
При конфликте требований соблюдай приоритеты из спецификации.
Не добавляй тесты, отладочный интерфейс, внешние ресурсы и возможности,
которые не нужны для описанной игры.
```
---
## 1. Назначение и приоритеты
Спецификация предназначена для создания небольших игр, которые сохраняются в
одном HTML-файле, кодируются в `data:` URL и запускаются офлайн после
сканирования QR-кода.
Если требования конфликтуют, приоритет следующий:
1. автономный запуск и работоспособность;
2. управление и читаемость на смартфоне;
3. попадание в доступный размер QR;
4. сохранение основной игровой механики;
5. оформление и дополнительные эффекты.
Необязательное оформление и функции нужно сокращать раньше игровой механики.
## 2. Результат
Если явно не запрошено иное, результат должен содержать только:
- один полный HTML-документ;
- встроенные CSS и JavaScript;
- готовую к запуску игру без сборки и установки зависимостей.
Не нужно возвращать отдельно описание, инструкцию, список параметров, тесты,
отладочную версию или готовый `data:` URL. Оптимизацию, кодирование и создание QR
выполняет QR Microapps Lab.
## 3. Обязательные требования
Игра должна:
- начинаться с единственного `<!doctype html>`;
- полностью работать без интернета;
- состоять из одного HTML-файла;
- не обращаться к CDN, API, серверу или другим файлам;
- не использовать внешние библиотеки, шрифты, изображения, аудио и импорты;
- содержать `<meta charset=utf-8>`;
- содержать мобильный viewport как минимум с
`width=device-width,initial-scale=1`;
- запускаться прямым открытием файла и из `data:` URL;
- не открывать внешние адреса, новые окна и не перенаправлять пользователя;
- считать смартфон и управление пальцем основной средой;
- не требовать клавиатуру, мышь или наведение указателя;
- помещать игровое поле и основные элементы в доступную область экрана;
- не создавать прокрутку, если она не является частью механики;
- сохранять читаемый текст и достаточно крупные цели касания;
- иметь понятную цель, состояние завершения и возможность повторного запуска.
- запускаться без ошибок JavaScript, необработанных Promise и заблокированных
попыток загрузить ресурсы или обратиться к сети.
Клавиатурное управление и поддержка старых браузеров добавляются только по
явному запросу.
## 4. Сложность
Сложность задаётся целым числом от `1` до `5`:
- `1` — очень легко;
- `2` — легко;
- `3` — средняя сложность и значение по умолчанию;
- `4` — сложно;
- `5` — очень сложно.
Правила реализации:
- объявить в JavaScript ровно одну глобальную переменную `var $d=3;`;
- считать `$d` зарезервированной переменной сложности, которую QR Microapps Lab
изменяет при подготовке разных вариантов QR-кода;
- использовать выбранное в промпте значение вместо `3`, сохраняя диапазон `1..5`;
- не переименовывать `$d`, не объявлять её повторно и не присваивать ей другое
значение во время игры;
- считать весь префикс `$` зарезервированным для переменных формата QR Microapps
Lab: разработчик не должен объявлять собственные переменные, параметры или
функции с именами, начинающимися с `$`;
- использовать `$d` как единственное разрешённое разработчику системное имя с
этим префиксом; в будущих версиях формат может определить другие переменные `$…`;
- менять через неё только значимые параметры баланса: скорость, время, частоту,
число целей, размер безопасной зоны, количество попыток или допустимых ошибок;
- не создавать пять копий уровней, если параметры можно вычислить компактно;
- не добавлять видимый выбор сложности, настройки или отдельное меню без запроса;
- не усложнять код и оформление только из-за более высокого уровня сложности.
На уровне `3` игра должна быть проходимой без предварительного знания механики,
но требовать внимания или нескольких осмысленных действий.
## 5. Ввод
Для единой поддержки пальца, стилуса и мыши предпочтительно использовать
Pointer Events как основной канал ввода.
Обязательные свойства:
- одно физическое касание вызывает одно игровое действие;
- не следует одновременно подключать pointer-, touch- и mouse-обработчики к
одной механике без явной дедупликации;
- нажатие кнопки интерфейса не должно одновременно запускать действие на игровом поле;
- системные жесты, выделение текста и контекстное меню нужно отключать только
там, где они мешают управлению;
- для перетаскивания или удержания применять Pointer Capture либо равноценную
компактную логику, если без неё управление теряется за пределами элемента;
- обрабатывать отмену активного непрерывного ввода, если она может оставить
игру в зависшем состоянии.
Не нужно добавлять отдельные Touch Events и Mouse Events как запасной вариант,
если целевые браузеры поддерживают Pointer Events.
## 6. Экран и масштабирование
Игра должна корректно выглядеть прежде всего на вертикальном экране смартфона,
если в запросе не выбрана другая ориентация.
- не привязывать важные элементы к единственному разрешению;
- учитывать изменение доступного размера и ориентации, если от них зависит поле;
- сохранять игровые объекты, текст и управление внутри видимой области;
- не вводить обязательный базовый макет, сложную систему масштаба или безопасные
поля, если простая адаптивная вёрстка решает задачу;
- не использовать жёсткие ограничения, делающие игру слишком мелкой на большом экране.
Для canvas требования применяются только при его использовании:
- координаты отрисовки и координаты касания должны соответствовать друг другу;
- изменение размера не должно ломать положение и столкновения объектов;
- учитывать `devicePixelRatio`, когда без этого заметно страдают чёткость текста
или игровой процесс;
- не добавлять универсальный масштабатор, если достаточно короткого пересчёта размеров.
## 7. Игровой цикл и завершение
- Для непрерывной анимации использовать `requestAnimationFrame`.
- Скорость движения, таймеры и другие зависящие от времени процессы рассчитывать
по прошедшему времени, а не по количеству кадров.
- Это правило не требует игрового цикла в викторинах, пошаговых и событийных играх.
- После победы или поражения игровая логика и управление должны прекратиться.
- Если ведётся счёт, итоговое значение должно оставаться видимым до перезапуска.
- Повторный запуск должен полностью восстановить начальное состояние без дублей
таймеров, циклов и обработчиков.
Не требуются определённые имена функций, классы или архитектурные слои. Важен
наблюдаемый результат, а не внутренняя структура программы.
Нативные `alert`, `confirm` и `prompt` не использовать как основной игровой
интерфейс. Компактный экран результата внутри игры предпочтительнее.
## 8. Экономия размера
Размер оценивается не по числу символов в исходнике, а по байтам
оптимизированного HTML и полного Base64 `data:` URL. Окончательный расчёт всегда
выполняет QR Microapps Lab, но при создании игры нужно придерживаться следующих
ориентиров для QR версии 40:
- основной и предпочтительный уровень — коррекция **M**;
- рекомендуемый объём оптимизированного HTML для M — не более **1600 байт**,
чтобы оставить запас на упаковку и небольшие изменения;
- технический предел используемого лабораторией Base64 `data:` URL при M —
**2331 байт**, что соответствует примерно **1719 байтам HTML**;
- не следует заранее заполнять весь предел M: меньший код обычно создаёт менее
плотную матрицу и легче считывается с экрана;
- коррекция **L** допустима только как запасной, нежелательный вариант, когда
основную законченную механику невозможно сохранить в M после разумного
упрощения;
- предел Base64 `data:` URL при L — **2953 байта**, или примерно **2187 байт
HTML**; даже при L желательно оставлять запас;
- L содержит меньше данных для исправления повреждений, поэтому такой QR менее
устойчив к дефектам, бликам, недостаточной чёткости и сложнее считывается в
реальных условиях;
- если игра не помещается и в L, её нужно упростить: один автономный QR не должен
создаваться ценой превышения стандартной вместимости.
Значения HTML являются предварительными ориентирами для текущего префикса и
Base64-упаковки QR Microapps Lab. Решение о M или L принимается только по
измеренному размеру итогового `data:` URL в лаборатории.
Для экономии кода:
- реализовать только основную законченную механику;
- не добавлять универсальный движок и абстракции «на будущее»;
- не дублировать разметку, стили, данные и обработчики;
- использовать компактные структуры данных;
- для викторин не создавать отдельную HTML-разметку для каждого вопроса;
- не встраивать крупные изображения, шрифты, аудио, SVG и таблицы данных без запроса;
- не добавлять заставки, обучение, настройки, таблицу рекордов, частицы и сложные
эффекты, если они не нужны идее игры;
- не добавлять комментарии, диагностические сообщения и код, не влияющий на игру;
- не создавать вторую, тестовую или расширенную версию;
- не помещать внутрь игры генератор `data:` URL или QR-кода.
Компактность не должна достигаться ценой синтаксических ошибок, неработающего
управления или невозможности перезапустить игру. Финальную механическую
оптимизацию исходника выполняет лаборатория.
## 9. Условные требования
Добавлять только когда этого требует идея игры:
- обработку `resize` — если размеры влияют на поле или ввод;
- Pointer Capture — для drag, удержания и непрерывного ведения;
- расчёт `dt` — для движения и таймеров;
- отдельный экран результата — если завершение иначе непонятно;
- звук — только по явному запросу, автономно и после пользовательского действия;
- локализацию — только для реально требуемых языков, без отдельного фреймворка;
- сложный HUD — только для значимых счёта, времени или ресурсов;
- специальный сценарий первого препятствия — только если старт иначе получается пустым;
- сохранение результата — только по явному запросу.
## 10. Тестирование
Тесты выполняются снаружи — средствами QR Microapps Lab и ручным запуском на
целевых устройствах. В HTML игры по умолчанию запрещено добавлять:
- test mode и self-check;
- тестовые функции и публичные хуки;
- отладочные панели и журналы;
- дублирующую dev/test-версию;
- код, существующий только ради тестовой архитектуры.
Спецификация требует проверяемого поведения, но не предписывает структуру кода.
## 11. Минимальный чек-лист приёмки
Этот список предназначен для внешней проверки и не должен встраиваться в игру:
- открывается одним HTML-файлом без сети;
- не содержит внешних запросов и зависимостей;
- начинается с `<!doctype html>` и содержит UTF-8 и корректный мобильный viewport;
- запускается из подготовленного лабораторией `data:` URL;
- запускается в изолированном предпросмотре без ошибок и заблокированных операций;
- основные действия выполняются пальцем;
- одно касание не срабатывает дважды;
- на целевом экране нет случайной прокрутки и недоступных элементов;
- движение и таймеры не зависят от FPS, если они есть;
- завершение останавливает игру и сохраняет итоговый результат;
- повторный запуск полностью сбрасывает состояние;
- в JavaScript ровно один раз объявлена `var $d=3;` или другое выбранное значение
из диапазона `1..5`;
- собственные идентификаторы разработчика не начинаются с зарезервированного
префикса `$`;
- итоговый Base64 `data:` URL предпочтительно помещается в M; L используется
только после попытки сократить код без потери основной механики и сопровождается
предупреждением о меньшей устойчивости QR.
## 12. Документация примера в каталоге
Этот раздел применяется только при добавлении готовой игры в каталог QR
Microapps Lab. Документация является метаданными элемента каталога, хранится
отдельно от HTML игры и не включается в её `data:` URL или QR-код. При обычном
создании игры по шаблону из начала файла по-прежнему нужно вернуть только HTML.
Элемент каталога может содержать необязательное поле `documentation`:
```js
documentation: {
title: 'Как играть',
intro: ['Краткая цель игры.'],
sections: [
{ title: 'Управление', items: ['Нажмите слева', 'Нажмите справа'] },
{ title: 'Правила', paragraphs: ['Краткое объяснение механики.'] }
]
}
```
Поддерживаемые поля раздела:
- `title` — заголовок;
- `paragraphs` — массив обычных абзацев;
- `items` — маркированный список;
- `diagram` — компактная текстовая схема с сохранением пробелов и переносов;
- `visualization` — структурированные данные для отдельного встроенного
визуализатора.
Текст должен быть самодостаточным: цель, управление, условия победы и поражения,
влияние сложности и важные числовые параметры. Описание не должно повторять весь
исходный код или содержать внешние ссылки, необходимые для понимания игры.
### 12.1. Статичная карта `grid-map`
Тип `grid-map` предназначен для компактных прямоугольных карт и строит безопасный
масштабируемый SVG средствами редактора. В документации хранятся только строки
сетки и маркеры, а не готовое растровое изображение:
```js
visualization: {
type: 'grid-map',
title: 'Карта 5 × 5',
caption: 'S1 → E · кратчайший путь 4 шага',
wall: '1',
rows: [
'11111',
'10001',
'10101',
'10021',
'11111'
],
starts: [{ label: 'S1', index: 6 }],
exit: { label: 'E', index: 18 }
}
```
Правила формата:
- все строки `rows` имеют одинаковую ненулевую длину;
- `wall` задаёт символ стены, остальные клетки считаются проходами;
- индекс клетки вычисляется как `y * ширина + x`, начало координат находится
слева сверху;
- `starts` содержит подписи и индексы точек старта;
- `exit` содержит подпись и индекс выхода;
- `title` используется как доступное название SVG, `caption` — как короткая
видимая подпись;
- карта является статичной: она показывает геометрию, все старты и выход без
обязательных переключателей или скрытых состояний.
Для простой моноширинной схемы можно сохранить поле `diagram`. Для лабиринта,
поля по клеткам или плана уровня предпочтителен `grid-map`: SVG остаётся чётким
на телефоне и большом экране, поддерживает тему редактора и обычно требует лишь
несколько сотен символов данных.
### 12.2. Другие карты и изображения
Нельзя помещать произвольный SVG или HTML в `innerHTML` документации. Для нового
вида изображения следует определить отдельный декларативный тип визуализации и
отдельный безопасный рендерер, который создаёт DOM или SVG из проверяемых данных.
Например, интерактивная карта маршрутов не должна менять смысл статичного
`grid-map`: для неё нужен самостоятельный тип наподобие `grid-map-routes`.
Растровые PNG, JPEG и WebP уместны только когда схему нельзя выразить компактными
данными. Они увеличивают автономный файл редактора, поэтому должны добавляться
явно, иметь проверенное происхождение и лицензию, не содержать персональные
данные и встраиваться сборщиком без сетевой загрузки. Исходный материал и
публикуемая производная копия должны храниться раздельно по правилам проекта.
### 12.3. Обратная совместимость визуализаторов
Форматы документации являются расширяемыми, но уже опубликованные документы не
должны требовать переделки после добавления новых возможностей:
- `documentation` и все поля разделов остаются необязательными;
- существующие `paragraphs`, `items` и `diagram` продолжают отображаться без
изменения их смысла;
- известный `visualization.type` сохраняет прежние обязательные поля, внешний
вид данных и базовое поведение;
- в существующий тип можно добавлять только необязательные поля с безопасными
значениями по умолчанию;
- несовместимая структура или другое поведение получают новое имя `type` и
отдельный рендерер;
- неизвестный тип визуализации должен быть проигнорирован без ошибки, а текст и
остальные разделы документа должны остаться доступными;
- для каждого опубликованного типа сохраняется браузерная проверка; отдельно
проверяется старое поле `diagram`.