playdev

Сделать игру с помощью ИИ

Скопируйте промпт в любой ИИ — он соберёт браузерную игру по правилам площадки: с облачными сохранениями, без внешних библиотек и готовую к загрузке одним ZIP.

Открыть на playdev

Зачем это

Скопируйте промпт в любой ИИ — он соберёт браузерную игру по правилам playdev: с облачными сохранениями, без внешних библиотек и готовую к загрузке одним ZIP. Программировать не нужно, достаточно описать идею.

Промпт целиком

Ты — опытный разработчик браузерных игр. Сделай законченную небольшую игру,
которую можно сразу выложить на площадку playdev и в которую сразу можно играть.

ИДЕЯ ИГРЫ
{{ИДЕЯ}}

ФОРМАТ ОТВЕТА
Выдай ровно три файла, каждый — отдельным блоком кода с указанием пути:

  index.html         — точка входа, лежит в КОРНЕ архива
  assets/style.css   — все стили
  assets/game.js     — вся логика

Только HTML, CSS и JavaScript (ES2020+). Никаких сборщиков, npm, фреймворков
и внешних библиотек — файлы должны работать в браузере как есть.

=== 1. ЖЁСТКИЕ ПРАВИЛА ПЛОЩАДКИ ===

Игра выполняется в iframe на отдельном домене под строгой политикой
безопасности. Поэтому:

1. НИКАКИХ внешних ресурсов. Запрещены CDN, Google Fonts, картинки по URL,
   внешние скрипты и стили. Всё содержимое — внутри твоих трёх файлов. Любой
   внешний запрос будет заблокирован, и игра останется без библиотеки.
2. Только относительные пути: `assets/style.css`, `assets/game.js`. Путь,
   начинающийся с `/`, сломается — сборка раздаётся из подпапки.
3. Никакого серверного кода и сетевых вызовов: только статика. Никаких PHP,
   fetch к сторонним API, WebSocket.
4. Запрещено: `window.top`, `parent.`, `document.cookie`, `window.open`,
   `top.location`, любые попытки выйти из iframe.
5. Вся графика — SVG прямо в разметке или CSS, либо Canvas. Никаких бинарных
   файлов.
6. Шрифты только системные:
   `font-family: system-ui, -apple-system, "Segoe UI", sans-serif`.
7. Игра должна работать без интернета: ни одного сетевого запроса.

=== 2. СОХРАНЕНИЯ ПРОГРЕССА ===

Площадка даёт облачные сохранения. Подключи SDK и используй его — прогресс
должен переживать перезагрузку и переезд на другое устройство.

В `index.html` строго в этом порядке:

  <script src="/__playdev/sdk.js"></script>
  <script src="assets/game.js"></script>

API (глобальный объект `Playdev`):

  Playdev.available       // true, если игра запущена с площадки
  await Playdev.load()    // состояние игры; {} если сохранения ещё нет
  Playdev.save(state)     // поставить в очередь; запись сама через ~4 секунды
  await Playdev.flush()   // сохранить немедленно
  await Playdev.reset()   // удалить прогресс игрока
  await Playdev.unlock('id')  // выдать достижение из своего манифеста

Обязательный каркас — игра обязана работать и БЕЗ площадки, когда
`Playdev.available === false` (автор открыл файл у себя на компьютере):

  var SAVE_KEY = 'mygame-state-v1'

  function fresh() {
    return { v: 1 /* ...все поля состояния... */ }
  }

  var state = fresh()

  function loadLocal() {
    try { return JSON.parse(localStorage.getItem(SAVE_KEY) || 'null') } catch (e) { return null }
  }

  function saveLocal() {
    try { localStorage.setItem(SAVE_KEY, JSON.stringify(state)) } catch (e) {}
  }

  async function boot() {
    var raw = null

    if (window.Playdev && Playdev.available) {
      try { raw = await Playdev.load() } catch (e) { raw = null }
    }
    if (!raw || !raw.v) raw = loadLocal()
    if (raw && raw.v) state = Object.assign(fresh(), raw)   // старые сохранения не ломают игру

    start()
  }

  function persist() {
    if (window.Playdev && Playdev.available) Playdev.save(state)
    else saveLocal()
  }

Требования к сохранению:

* Всё состояние — один обычный объект, который чисто сериализуется в JSON.
* Обязательно поле `v` (версия). При загрузке восстанавливай недостающие поля
  значениями по умолчанию.
* Размер — до 50 КБ. Не пиши в сохранение логи, историю и картинки.
* `persist()` вызывай на значимых событиях (покупка, финиш уровня, смерть) и
  раз в ~10 секунд. Ни в коем случае не каждый кадр.
* Если облако не ответило — не теряй прогресс: пиши в localStorage и
  попробуй снова позже.
* Сделай кнопку сброса прогресса со своим диалогом подтверждения внутри
  интерфейса игры.
* Если в игре есть пассивный прогресс (ресурс копится во времени) — храни
  отметку времени и начисляй пропущенное при возвращении, но не больше
  нескольких часов.

=== 2.1 ДОСТИЖЕНИЯ (НЕОБЯЗАТЕЛЬНО) ===

Нужны достижения — положи рядом с `index.html` файл `achievements.json`:

  {
    "items": [
      { "id": "first_spark", "name": "Первая искра",
        "description": "Подкинуть первую ветку",
        "image": "achievements/first-spark.png" },
      { "id": "night_guest", "name": "Ночной гость",
        "description": "Кто-то приходил",
        "image": "achievements/guest.png", "hidden": true }
    ]
  }

Правила:
- `id` — латиница, цифры, дефис и подчёркивание, до 64 знаков. Больше нигде
  не встречается, игра присылает именно его;
- `image` — путь ВНУТРИ сборки. Внешние адреса не принимаются;
- `hidden: true` — секретное: до получения игрок видит «Секретное достижение»
  без описания и картинки;
- картинки — квадратные, 256×256, PNG. Площадка ничего не рисует сама:
  названия, описания и значки берутся из игры;
- до 100 достижений.

Выдавай так — повторный вызов безопасен, площадка не задвоит:

  if (warmth > 500 && !state.gotWarmNight) {
    state.gotWarmNight = true
    Playdev.unlock('warm_night').then(function (r) {
      if (r.new) показатьПлашку(r.achievement.name)
    })
  }

`Playdev.unlock` возвращает `{ new, achievement }`. Вне площадки вернёт
`{ new: false, achievement: null }` — проверять `Playdev.available` не нужно.

Если манифеста нет, игра просто останется без достижений. Это не ошибка.

=== 3. КАЧЕСТВО ===

* Интерфейс на русском, живые формулировки без канцелярита.
* Мобильные: `<meta name="viewport" content="width=device-width, initial-scale=1" />`,
  вёрстка держится от 320 px, кнопки не меньше 44×44 px, никаких действий
  только по наведению мыши.
* Управление и мышь/тач, и клавиатура. Для тача — pointer-события.
* Игра вписывается в любой размер окна:
  `html, body { height: 100%; margin: 0 }`, без фиксированной ширины.
* Игровой цикл — `requestAnimationFrame` с дельтой времени, а не `setInterval`,
  чтобы скорость не зависела от частоты кадров.
* Звук — только после первого действия игрока (автовоспроизведение
  заблокировано). Можно обойтись без звука.
* Уважай `@media (prefers-reduced-motion: reduce)`: отключай тряску и вспышки.
* Понятный экран победы/проигрыша и кнопка «начать заново».
* Никаких `alert()` и `confirm()`: пользователь должен всегда видеть
  нормальный интерфейс и мочь выйти кнопкой площадки.
* Коротко объясни управление прямо в игре — человек видит её впервые.

=== 4. САМОПРОВЕРКА ПЕРЕД ОТВЕТОМ ===

Прогони мысленно и почини, если что-то не так:

  [ ] ровно три файла: index.html, assets/style.css, assets/game.js
  [ ] в index.html есть <script src="/__playdev/sdk.js"></script>
  [ ] ни одной внешней ссылки в src, href, url(), import
  [ ] игра запускается и полностью играбельна БЕЗ площадки
  [ ] прогресс сохраняется, переживает перезагрузку и восстанавливается
  [ ] есть кнопка сброса прогресса
  [ ] играется на ширине 320 px
  [ ] нет обращений к window.top, parent, document.cookie, window.open
  [ ] нет alert() и confirm()
  [ ] нет ни одного сетевого запроса

=== 5. ЧТО ОБЪЯСНИТЬ ПОЛЬЗОВАТЕЛЮ В КОНЦЕ ===

Коротко, без воды:

1. Сохрани три файла, сохранив структуру папок.
2. Заархивируй СОДЕРЖИМОЕ папки в ZIP так, чтобы `index.html` оказался в корне
   архива, а не внутри вложенной папки.
3. На площадке: «Залить игру» → тип «Лёгкая», платформа «Браузер», приложи ZIP
   в поле «ZIP-сборка игры».
4. После модерации игра появится в каталоге, а прогресс игроков будет
   сохраняться в облаке автоматически.

Что он гарантирует

  • ровно три файла, index.html в корне архива;
  • ни одной внешней библиотеки — политика безопасности площадки их блокирует;
  • облачные сохранения через SDK и запасной вариант в localStorage, если игра открыта вне площадки;
  • сброс прогресса, мобильную вёрстку от 320 px и управление с клавиатуры.

Почему такие ограничения

Игра раздаётся с отдельного адреса, а не с домена площадки. Это защищает аккаунт игрока: код игры не может добраться до его данных. Плата за это — строгая политика безопасности, поэтому весь код должен лежать внутри сборки, а сохранения идти через SDK.

Куда дальше

Готовую игру загрузите через форму заявки: тип «Лёгкая», платформа «Браузер», ZIP-сборка. Как это устроено — в гайде «Как опубликовать игру».