---
type: reference
title: Referencia del game SDK
summary: La superficie completa de @caputchin/game-sdk contra la que escribe un autor de juegos, la función register, el bridge de solo empuje, el contexto por ronda, y los tipos de preset.
---

`@caputchin/game-sdk` es el contrato contra el que escribe un autor de juegos: un helper `register`, un `Bridge` de solo empuje, el `GameContext` por ronda, y los tipos de TypeScript para los bloques de preset del manifiesto. Se publica por separado del widget de cara al usuario para que los juegos nunca empaqueten transitivamente el runtime del widget. Los juegos de primera parte usan esta misma API pública; no hay contrato privado.

Para un build guiado, mira [Construye un juego del marketplace](/docs/marketplace-game-development/build-a-marketplace-game). Para el manifiesto que declara los presets que este SDK expone, mira [El manifiesto caputchin.json](/docs/marketplace-game-development/the-caputchin-json-manifest).

## `register(factory)`

El único punto de entrada de registro. Pasa tu factory de juego; **no** pasas el manifiesto (el servidor lee `caputchin.json` en tiempo de indexación y envía los presets resueltos como el contexto de la factory). Registrar dos veces emite un warning en consola y la última escritura gana; no hay imposición de la plataforma.

```ts
register(factory: GameFactory): void
```

## La factory de juego

```ts
type GameFactory = (
  container: HTMLElement,
  bridge: Bridge,
  ctx?: GameContext,
) => (() => void) | void
```

| Parámetro | Significado |
|---|---|
| `container` | Un elemento dentro del iframe en sandbox del juego. Renderiza aquí. El estilo queda naturalmente acotado, el iframe es su propio documento. |
| `bridge` | El canal de solo empuje hacia el anfitrión (mira [El bridge](#the-bridge)). El juego emite hacia arriba; no se suscribe. Que la factory sea llamada es la señal de inicio. |
| `ctx` | El [contexto](#the-context) por ronda (semilla más presets resueltos). Opcional en el tipo porque el widget puede correr un juego fuera de una sesión verificada. |
| return | Una función de limpieza opcional que el widget llama si desmonta tu juego. |

## El bridge [#the-bridge]

El bridge es de solo empuje: el juego reporta eventos al anfitrión y nunca escucha. Sus miembros:

| Miembro | Forma | Efecto |
|---|---|---|
| `pass` | `pass(result: { trace: string }): void` | Señala que la ronda se **aprobó**, entregándole al anfitrión la `trace` opaca. El servidor vuelve a correr el [`run`](/docs/marketplace-game-development/replay-contract) del juego bajo la semilla emitida para computar el veredicto autoritativo, así que el juego **no** reporta una puntuación aquí. La primera llamada libera la verificación retenida y bloquea el token; las llamadas posteriores se ignoran. |
| `error` | `error(err: { code: string; message?: string }): void` | El propio juego falló (carga de asset, excepción interna). Hace aflorar un evento `error` al usuario. Distinto de que un jugador pierda, que se señala llamando a nada. |
| `setSize` | `setSize(width: number, height: number): void` | Redimensiona explícitamente el iframe para ajustar el contenido. Llámalo tras el primer pintado; el widget también automide el primer hijo del juego, así que la mayoría de los juegos nunca lo necesitan. |
| `layout` | `readonly layout: 'inline' \| 'modal' \| 'fullscreen' \| null` | La presentación resuelta bajo la que corre el juego, o `null` cuando se desconoce. |

Deliberadamente no hay `complete`, ni listener `start`, ni método `unmount` (devuelve una función de limpieza en su lugar), ni señal de fallo más allá del silencio.

## El contexto [#the-context]

```ts
interface GameContext {
  seed:   Seed          | null
  locale: ResolvedLocale | null
  skin:   ResolvedSkin   | null
  config: ResolvedConfig | null
}
```

| Campo | Significado |
|---|---|
| `seed` | La semilla de repetición por ronda (un [`Seed`](/docs/marketplace-game-development/replay-contract) del contrato de repetición). Siembra toda la aleatoriedad del juego de ella. `null` cuando el juego corre fuera de una sesión verificada. |
| `locale` | El objeto de idioma resuelto: `_lang` (BCP-47), `_direction`, más tus claves de texto aplanadas. `null` si tu manifiesto no publica ningún bloque `locales`. |
| `skin` | El skin resuelto: `_theme` más tus claves de color/asset aplanadas, las URLs de asset ya absolutas. `_theme` es siempre el modo concreto para el que se resolvió el skin, `light` o `dark` (nunca `any`), así que un preset agnóstico al tema reporta el modo real del visitante. `null` si no hay bloque `skins`. |
| `config` | La configuración resuelta: tus escalares tipados aplanados. `null` si no hay bloque `configurations`. |

Cada uno es `null` cuando el bloque correspondiente del manifiesto está ausente, así que provee siempre un fallback integrado.

## Tipos de preset

El SDK exporta tipos de TypeScript para crear `caputchin.json` (y los archivos divididos `.caputchin/`) con comprobación de tipos. Estos reflejan los bloques del [manifiesto](/docs/marketplace-game-development/the-caputchin-json-manifest):

| Tipo | Describe |
|---|---|
| `GameManifest` | El `caputchin.json` entero. Fuente de verdad del autor + indexador; nunca se lee en el navegador. |
| `LocalePreset` / `ResolvedLocale` | Un preset de locale declarado / el objeto resuelto que el juego recibe. |
| `SkinPreset` / `ResolvedSkin` / `SkinSchemaEntry` / `SkinValueType` | Presets de skin, el skin resuelto, y el esquema de tipo por clave. |
| `ConfigPreset` / `ResolvedConfig` / `ConfigSchemaEntry` / `ConfigValueType` | Presets de configuración, la config resuelta, y el esquema de tipo por clave. |
| `LocalesFile` / `SkinsFile` / `ConfigurationsFile` | El objeto de nivel superior de cada archivo dividido `.caputchin/<axis>.json`. |
| `MarketplaceMetadata` / `PreferredPresentation` | El bloque `marketplace` y la pista de huella `preferred`. |

Crea un archivo dividido con un import `satisfies` para que el compilador lo compruebe:

```ts
import type { LocalesFile } from "@caputchin/game-sdk";
export default { schema: { /* ... */ }, presets: { /* ... */ } } satisfies LocalesFile;
```

## Qué está ausente a propósito

- Ningún `sessionId` ni identificadores de plataforma llegan al juego.
- Ningún gancho de ciclo de vida `start` / `pause` / `resume`; la llamada a la factory es el inicio.
- Ningún `maxScore` ni rango de puntuación de plataforma; la puntuación del veredicto es lo que tu `run` devuelva.

El contrato es deliberadamente diminuto para que se mantenga estable a través de años de crecimiento del catálogo.

## Véase también

- [Construye un juego del marketplace](/docs/marketplace-game-development/build-a-marketplace-game): el tutorial que usa esta superficie.
- [El contrato de repetición](/docs/marketplace-game-development/replay-contract): el `Seed`, la traza, y el veredicto a los que se refieren el bridge y el contexto.
- [El manifiesto caputchin.json](/docs/marketplace-game-development/the-caputchin-json-manifest): declarar los presets que el contexto resuelve.
