O manifesto caputchin.json
O caputchin.json na raiz do seu repositório é a fonte de verdade do autor e do indexador para um jogo de marketplace. O indexador o lê no servidor para conhecer a identidade do jogo, onde seu bundle vive, quais presets ele oferece, e como reexecutá-lo. Ele nunca é lido no navegador; o SDK não o carrega em tempo de execução.
Esta página é a referência de campos. Para a construção, veja Construir um jogo de marketplace; para a publicação, veja Publicar no marketplace. Os tipos exatos são exportados do SDK como GameManifest (veja a referência do SDK).
Um jogo ú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 nível superior
| Campo | Obrigatório | Propósito |
|---|---|---|
terms_accepted | para indexar | Precisa ser o literal true para confirmar que você aceita os Termos de Submissão do Marketplace. Qualquer outro valor (ou ausente) tira o manifesto do índice. Manifestos só-auto-hospedados podem omiti-lo. |
license | para indexar | Um identificador ou expressão SPDX cobrindo seu código e ativos empacotados. Precisa avaliar para um identificador aprovado (veja a referência de erros de publicação). |
marketplace | para indexar | A presença é o sinal de "me indexe". Ausente significa um jogo auto-hospedado válido que o marketplace ignora. Veja O bloco marketplace. |
npm | com entry | A coordenada de pacote npm que o indexador resolve para uma URL jsDelivr. |
entry | com npm | Caminho relativo ao repositório para o bundle construído. entry, npm, ou ambos precisam estar presentes para um jogo executável. |
games | para coleções | Caminhos de submanifesto para um wrapper de coleção. Mutuamente exclusivo com entry / npm. Veja Coleções. |
run | opcional | Um artefato de replay headless dedicado. Veja O artefato run. |
preferred | opcional | Dicas de apresentação que o anfitrião PODE honrar. Veja O bloco preferred. |
locales / skins / configurations | opcional | Blocos de preset consumidos pelo SDK no iframe. Veja Blocos de preset. |
Não há campo version: o indexador fixa o bundle em uma ref imutável ele mesmo (a versão npm publicada ou o SHA de commit resolvido).
O bloco marketplace
| Campo | Propósito |
|---|---|
name | Título do card. Recai para o nome do repositório (único / wrapper) ou o nome do diretório folha (filho de coleção). |
description | Subtítulo do card e corpo da página de detalhe. |
preview | Caminho de imagem (relativo à raiz do repositório) ou URL absoluta. Cerca de 600x315, com o sujeito centralizado. |
version | String de versão só de exibição para a página de detalhe. Opcional. |
support | Flags de compatibilidade declaradas pelo autor (responsive, touch, accessible, audio, ...), nunca verificadas pela plataforma; expostas como filtros e ícones de card. |
author | { name?, url?, email? } opcional. name / url renderizam como uma assinatura de autor na página de detalhe; email nunca é mostrado e é a opção de adesão para os e-mails de falha de publicação. Os três subcampos são independentes. |
O bloco é totalmente opcional. Omita name / url e a página de detalhe simplesmente não mostra assinatura de autor (o dono do GitHub mostrado em outro lugar da página é uma identidade separada, sempre presente, não um fallback para esta assinatura). Omita email e você não recebe notificações de falha de publicação. Defina só os subcampos que quiser.
Ponteiros de distribuição
O indexador fixa o bundle de cada jogo em uma ref imutável para que o hash de integridade armazenado continue válido, e re-resolve a cada execução (cron diário mais "Publicar ou atualizar" manual):
entry+npmresolvem paracdn.jsdelivr.net/npm/<npm>@<resolved-version>/<entry>.entrysozinho resolve paracdn.jsdelivr.net/gh/<owner>/<repo>@<commit-sha>/<entry>.npmsozinho resolve para a entrada padrão do pacote na versão fixada.
Não há fixação de versão do lado do usuário; para congelar uma build, um usuário a auto-hospeda pelo game-src do widget (jogo personalizado).
O artefato run
Por padrão a autoverificação de replay roda seu bundle entry ativo. Quando seu jogo é grande ou baseado em framework ou WASM, envie um artefato run headless enxuto e dedicado em vez disso:
{
"run": {
"entry": "dist/run.js",
"modules": [
{ "name": "sim.wasm", "type": "wasm", "path": "dist/sim.wasm" }
]
}
}| Campo | Significado |
|---|---|
run.entry | Caminho relativo ao repositório para o bundle run headless (o export run do contrato de replay). |
run.modules | Array opcional de entradas de módulo que o run importa por name. |
Restrições que o indexador impõe
Estas são validadas no momento da indexação; uma violação falha a publicação com um manifest-error (veja a referência de erros de publicação).
run.entry:
- Precisa ser JavaScript: o basename precisa casar com
[a-zA-Z0-9_-]+.js. O artefato run é sempre JS (o WASM é enviado como um módulo, abaixo). - Precisa ser um caminho limpo relativo ao repositório: sem barra inicial, sem travessia
.., sem espaço em branco, sem?/#, sem prefixoscheme://.
Cada entrada run.modules[] é { name, type, path }:
nameprecisa casar com[a-zA-Z0-9_-]+.(wasm|js), um módulo é ou JS ou WASM, nada mais. Onameé o especificador de import que a entrada usa.typeprecisa concordar com a extensão:wasmpara um nome.wasm,jspara um nome.js.namenão pode ser um nome reservado (entry.js,artifact.js) que o anfitrião de replay usa internamente.nameprecisa ser único dentro do array (sem duplicatas).pathprecisa ser um caminho limpo relativo ao repositório (mesmas regras derun.entry).- No máximo 16 módulos.
Omita run para reexecutar o entry ativo diretamente. Veja o contrato de replay para o que o artefato precisa exportar.
O bloco preferred
O bloco preferred opcional carrega dicas de apresentação. Toda chave é consultiva: o anfitrião PODE honrá-la, e ela nunca sobrescreve um atributo de embed explícito.
{
"preferred": { "width": 360, "height": 480, "layout": "modal" }
}Um jogo responsivo que deve ocupar seu contêiner por padrão pode declarar "full" em qualquer eixo:
{
"preferred": { "width": "full", "height": 480 }
}| Campo | Significado |
|---|---|
width / height | Uma pegada em pixels, ou o literal "full". O widget a aplica quando o embed deixa width / height sem definir (um valor de embed explícito, inclusive full, vence). Um valor em pixels dimensiona o iframe para essa contagem; "full" estica esse eixo para preencher o pai, o mesmo efeito que um width="full" de embed tem. Omita para recair na pegada padrão embutida do widget. |
layout | O shell que o widget constrói ao redor do jogo: inline, modal ou fullscreen. Usado só quando o embed deixa layout sem definir (seu padrão auto). Ordem de resolução: o atributo layout do embed, depois este layout preferred, depois inline. |
Estas dicas são honradas só para jogos que a plataforma resolve no servidor (jogos de marketplace, ou um id de jogo dado sem uma chave de site). Um bundle game-src auto-hospedado que a plataforma não consegue ler antes da montagem ignora tanto a pegada quanto a dica de layout.
Blocos de preset
locales, skins e configurations cada um declara um schema opcional (tipos por chave e documentação) mais presets (os bancos de opções nomeados). O widget resolve a escolha do visitante contra estes e entrega ao seu jogo o resultado achatado como ctx. O catálogo completo de tipos de campo é a referência de esquema de personalização compartilhada; os mesmos tipos alimentam o esquema do painel de um jogo personalizado.
Um campo skins.schema pode ser um color, um ativo (image / audio / video), ou um escalar (boolean, number, range, list) usando as mesmas formas de restrição que configurations ({ "type": "range", "min": 0, "max": 24 }, ["dots","stripes"], e assim por diante). Valores escalares de skin resolvem para seu valor tipado em ctx.skin (um number é um número de verdade), exatamente como um valor de configuração; valores de cor e ativo resolvem para strings.
O _theme de um preset de skin declara o modo em que funciona: light, dark, ou any (omiti-lo significa any). Um preset light ou dark aparece só naquele modo; um preset any lê em qualquer fundo e é elegível para os dois. Há um padrão por modo. Um preset marcado _default: true é o padrão para qualquer modo para o qual é elegível, então um padrão any cobre os dois; quando vários presets elegíveis são marcados como padrão para um modo, o primeiro na ordem de declaração o vence. Liste um preset específico de modo acima de um any para dar a esse modo um skin dedicado enquanto o preset any cai para o outro.
Os arquivos divididos .caputchin/
Blocos de preset (especialmente conjuntos completos de idioma) deixam o caputchin.json longo. Mova qualquer eixo para o seu próprio arquivo sob uma pasta .caputchin/, deixando o manifesto curto:
caputchin.json
.caputchin/locales.json
.caputchin/skins.json
.caputchin/configurations.jsonO objeto de nível superior de cada arquivo é aquele bloco de eixo ({ schema?, presets }). Os três são opcionais. A precedência é substituição de eixo inteiro, caputchin.json vence: se um eixo é declarado tanto inline quanto como arquivo, o bloco inline é usado e o arquivo é ignorado (a publicação avisa para você saber que ele ficou morto). Mantenha cada eixo em exatamente um lugar.
Coleções
Um repositório pode enviar vários jogos. Um wrapper de coleção declara caminhos de filho em vez de entry / npm:
{
"marketplace": { "name": "Caputchin Core Pack", "description": "The official pack." },
"games": ["./packages/leaf-memory", "./packages/dino-runner"]
}Cada caminho aponta para um diretório filho que tem seu próprio caputchin.json. Os ids dos filhos são owner/repo/<leaf-dir>. Omita o bloco marketplace do wrapper para indexar os filhos sem uma página de coleção.
Veja também
- Construir um jogo de marketplace: produzir o bundle para o qual este manifesto aponta.
- O contrato de replay: o que o artefato
runprecisa exportar. - Referência de erros de publicação: cada erro de validação de manifesto e a lista de licenças aprovadas.
- Referência de esquema de personalização: os tipos de campo que os blocos de preset usam.