Caputchin
Desarrollo de juegos del marketplace

El manifiesto caputchin.json

caputchin.json en la raíz de tu repositorio es la fuente de verdad del autor y del indexador para un juego del marketplace. El indexador lo lee en el servidor para aprender la identidad del juego, dónde vive su bundle, qué presets ofrece, y cómo repetirlo. Nunca se lee en el navegador; el SDK no lo carga en tiempo de ejecución.

Esta página es la referencia de campos. Para el build, mira Construye un juego del marketplace; para publicar, mira Publica en el marketplace. Los tipos exactos se exportan del SDK como GameManifest (mira la referencia del SDK).

Un juego único mínimo

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

Campos de nivel superior

CampoObligatorioPropósito
terms_acceptedpara indexarDebe ser el literal true para confirmar que aceptas los Términos de Envío del Marketplace. Cualquier otro valor (o ausente) descarta el manifiesto del índice. Los manifiestos solo-autoalojados pueden omitirlo.
licensepara indexarUn identificador o expresión SPDX que cubra tu código y los assets empaquetados. Debe evaluar a un identificador aprobado (mira la referencia de errores de publicación).
marketplacepara indexarSu presencia es la señal de "indéxame". Ausente significa un juego autoalojado válido que el marketplace ignora. Mira El bloque marketplace.
npmcon entryCoordenada de paquete npm que el indexador resuelve a una URL de jsDelivr.
entrycon npmRuta relativa al repo del bundle construido. entry, npm, o ambos deben estar presentes para un juego ejecutable.
gamespara coleccionesRutas de sub-manifiesto para un envoltorio de colección. Mutuamente excluyente con entry / npm. Mira Colecciones.
runopcionalUn artefacto de repetición headless dedicado. Mira El artefacto run.
preferredopcionalPistas de presentación que el anfitrión PUEDE honrar. Mira El bloque preferred.
locales / skins / configurationsopcionalBloques de preset consumidos por el SDK en el iframe. Mira Bloques de preset.

No hay campo version: el indexador fija el bundle a una ref inmutable él mismo (la versión publicada de npm o el SHA de commit resuelto).

El bloque marketplace

CampoPropósito
nameTítulo de la tarjeta. Recae en el nombre del repo (único / envoltorio) o el nombre del leaf-dir (hijo de colección).
descriptionSubtítulo de la tarjeta y cuerpo de la página de detalle.
previewRuta de imagen (relativa a la raíz del repo) o URL absoluta. En torno a 600x315, sujeto centrado.
versionCadena de versión solo de visualización para la página de detalle. Opcional.
supportFlags de compatibilidad declarados por el autor (responsive, touch, accessible, audio, ...), nunca verificados por la plataforma; expuestos como filtros e iconos de tarjeta.
author{ name?, url?, email? } opcional. name / url se renderizan como una firma de autor en la página de detalle; email nunca se muestra y es el opt-in para los correos de fallo de publicación. Los tres subcampos son independientes.

El bloque es totalmente opcional. Omite name / url y la página de detalle simplemente no muestra firma de autor (el owner de GitHub mostrado en otro sitio de la página es una identidad separada y siempre presente, no un fallback para esta firma). Omite email y no recibes notificaciones de fallo de publicación. Fija solo los subcampos que quieras.

Punteros de distribución

El indexador fija el bundle de cada juego a una ref inmutable para que el hash de integridad guardado siga siendo válido, y vuelve a resolver en cada ejecución (cron diario más "Publicar o actualizar" manual):

  • entry + npm resuelven a cdn.jsdelivr.net/npm/<npm>@<resolved-version>/<entry>.
  • solo entry resuelve a cdn.jsdelivr.net/gh/<owner>/<repo>@<commit-sha>/<entry>.
  • solo npm resuelve al entry por defecto del paquete en la versión fijada.

No hay fijación de versión del lado del usuario; para congelar un build, un usuario lo autoaloja vía el game-src del widget (juego a medida).

El artefacto run

Por defecto la autocomprobación de repetición corre tu bundle entry en vivo. Cuando tu juego es grande o está basado en framework o WASM, publica en su lugar un artefacto run headless ligero y dedicado:

{
  "run": {
    "entry": "dist/run.js",
    "modules": [
      { "name": "sim.wasm", "type": "wasm", "path": "dist/sim.wasm" }
    ]
  }
}
CampoSignificado
run.entryRuta relativa al repo del bundle run headless (el export run del contrato de repetición).
run.modulesArray opcional de entradas de módulo que el run importa por name.

Restricciones que el indexador impone

Estas se validan en tiempo de indexación; una violación hace fallar la publicación con un manifest-error (mira la referencia de errores de publicación).

run.entry:

  • Debe ser JavaScript: el basename debe coincidir con [a-zA-Z0-9_-]+.js. El artefacto run es siempre JS (WASM se publica como un módulo, abajo).
  • Debe ser una ruta limpia relativa al repo: sin barra inicial, sin recorrido .., sin espacios en blanco, sin ? / #, sin prefijo scheme://.

Cada entrada run.modules[] es { name, type, path }:

  • name debe coincidir con [a-zA-Z0-9_-]+.(wasm|js), un módulo es o JS o WASM, nada más. El name es el especificador de import que usa el entry.
  • type debe concordar con la extensión: wasm para un nombre .wasm, js para un nombre .js.
  • name no debe ser un nombre reservado (entry.js, artifact.js) que el anfitrión de repetición usa internamente.
  • name debe ser único dentro del array (sin duplicados).
  • path debe ser una ruta limpia relativa al repo (mismas reglas que run.entry).
  • Como mucho 16 módulos.

Omite run para repetir el entry en vivo directamente. Mira el contrato de repetición para lo que el artefacto debe exportar.

El bloque preferred

El bloque preferred opcional lleva pistas de presentación. Cada clave es consultiva: el anfitrión PUEDE honrarla, y nunca anula un atributo de incrustación explícito.

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

Un juego responsive que debería abarcar su contenedor por defecto puede declarar "full" en cualquier eje:

{
  "preferred": { "width": "full", "height": 480 }
}
CampoSignificado
width / heightUna huella en píxeles, o el literal "full". El widget la aplica cuando la incrustación deja width / height sin fijar (un valor de incrustación explícito, incluido full, gana en su lugar). Un valor en píxeles dimensiona el iframe a esa cantidad; "full" estira ese eje para llenar el padre, el mismo efecto que tiene un width="full" de incrustación. Omítelo para recaer en la huella por defecto integrada del widget.
layoutEl shell que el widget construye alrededor del juego: inline, modal, o fullscreen. Usado solo cuando la incrustación deja layout sin fijar (su auto por defecto). Orden de resolución: el atributo layout de la incrustación, luego este layout preferido, luego inline.

Estas pistas se honran solo para juegos que la plataforma resuelve en el servidor (juegos del marketplace, o un id de juego dado sin una clave de sitio). Un bundle game-src autoalojado que la plataforma no puede leer antes del montaje ignora tanto la huella como la pista de layout.

Bloques de preset

locales, skins y configurations cada uno declara un schema opcional (tipos y documentación por clave) más presets (los bancos de opciones con nombre). El widget resuelve la elección del visitante contra estos y le entrega a tu juego el resultado aplanado como ctx. El catálogo completo de tipos de campo es la referencia del esquema de personalización compartida; los mismos tipos impulsan el esquema del dashboard de un juego a medida.

Un campo skins.schema puede ser un color, un asset (image / audio / video), o un escalar (boolean, number, range, list) usando las mismas formas de restricción que configurations ({ "type": "range", "min": 0, "max": 24 }, ["dots","stripes"], etcétera). Los valores escalares de skin resuelven a su valor tipado en ctx.skin (un number es un número real), exactamente como un valor de configuración; los valores de color y asset resuelven a cadenas.

El _theme de un preset de skin declara el modo en el que funciona: light, dark, o any (omitirlo significa any). Un preset light o dark aparece solo en ese modo; un preset any se lee sobre cualquier fondo y es elegible para ambos. Hay un default por modo. Un preset marcado _default: true es el default para los modos para los que es elegible, así que un default any cubre ambos; cuando varios presets elegibles están marcados como default para un modo, el primero en orden de declaración lo gana. Lista un preset específico de modo por encima de uno any para darle a ese modo un skin dedicado mientras el preset any recae al otro.

Los archivos divididos .caputchin/

Los bloques de preset (especialmente los conjuntos completos de locale) hacen caputchin.json largo. Mueve cualquier eje a su propio archivo bajo una carpeta .caputchin/, dejando el manifiesto corto:

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

El objeto de nivel superior de cada archivo es ese bloque de eje ({ schema?, presets }). Los tres son opcionales. La precedencia es reemplazo de eje entero, caputchin.json gana: si un eje se declara tanto inline como en archivo, se usa el bloque inline y el archivo se ignora (la publicación avisa para que sepas que estaba muerto). Mantén cada eje en exactamente un sitio.

Colecciones

Un repo puede publicar varios juegos. Un envoltorio de colección declara rutas de hijos en lugar de entry / npm:

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

Cada ruta apunta a un directorio hijo que tiene su propio caputchin.json. Los ids de los hijos son owner/repo/<leaf-dir>. Omite el bloque marketplace del envoltorio para indexar los hijos sin una página de colección.

Véase también

En esta página