---
type: tutorial
title: L'engine-kit
summary: Un kit de rédaction optionnel qui produit un run de rejeu conforme à partir d'un simple reducer, gérant pour toi le déterminisme, la boucle à pas fixe, l'encodage de trace, et une auto-vérification locale.
---

`@caputchin/engine-kit` est un kit de rédaction optionnel qui transforme un simple reducer de jeu en un [`run`](/docs/marketplace-game-development/replay-contract) conforme, gérant pour toi le déterminisme, la boucle à pas fixe, et l'encodage de trace. C'est une façon commode de produire cet artefact, pas une obligation : tu peux ignorer le kit entièrement et livrer un `run` nu que tu as écrit à la main. Tends la main vers lui quand tu préfères écrire une logique de jeu ordinaire et avoir le déterminisme, la boucle de rejeu et l'encodage de trace gérés pour toi.

Le kit réexporte toute la surface du [contrat de rejeu](/docs/marketplace-game-development/replay-contract), donc les utilisateurs du kit ont un seul site d'import.

```bash
npm install @caputchin/engine-kit
```

## L'idée : écris un reducer, obtiens un run

Le geste central du kit est de te laisser exprimer ton jeu comme un **reducer pur** : une fonction qui prend l'état actuel et l'entrée d'un tick et renvoie l'état suivant. À partir de ce reducer plus des primitives déterministes, l'adaptateur `toRun` du kit produit un `run(seed, config, trace)` qui se conforme au contrat par construction.

```js
import { defineEngine, toRun, cap } from "@caputchin/engine-kit";

const engine = defineEngine({
  setup(seed) {
    const rng = cap.rng(seed);          // deterministic, seeded RNG
    return { score: 0, targets: spawn(rng), rng };
  },
  tick(state, input) {
    // pure: same (state, input) always yields the same next state
    return applyInput(state, input);
  },
  result(state) {
    return { passed: state.score >= 3, score: state.score, durationMs: state.elapsed };
  },
});

export const run = toRun(engine);       // a conforming RunFn
```

## Primitives déterministes

Le kit te donne les deux choses qui cassent le plus souvent le déterminisme inter-runtime, toutes deux ensemencées et reproductibles :

- `cap.rng(seed)` (et `cap.rngFromState`) : un PRNG ensemençable. Utilise-le pour chaque choix aléatoire au lieu de `Math.random()`.
- `cap.math` : des transcendantales déterministes (`sin`, `cos`, ...) qui s'accordent entre runtimes, au lieu de celles de la plateforme `Math` qui peuvent ne pas le faire.

## Shims optionnels

- `applyShim()` : neutralise les globaux non déterministes (l'horloge murale, `Math.random`) pour qu'un appel accidentel échoue bruyamment en développement au lieu de diverger silencieusement au rejeu.
- `applyDomShim()` : un DOM headless minimal pour le chemin framework, pour qu'un reducer qui touche une petite surface DOM se rejoue quand même dans l'isolat sans DOM.

## Exécute-le en local avant de publier

Le harnais `replay` du kit passe une trace à travers ton moteur de la même façon que le serveur le fera, et `selfCheck` exécute une batterie de cas et rapporte tout non-déterminisme **avant** que tu publies :

```js
import { selfCheck } from "@caputchin/engine-kit";

const report = selfCheck(engine, { cases: myCases });
if (!report.ok) console.error(report.violations);
```

Un `selfCheck` local propre est le meilleur prédicteur que l'auto-vérification de publication du marketplace réussira (c'est le même standard de déterminisme). Le kit livre aussi une CLI pour exécuter ça depuis les scripts `package.json` ou la CI.

## Encodage de trace

`encodeTrace` / `decodeTrace` te donnent un format de trace compact et versionné pour que le flux d'entrées que ton jeu en direct émet soit exactement ce que ton `run` décode au rejeu. Les utiliser des deux côtés garde les deux au pas.

## Quand sauter le kit

Saute-le quand tu as déjà une logique déterministe (une simulation à virgule fixe, un module WASM compilé pour les flottants-spec) ou quand ton jeu est assez simple pour qu'écrire `run` à la main soit trivial. La plateforme ne sait ni ne se soucie jamais si le kit a produit ton `run` ; elle ne fait que charger et rejouer le contrat.

## Voir aussi

- [Le contrat de rejeu](/docs/marketplace-game-development/replay-contract) : le `run` / la graine / le verdict que ce kit produit.
- [Bâtir un jeu pour le marketplace](/docs/marketplace-game-development/build-a-marketplace-game) : le jeu dont ce kit peut adosser la logique.
- [Le manifeste caputchin.json](/docs/marketplace-game-development/the-caputchin-json-manifest#the-run-artifact) : livrer le `run` produit comme artefact.
