Make a custom game gateable
A self-hosted game runs and verifies as soon as you point game-src at it. But to use it as a game gate, where a visitor must clear it to pass, Caputchin has to be able to re-derive the result itself, not trust the browser. That is what the replay artifact is for. By the end of this tutorial your custom game will be gate-eligible.
This is the determinism payoff: because your game records a trace and derives everything from the seed, the server can run a headless copy of your logic against the same seed and trace and reach the same verdict independently.
What the replay artifact is
The artifact is a small, self-contained JavaScript bundle of just your game logic, with no rendering, no DOM, and no network. The server loads it into an isolated sandbox and runs it to produce a verdict from (seed, trace). It is not your playable game; it is the headless judge of your playable game.
Two properties are required:
- Self-contained. It cannot import anything the isolate can't resolve; bundle everything in. The upload is capped at 2 MB, which is far above a typical logic bundle.
- Deterministic and in agreement with the live game. Given the same seed and the trace your live game emitted, it must reach the same verdict the live game claimed. If they disagree, real players get false rejections.
1. Register the custom game
If you have not already, register the game on the dashboard so it has an id and a place to hold the artifact. On a site key's (or the troop's) Games page, use the Custom game input in the Add a game panel: enter your id and click Define. See custom games for this step and the schema you define.
2. Upload the artifact
On the registered game's Settings tab, upload the replay bundle. It is sent as a single file; Caputchin content-hashes it (re-uploading the same bytes is a no-op) and immediately runs a self-check.
3. The self-check
The self-check runs your uploaded artifact in the replay isolate against a synthetic seed (and your committed trace sample, if you provide one) and records whether it produced a clean verdict:
- Passes → the install becomes gate-eligible. The Not replayable badge clears, and you can now turn on require a game with this game in the pool.
- Fails → the artifact is still stored (so you can inspect the error), but the install stays non-gate-eligible. Fix the logic and re-upload.
A failed self-check is the system telling you the headless judge does not agree with itself or could not run; it is exactly the disagreement that would have caused false rejections in production, caught before any visitor hits it.
4. Turn on the gate
Once the self-check passes, the game is in the key's gate pool. Turn on Require a game on the key's Security page (or the troop's force-game ceiling), and Caputchin will serve your custom game, take the player's trace, and re-run your artifact server-side to decide each verification.
Keeping the two in sync
The live game (loaded via game-src) and the replay artifact are two builds of the same logic. When you change anything that affects the outcome, rebuild and re-upload the artifact so the two still agree. If they drift, the self-check or production replay will start rejecting real wins. Building both from one shared logic module is the reliable way to keep them identical.
See also
- Build a self-hosted game: producing the trace this artifact replays.
- Games and the game gate: turning the gate on and the replayability requirement.
- Custom games: registering and the Not-replayable badge.
- Dashboard schema reference: the fields the game reads from its factory context.