Caputchin
Custom game development

Run your own game

A custom game is a game you build and host, used in the Caputchin widget instead of a marketplace game. Nobody else can install it, there is no GitHub topic and no publish step, and you keep the code. This section is the detailed, build-it-yourself guide to that path. (If you want to ship a game for anyone to embed, that is marketplace game development, a separate path.)

There are two ways to deliver a custom game, and they are genuinely different surfaces with different limits. Pick by what you need:

Manual mode: your own DOM, no gate

Manual mode is the lightweight option. You set trigger="manual" on <caputchin-game>, put your own markup inside it, and call the element's pass() / fail() methods from your own code when the visitor succeeds or fails. There is no iframe and no game SDK; the widget just gives you its layout shell and the verification plumbing around your markup.

The tradeoff: a manual-mode round cannot be server-replayed, so a manual-mode game cannot satisfy a game gate. It runs only on an ungated key (proof-of-work verification, with your interaction as UX), or game-only with no verification at all. Use it for a branded interaction, not for a security gate you need replayed.

Self-hosted iframe game: can gate

A self-hosted game is a real, sandboxed game: a JavaScript bundle built against the @caputchin/game-sdk package that runs in the widget's iframe, talks to the host over the SDK bridge, and reports a trace the server can re-run. You host the bundle yourself and point the widget at it with the game-src attribute.

Because the round produces a replayable trace, a self-hosted game can gate a site key, but only once you give Caputchin a replay artifact: a small headless build of your game logic that the server runs to re-derive the verdict. Until that artifact is uploaded and passes its self-check, the custom game shows Not replayable and cannot gate.

What the dashboard adds

A marketplace game ships a caputchin.json manifest that declares its customization fields. A custom game has no manifest, so you declare those fields on the dashboard instead: you register the custom game by an id you choose, define its field schema per axis (language, skin, configuration), and author presets against it. From there it resolves and applies exactly like a marketplace game, on the same plan tiers.

So the full custom-game surface is:

PieceWhereNeeded for
The game itselfYour code, your hostAlways
Deliverytrigger="manual" slot, or game-src iframeAlways
Field schema + presetsDashboard (you define the schema)Customizing language / skin / config
Replay artifactDashboard uploadGating verification (self-hosted only)

See also

On this page