---
type: reference
title: Манифест caputchin.json
summary: Каждое поле манифеста caputchin.json, описывающего игру для маркетплейса, блок marketplace, указатели распространения, артефакт реплея run, блоки пресетов и сплит-файлы .caputchin.
---

`caputchin.json` в корне твоего репозитория это источник истины автора и индексатора для игры маркетплейса. Индексатор читает его на сервере, чтобы узнать идентичность игры, где живёт её бандл, какие пресеты она предлагает и как её реплеить. Он **никогда** не читается в браузере; SDK не загружает его в рантайме.

Эта страница это справочник полей. Для построения смотри [Построй игру для маркетплейса](/docs/marketplace-game-development/build-a-marketplace-game); для публикации смотри [Опубликуй в маркетплейс](/docs/marketplace-game-development/publish-to-the-marketplace). Точные типы экспортируются из SDK как `GameManifest` (смотри [справочник SDK](/docs/marketplace-game-development/game-sdk-reference)).

## Минимальная одиночная игра

```json
{
  "terms_accepted": true,
  "license": "MIT",
  "marketplace": {
    "name": "Leaf Memory",
    "description": "Match pairs of tropical leaves before the timer runs out.",
    "preview": "preview.png"
  },
  "npm": "@your-org/leaf-memory",
  "entry": "dist/leaf-memory.js"
}
```

## Поля верхнего уровня

| Поле | Обязательно | Назначение |
|---|---|---|
| `terms_accepted` | для индексации | Должно быть литеральным `true`, чтобы подтвердить, что ты принимаешь [Условия отправки в маркетплейс](/legal/submission-terms). Любое другое значение (или отсутствие) выбрасывает манифест из индекса. Только-самостоятельно-размещаемые манифесты могут его опустить. |
| `license` | для индексации | Идентификатор или выражение SPDX, покрывающее твой код и встроенные ассеты. Должно вычисляться в одобренный идентификатор (смотри [справочник ошибок публикации](/docs/marketplace-game-development/publish-failed-reference#approved-licenses)). |
| `marketplace` | для индексации | Присутствие это сигнал «индексируй меня». Отсутствие означает валидную [самостоятельно размещаемую](/docs/custom-game-development/overview) игру, которую маркетплейс игнорирует. Смотри [Блок marketplace](#the-marketplace-block). |
| `npm` | с `entry` | Координата npm-пакета, которую индексатор разрешает в URL jsDelivr. |
| `entry` | с `npm` | Путь к собранному бандлу относительно репозитория. `entry`, `npm` или оба должны присутствовать для запускаемой игры. |
| `games` | для коллекций | Пути под-манифестов для обёртки коллекции. Взаимно исключающи с `entry` / `npm`. Смотри [Коллекции](#collections). |
| `run` | опционально | Выделенный headless-артефакт реплея. Смотри [Артефакт run](#the-run-artifact). |
| `preferred` | опционально | Подсказки представления, которые хост МОЖЕТ учесть. Смотри [Блок preferred](#the-preferred-block). |
| `locales` / `skins` / `configurations` | опционально | Блоки пресетов, потребляемые SDK в iframe. Смотри [Блоки пресетов](#preset-blocks). |

Поля `version` нет: индексатор сам прибивает бандл к неизменному ref (опубликованная версия npm или разрешённый коммит SHA).

## Блок marketplace [#the-marketplace-block]

| Поле | Назначение |
|---|---|
| `name` | Заголовок карточки. Откатывается на имя репозитория (одиночная / обёртка) или имя leaf-каталога (ребёнок коллекции). |
| `description` | Подзаголовок карточки и тело страницы деталей. |
| `preview` | Путь изображения (относительно корня репозитория) или абсолютный URL. Около 600x315, субъект по центру. |
| `version` | Строка версии только для отображения на странице деталей. Опционально. |
| `support` | Объявленные автором флаги совместимости (`responsive`, `touch`, `accessible`, `audio`, ...), никогда не проверяемые платформой; выводятся как фильтры и иконки карточки. |
| `author` | Опциональный `{ name?, url?, email? }`. `name` / `url` рендерятся как подпись автора на странице деталей; `email` никогда не показывается и является **opt-in** для [писем о сбое публикации](/docs/marketplace-game-development/publish-to-the-marketplace#get-notified-when-a-publish-fails). Все три подполя независимы. |

Блок полностью опционален. Опусти `name` / `url`, и страница деталей просто не показывает подпись автора (владелец GitHub, показываемый в другом месте на странице, это отдельная, всегда присутствующая идентичность, а не откат для этой подписи). Опусти `email`, и ты не получаешь уведомлений о сбое публикации. Задавай только те подполя, что хочешь.

## Указатели распространения

Индексатор прибивает бандл каждой игры к неизменному ref, чтобы сохранённый хеш целостности оставался валидным, и перерешает на каждом прогоне (ежедневный cron плюс ручное «Опубликовать или обновить»):

- `entry` + `npm` разрешаются в `cdn.jsdelivr.net/npm/<npm>@<resolved-version>/<entry>`.
- Только `entry` разрешается в `cdn.jsdelivr.net/gh/<owner>/<repo>@<commit-sha>/<entry>`.
- Только `npm` разрешается в дефолтную точку входа пакета на закреплённой версии.

Нет пользовательского закрепления версии; чтобы заморозить сборку, пользователь размещает её сам через атрибут `game-src` виджета ([пользовательская игра](/docs/custom-game-development/self-hosted-game)).

## Артефакт run [#the-run-artifact]

По умолчанию самопроверка реплея запускает твой живой бандл `entry`. Когда твоя игра большая или основана на фреймворке либо WASM, поставь выделенный лёгкий headless-артефакт `run` вместо этого:

```json
{
  "run": {
    "entry": "dist/run.js",
    "modules": [
      { "name": "sim.wasm", "type": "wasm", "path": "dist/sim.wasm" }
    ]
  }
}
```

| Поле | Значение |
|---|---|
| `run.entry` | Путь к headless-бандлу `run` относительно репозитория (экспорт `run` [контракта реплея](/docs/marketplace-game-development/replay-contract)). |
| `run.modules` | Опциональный массив записей модулей, которые run импортирует по `name`. |

### Ограничения, которые соблюдает индексатор

Они валидируются во время индексации; нарушение проваливает публикацию с `manifest-error` (смотри [справочник ошибок публикации](/docs/marketplace-game-development/publish-failed-reference)).

**`run.entry`:**

- Должен быть **JavaScript**: базовое имя должно совпадать с `[a-zA-Z0-9_-]+.js`. Артефакт run всегда JS (WASM поставляется как модуль, ниже).
- Должен быть чистым путём относительно репозитория: без ведущего слеша, без обхода `..`, без пробелов, без `?` / `#`, без префикса `scheme://`.

**Каждая запись `run.modules[]`** это `{ name, type, path }`:

- `name` должно совпадать с `[a-zA-Z0-9_-]+.(wasm|js)`, модуль это либо **JS, либо WASM**, ничего больше. `name` это спецификатор импорта, который использует entry.
- `type` должен согласоваться с расширением: `wasm` для имени `.wasm`, `js` для имени `.js`.
- `name` не должно быть **зарезервированным** именем (`entry.js`, `artifact.js`), которое хост реплея использует внутри.
- `name` должно быть **уникальным** внутри массива (без дубликатов).
- `path` должен быть чистым путём относительно репозитория (те же правила, что и у `run.entry`).
- Не более **16** модулей.

Опусти `run`, чтобы реплеить живой `entry` напрямую. Смотри [контракт реплея](/docs/marketplace-game-development/replay-contract) о том, что должен экспортировать артефакт.

## Блок preferred [#the-preferred-block]

Опциональный блок `preferred` несёт подсказки представления. Каждый ключ совещательный: хост МОЖЕТ его учесть, и он никогда не перебивает явный атрибут встраивания.

```json
{
  "preferred": { "width": 360, "height": 480, "layout": "modal" }
}
```

Адаптивная игра, которая должна занимать свой контейнер по умолчанию, может объявить `"full"` на любой оси:

```json
{
  "preferred": { "width": "full", "height": 480 }
}
```

| Поле | Значение |
|---|---|
| `width` / `height` | Пиксельный след или литеральное `"full"`. Виджет применяет это, когда встраивание оставляет `width` / `height` незаданными (явное значение встраивания, включая `full`, побеждает вместо этого). Пиксельное значение задаёт iframe этот размер; `"full"` растягивает эту ось, чтобы заполнить родителя, тот же эффект, что у встраивания `width="full"`. Опусти, чтобы откатиться на встроенный дефолтный след виджета. |
| `layout` | Оболочка, которую виджет строит вокруг игры: `inline`, `modal` или `fullscreen`. Используется только когда встраивание оставляет `layout` незаданным (его дефолт `auto`). Порядок разрешения: атрибут `layout` встраивания, затем эта предпочтительная раскладка, затем `inline`. |

Эти подсказки учитываются только для игр, которые платформа разрешает на сервере (игры маркетплейса или id игры, данный без ключа сайта). Самостоятельно размещённый бандл `game-src`, который платформа не может прочитать до монтирования, игнорирует и след, и подсказку раскладки.

## Блоки пресетов [#preset-blocks]

`locales`, `skins` и `configurations` каждый объявляют опциональную `schema` (типы и документацию на каждый ключ) плюс `presets` (именованные банки опций). Виджет разрешает выбор посетителя против них и вручает твоей игре уплощённый результат как [`ctx`](/docs/marketplace-game-development/game-sdk-reference). Полный каталог типов полей это общий [справочник схемы настройки](/docs/references/customization-schema); те же типы питают [схему панели пользовательской игры](/docs/custom-game-development/dashboard-schema).

Поле `skins.schema` может быть `color`, ассетом (`image` / `audio` / `video`) или скаляром (`boolean`, `number`, `range`, `list`), используя те же формы ограничений, что и `configurations` (`{ "type": "range", "min": 0, "max": 24 }`, `["dots","stripes"]` и так далее). Скалярные значения скина разрешаются в своё типизированное значение в `ctx.skin` (`number` это настоящее число), ровно как значение конфигурации; значения цвета и ассета разрешаются в строки.

`_theme` пресета скина объявляет режим, в котором он работает: `light`, `dark` или `any` (опущение означает `any`). Пресет `light` или `dark` показывается только в этом режиме; пресет `any` читается на любом фоне и годен для обоих. Есть одно умолчание на режим. Пресет, помеченный `_default: true`, это умолчание для тех режимов, для которых он годен, так что умолчание `any` покрывает оба; когда несколько годных пресетов помечены умолчанием для режима, первый в порядке объявления его побеждает. Перечисли пресет, специфичный для режима, выше пресета `any`, чтобы дать этому режиму выделенный скин, пока пресет `any` проваливается на другой.

## Сплит-файлы `.caputchin/`

Блоки пресетов (особенно полные наборы локалей) делают `caputchin.json` длинным. Перенеси любую ось в свой собственный файл под папкой `.caputchin/`, оставив манифест коротким:

```
caputchin.json
.caputchin/locales.json
.caputchin/skins.json
.caputchin/configurations.json
```

Объект верхнего уровня каждого файла **является** этим блоком оси (`{ schema?, presets }`). Все три опциональны. Старшинство это замена целой оси, `caputchin.json` побеждает: если ось объявлена и инлайн, и как файл, используется инлайновый блок, а файл игнорируется (публикация предупреждает, чтобы ты знал, что он мёртв). Держи каждую ось ровно в одном месте.

## Коллекции [#collections]

Репозиторий может поставлять несколько игр. Обёртка коллекции объявляет пути детей вместо `entry` / `npm`:

```json
{
  "marketplace": { "name": "Caputchin Core Pack", "description": "The official pack." },
  "games": ["./packages/leaf-memory", "./packages/dino-runner"]
}
```

Каждый путь указывает на каталог-ребёнок, держащий свой собственный `caputchin.json`. Id детей это `owner/repo/<leaf-dir>`. Опусти блок `marketplace` обёртки, чтобы индексировать детей без страницы коллекции.

## См. также

- [Построй игру для маркетплейса](/docs/marketplace-game-development/build-a-marketplace-game): производство бандла, на который указывает этот манифест.
- [Контракт реплея](/docs/marketplace-game-development/replay-contract): что должен экспортировать артефакт `run`.
- [Справочник ошибок публикации](/docs/marketplace-game-development/publish-failed-reference): каждая ошибка валидации манифеста и список одобренных лицензий.
- [Справочник схемы настройки](/docs/references/customization-schema): типы полей, которые используют блоки пресетов.
