---
type: reference
title: Das caputchin.json-Manifest
summary: Jedes Feld des caputchin.json-Manifests, das ein Marketplace-Spiel beschreibt, der marketplace-Block, Distributions-Zeiger, das Replay-run-Artefakt, Preset-Blöcke und die .caputchin-Split-Dateien.
---

`caputchin.json` im Root deines Repositorys ist die Autoren- und Indexer-Wahrheitsquelle für ein Marketplace-Spiel. Der Indexer liest es serverseitig, um die Identität des Spiels zu lernen, wo sein Bundle lebt, welche Presets es bietet und wie man es abspielt. Es wird **nie** im Browser gelesen; das SDK lädt es zur Laufzeit nicht.

Diese Seite ist die Feld-Referenz. Für den Build sieh dir [Ein Marketplace-Spiel bauen](/docs/marketplace-game-development/build-a-marketplace-game) an; fürs Veröffentlichen sieh dir [An den Marketplace veröffentlichen](/docs/marketplace-game-development/publish-to-the-marketplace) an. Die genauen Typen werden aus dem SDK als `GameManifest` exportiert (siehe die [SDK-Referenz](/docs/marketplace-game-development/game-sdk-reference)).

## Ein minimales einzelnes Spiel

```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"
}
```

## Felder auf oberster Ebene

| Feld | Pflicht | Zweck |
|---|---|---|
| `terms_accepted` | für Indexierung | Muss das literale `true` sein, um zu bestätigen, dass du die [Marketplace-Einreichungsbedingungen](/legal/submission-terms) akzeptierst. Jeder andere Wert (oder fehlend) droppt das Manifest aus dem Index. Nur-selbst-gehostete Manifeste dürfen es weglassen. |
| `license` | für Indexierung | Ein SPDX-Identifier oder -Ausdruck, der deinen Code und die gebündelten Assets abdeckt. Muss zu einem genehmigten Identifier auswerten (siehe die [Publish-Fehler-Referenz](/docs/marketplace-game-development/publish-failed-reference#approved-licenses)). |
| `marketplace` | für Indexierung | Anwesenheit ist das "indexier mich"-Signal. Abwesend bedeutet ein gültiges [selbst gehostetes](/docs/custom-game-development/overview) Spiel, das der Marketplace ignoriert. Sieh dir [Der marketplace-Block](#the-marketplace-block) an. |
| `npm` | mit `entry` | npm-Paket-Koordinate, die der Indexer zu einer jsDelivr-URL auflöst. |
| `entry` | mit `npm` | Repo-relativer Pfad zum gebauten Bundle. `entry`, `npm` oder beide müssen für ein lauffähiges Spiel vorhanden sein. |
| `games` | für Sammlungen | Sub-Manifest-Pfade für einen Sammlungs-Wrapper. Gegenseitig ausschließend mit `entry` / `npm`. Sieh dir [Sammlungen](#collections) an. |
| `run` | optional | Ein dediziertes Headless-Replay-Artefakt. Sieh dir [Das run-Artefakt](#the-run-artifact) an. |
| `preferred` | optional | Präsentations-Hinweise, die der Host honorieren KANN. Sieh dir [Der preferred-Block](#the-preferred-block) an. |
| `locales` / `skins` / `configurations` | optional | Preset-Blöcke, die das SDK im Iframe konsumiert. Sieh dir [Preset-Blöcke](#preset-blocks) an. |

Es gibt kein `version`-Feld: der Indexer pinnt das Bundle selbst auf eine unveränderliche Ref (die veröffentlichte npm-Version oder die aufgelöste Commit-SHA).

## Der marketplace-Block [#the-marketplace-block]

| Feld | Zweck |
|---|---|
| `name` | Karten-Titel. Fällt auf den Repo-Namen (einzeln / Wrapper) oder den Leaf-Dir-Namen (Sammlungs-Kind) zurück. |
| `description` | Karten-Untertitel und Detail-Seiten-Body. |
| `preview` | Bild-Pfad (relativ zum Repo-Root) oder absolute URL. Etwa 600x315, Motiv zentriert. |
| `version` | Nur-Anzeige-Versions-String für die Detail-Seite. Optional. |
| `support` | Autor-deklarierte Kompatibilitäts-Flags (`responsive`, `touch`, `accessible`, `audio`, ...), nie von der Plattform verifiziert; als Filter und Karten-Icons zum Vorschein gebracht. |
| `author` | Optionales `{ name?, url?, email? }`. `name` / `url` rendern als Autoren-Byline auf der Detail-Seite; `email` wird nie gezeigt und ist das **Opt-in** für [Publish-Fehler-E-Mails](/docs/marketplace-game-development/publish-to-the-marketplace#get-notified-when-a-publish-fails). Alle drei Unterfelder sind unabhängig. |

Der Block ist vollständig optional. Lass `name` / `url` weg, und die Detail-Seite zeigt einfach keine Autoren-Byline (der anderswo auf der Seite gezeigte GitHub-Besitzer ist eine separate, immer vorhandene Identität, kein Fallback für diese Byline). Lass `email` weg, und du empfängst keine Publish-Fehler-Benachrichtigungen. Setz nur die Unterfelder, die du willst.

## Distributions-Zeiger

Der Indexer pinnt das Bundle jedes Spiels auf eine unveränderliche Ref, sodass der gespeicherte Integritäts-Hash gültig bleibt, und löst bei jedem Lauf neu auf (täglicher Cron plus manuelles "Veröffentlichen oder aktualisieren"):

- `entry` + `npm` lösen zu `cdn.jsdelivr.net/npm/<npm>@<resolved-version>/<entry>` auf.
- Nur `entry` löst zu `cdn.jsdelivr.net/gh/<owner>/<repo>@<commit-sha>/<entry>` auf.
- Nur `npm` löst zum Paket-Standard-Entry bei der gepinnten Version auf.

Es gibt kein nutzerseitiges Versions-Pinning; um einen Build einzufrieren, hostet ein Nutzer ihn selbst über das `game-src` des Widgets ([Custom-Spiel](/docs/custom-game-development/self-hosted-game)).

## Das run-Artefakt [#the-run-artifact]

Standardmäßig lässt die Replay-Selbstprüfung dein Live-`entry`-Bundle laufen. Wenn dein Spiel groß oder framework- oder WASM-basiert ist, liefere stattdessen ein dediziertes schlankes Headless-`run`-Artefakt:

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

| Feld | Bedeutung |
|---|---|
| `run.entry` | Repo-relativer Pfad zum Headless-`run`-Bundle (der [Replay-Vertrag](/docs/marketplace-game-development/replay-contract)-`run`-Export). |
| `run.modules` | Optionales Array von Modul-Einträgen, die der Run per `name` importiert. |

### Beschränkungen, die der Indexer durchsetzt

Diese werden zur Index-Zeit validiert; ein Verstoß lässt das Veröffentlichen mit einem `manifest-error` fehlschlagen (siehe die [Publish-Fehler-Referenz](/docs/marketplace-game-development/publish-failed-reference)).

**`run.entry`:**

- Muss **JavaScript** sein: der Basename muss `[a-zA-Z0-9_-]+.js` matchen. Das run-Artefakt ist immer JS (WASM wird als Modul ausgeliefert, unten).
- Muss ein sauberer repo-relativer Pfad sein: kein führender Slash, keine `..`-Traversierung, kein Whitespace, kein `?` / `#`, kein `scheme://`-Präfix.

**Jeder `run.modules[]`-Eintrag** ist `{ name, type, path }`:

- `name` muss `[a-zA-Z0-9_-]+.(wasm|js)` matchen, ein Modul ist entweder **JS oder WASM**, nichts sonst. Der `name` ist der Import-Specifier, den der Entry nutzt.
- `type` muss mit der Endung übereinstimmen: `wasm` für einen `.wasm`-Namen, `js` für einen `.js`-Namen.
- `name` darf kein **reservierter** Name (`entry.js`, `artifact.js`) sein, den der Replay-Host intern nutzt.
- `name` muss **eindeutig** im Array sein (keine Duplikate).
- `path` muss ein sauberer repo-relativer Pfad sein (dieselben Regeln wie `run.entry`).
- Höchstens **16** Module.

Lass `run` weg, um das Live-`entry` direkt abzuspielen. Sieh dir [den Replay-Vertrag](/docs/marketplace-game-development/replay-contract) dafür an, was das Artefakt exportieren muss.

## Der preferred-Block [#the-preferred-block]

Der optionale `preferred`-Block trägt Präsentations-Hinweise. Jeder Schlüssel ist beratend: der Host KANN ihn honorieren, und er überschreibt nie ein explizites Embed-Attribut.

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

Ein responsives Spiel, das standardmäßig seinen Container überspannen soll, kann `"full"` auf einer der Achsen deklarieren:

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

| Feld | Bedeutung |
|---|---|
| `width` / `height` | Ein Pixel-Footprint oder das literale `"full"`. Das Widget wendet es an, wenn das Embed `width` / `height` ungesetzt lässt (ein expliziter Embed-Wert, einschließlich `full`, gewinnt stattdessen). Ein Pixel-Wert dimensioniert den Iframe auf diese Anzahl; `"full"` streckt diese Achse, um das Eltern-Element zu füllen, derselbe Effekt, den ein Embed-`width="full"` hat. Weglassen, um auf den eingebauten Standard-Footprint des Widgets zurückzufallen. |
| `layout` | Die Hülle, die das Widget um das Spiel baut: `inline`, `modal` oder `fullscreen`. Nur genutzt, wenn das Embed `layout` ungesetzt lässt (seinen Standard `auto`). Auflösungsreihenfolge: das `layout`-Attribut des Embeds, dann dieses preferred-Layout, dann `inline`. |

Diese Hinweise werden nur für Spiele honoriert, die die Plattform serverseitig auflöst (Marketplace-Spiele, oder eine ohne Site-Key gegebene Spiel-id). Ein selbst gehostetes `game-src`-Bundle, das die Plattform vor dem Mount nicht lesen kann, ignoriert sowohl den Footprint als auch den Layout-Hinweis.

## Preset-Blöcke [#preset-blocks]

`locales`, `skins` und `configurations` deklarieren jeweils ein optionales `schema` (Pro-Schlüssel-Typen und Dokumentation) plus `presets` (die benannten Options-Banken). Das Widget löst die Wahl des Besuchers dagegen auf und reicht deinem Spiel das abgeflachte Ergebnis als [`ctx`](/docs/marketplace-game-development/game-sdk-reference). Der vollständige Feldtyp-Katalog ist die geteilte [Anpassungs-Schema-Referenz](/docs/references/customization-schema); dieselben Typen treiben das [Dashboard-Schema eines Custom-Spiels](/docs/custom-game-development/dashboard-schema).

Ein `skins.schema`-Feld kann ein `color`, ein Asset (`image` / `audio` / `video`) oder ein Skalar (`boolean`, `number`, `range`, `list`) sein, mit denselben Constraint-Formen wie `configurations` (`{ "type": "range", "min": 0, "max": 24 }`, `["dots","stripes"]` und so weiter). Skalare Skin-Werte lösen sich zu ihrem typisierten Wert in `ctx.skin` auf (eine `number` ist eine echte Zahl), genau wie ein Konfigurationswert; Farb- und Asset-Werte lösen sich zu Strings auf.

Das `_theme` eines Skin-Presets deklariert den Modus, in dem es funktioniert: `light`, `dark` oder `any` (es wegzulassen bedeutet `any`). Ein `light`- oder `dark`-Preset zeigt sich nur in diesem Modus; ein `any`-Preset liest sich auf beiden Hintergründen und ist für beide berechtigt. Es gibt einen Standard pro Modus. Ein als `_default: true` markiertes Preset ist der Standard für die Modi, für die es berechtigt ist, also deckt ein `any`-Standard beide ab; wenn mehrere berechtigte Presets als Standard für einen Modus geflaggt sind, gewinnt das erste in Deklarationsreihenfolge ihn. Liste ein modus-spezifisches Preset über einem `any`, um diesem Modus einen dedizierten Skin zu geben, während das `any`-Preset auf den anderen durchfällt.

## Die `.caputchin/`-Split-Dateien

Preset-Blöcke (besonders volle Locale-Sätze) machen `caputchin.json` lang. Verschieb jede Achse in ihre eigene Datei unter einem `.caputchin/`-Ordner, sodass das Manifest kurz bleibt:

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

Das Top-Level-Objekt jeder Datei **ist** dieser Achsen-Block (`{ schema?, presets }`). Alle drei sind optional. Vorrang ist Ganz-Achsen-Ersetzung, `caputchin.json` gewinnt: ist eine Achse sowohl inline als auch als Datei deklariert, wird der Inline-Block genutzt und die Datei ignoriert (das Veröffentlichen warnt, sodass du weißt, dass sie tot war). Halt jede Achse an genau einem Ort.

## Sammlungen [#collections]

Ein Repo kann mehrere Spiele ausliefern. Ein Sammlungs-Wrapper deklariert Kind-Pfade statt `entry` / `npm`:

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

Jeder Pfad zeigt auf ein Kind-Verzeichnis, das seine eigene `caputchin.json` hält. Kind-ids sind `owner/repo/<leaf-dir>`. Lass den `marketplace`-Block des Wrappers weg, um die Kinder ohne Sammlungs-Seite zu indexieren.

## Siehe auch

- [Ein Marketplace-Spiel bauen](/docs/marketplace-game-development/build-a-marketplace-game): das Bundle produzieren, auf das dieses Manifest zeigt.
- [Der Replay-Vertrag](/docs/marketplace-game-development/replay-contract): was das `run`-Artefakt exportieren muss.
- [Publish-Fehler-Referenz](/docs/marketplace-game-development/publish-failed-reference): jeder Manifest-Validierungsfehler und die genehmigte Lizenz-Liste.
- [Anpassungs-Schema-Referenz](/docs/references/customization-schema): die Feldtypen, die die Preset-Blöcke nutzen.
