Référence du SDK de jeu
@caputchin/game-sdk est le contrat contre lequel un auteur de jeu écrit : un assistant register, un Bridge push-only, le GameContext par manche, et les types TypeScript pour les blocs de préréglages du manifeste. Il est publié séparément du widget destiné à l'utilisateur pour que les jeux n'embarquent jamais transitivement le runtime du widget. Les jeux maison utilisent cette même API publique ; il n'y a pas de contrat privé.
Pour une construction guidée, vois Bâtir un jeu pour le marketplace. Pour le manifeste qui déclare les préréglages que ce SDK remonte, vois Le manifeste caputchin.json.
register(factory)
L'unique point d'entrée d'enregistrement. Passe ta fabrique de jeu ; tu ne passes pas le manifeste (le serveur lit caputchin.json au moment de l'indexation et livre les préréglages résolus comme contexte de la fabrique). Enregistrer deux fois journalise un avertissement console et la dernière écriture l'emporte ; il n'y a pas d'application par la plateforme.
register(factory: GameFactory): voidLa fabrique de jeu
type GameFactory = (
container: HTMLElement,
bridge: Bridge,
ctx?: GameContext,
) => (() => void) | void| Paramètre | Signification |
|---|---|
container | Un élément dans l'iframe en bac à sable du jeu. Rends ici. Le style est naturellement délimité, l'iframe est son propre document. |
bridge | Le canal push-only vers l'hôte (vois Le pont). Le jeu émet vers le haut ; il ne s'abonne pas. La fabrique appelée est le signal de départ. |
ctx | Le contexte par manche (graine plus préréglages résolus). Optionnel dans le type parce que le widget peut exécuter un jeu hors d'une session vérifiée. |
| return | Une fonction de nettoyage optionnelle que le widget appelle s'il démonte ton jeu. |
Le pont
Le pont est push-only : le jeu rapporte des événements à l'hôte et n'écoute jamais. Ses membres :
| Membre | Forme | Effet |
|---|---|---|
pass | pass(result: { trace: string }): void | Signale que la manche a été réussie, remettant à l'hôte le trace opaque. Le serveur réexécute le run du jeu sous la graine émise pour calculer le verdict faisant autorité, donc le jeu ne rapporte pas de score ici. Le premier appel libère la vérification retenue et verrouille le token ; les appels ultérieurs sont ignorés. |
error | error(err: { code: string; message?: string }): void | Le jeu lui-même a échoué (chargement de ressource, exception interne). Fait surgir un événement error vers l'utilisateur. Distinct d'un joueur qui perd, signalé en n'appelant rien. |
setSize | setSize(width: number, height: number): void | Redimensionne explicitement l'iframe pour ajuster le contenu. Appelle après le premier rendu ; le widget mesure aussi automatiquement le premier enfant du jeu, donc la plupart des jeux n'en ont jamais besoin. |
layout | readonly layout: 'inline' | 'modal' | 'fullscreen' | null | La présentation résolue sous laquelle le jeu tourne, ou null quand inconnue. |
Il n'y a délibérément pas de complete, pas d'écouteur start, pas de méthode unmount (renvoie plutôt une fonction de nettoyage), et pas de signal d'échec au-delà du silence.
Le contexte
interface GameContext {
seed: Seed | null
locale: ResolvedLocale | null
skin: ResolvedSkin | null
config: ResolvedConfig | null
}| Champ | Signification |
|---|---|
seed | La graine de rejeu par manche (un Seed du contrat de rejeu). Ensemence tout l'aléatoire du jeu à partir d'elle. null quand le jeu tourne hors d'une session vérifiée. |
locale | L'objet de langue résolu : _lang (BCP-47), _direction, plus tes clés de texte aplaties. null si ton manifeste ne livre aucun bloc locales. |
skin | Le skin résolu : _theme plus tes clés de couleur/ressource aplaties, les URL de ressources déjà absolues. _theme est toujours le mode concret pour lequel le skin a été résolu, light ou dark (jamais any), donc un préréglage agnostique au thème rapporte le mode réel du visiteur. null s'il n'y a pas de bloc skins. |
config | La configuration résolue : tes scalaires typés aplatis. null s'il n'y a pas de bloc configurations. |
Chacun est null quand le bloc de manifeste correspondant est absent, donc fournis toujours un repli intégré.
Types de préréglages
Le SDK exporte des types TypeScript pour rédiger caputchin.json (et les fichiers de découpe .caputchin/) avec une vérification de type. Ceux-ci reflètent les blocs du manifeste :
| Type | Décrit |
|---|---|
GameManifest | Tout le caputchin.json. Source de vérité auteur + indexeur ; jamais lu dans le navigateur. |
LocalePreset / ResolvedLocale | Un préréglage de locale déclaré / l'objet résolu que le jeu reçoit. |
SkinPreset / ResolvedSkin / SkinSchemaEntry / SkinValueType | Les préréglages de skin, le skin résolu, et le schéma de type par clé. |
ConfigPreset / ResolvedConfig / ConfigSchemaEntry / ConfigValueType | Les préréglages de configuration, la config résolue, et le schéma de type par clé. |
LocalesFile / SkinsFile / ConfigurationsFile | L'objet de premier niveau de chaque fichier de découpe .caputchin/<axis>.json. |
MarketplaceMetadata / PreferredPresentation | Le bloc marketplace et l'indice d'empreinte preferred. |
Rédige un fichier de découpe avec un import satisfies pour que le compilateur le vérifie :
import type { LocalesFile } from "@caputchin/game-sdk";
export default { schema: { /* ... */ }, presets: { /* ... */ } } satisfies LocalesFile;Ce qui est intentionnellement absent
- Aucun
sessionIdni identifiant de plateforme n'atteint le jeu. - Pas de hooks de cycle de vie
start/pause/resume; l'appel de la fabrique est le départ. - Pas de
maxScoreni de plage de score de plateforme ; le score du verdict est ce que tonrunrenvoie.
Le contrat est intentionnellement minuscule pour rester stable à travers des années de croissance du catalogue.
Voir aussi
- Bâtir un jeu pour le marketplace : le tutoriel qui utilise cette surface.
- Le contrat de rejeu : le
Seed, la trace et le verdict auxquels le pont et le contexte se réfèrent. - Le manifeste caputchin.json : déclarer les préréglages que le contexte résout.