---
type: tutorial
title: Das engine-kit
summary: Ein optionales Verfassungs-Kit, das ein konformes Replay-run aus einem schlichten Reducer produziert und Determinismus, die Fixed-Step-Schleife, Trace-Kodierung und eine lokale Selbstprüfung für dich handhabt.
---

`@caputchin/engine-kit` ist ein optionales Verfassungs-Kit, das einen schlichten Spiel-Reducer in ein konformes [`run`](/docs/marketplace-game-development/replay-contract) verwandelt und Determinismus, die Fixed-Step-Schleife und Trace-Kodierung für dich handhabt. Es ist ein bequemer Weg, dieses Artefakt zu produzieren, keine Pflicht: du kannst das Kit ganz ignorieren und ein nacktes `run` ausliefern, das du von Hand geschrieben hast. Greif danach, wenn du lieber gewöhnliche Spiel-Logik schreibst und Determinismus, die Replay-Schleife und Trace-Kodierung für dich gehandhabt haben willst.

Das Kit re-exportiert die ganze [Replay-Vertrag](/docs/marketplace-game-development/replay-contract)-Fläche, sodass Kit-Nutzer eine einzige Import-Stelle haben.

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

## Die Idee: schreib einen Reducer, bekomm ein run

Der Kern-Zug des Kits ist, dich dein Spiel als **reinen Reducer** ausdrücken zu lassen: eine Funktion, die den aktuellen Zustand und die Eingabe eines Ticks nimmt und den nächsten Zustand zurückgibt. Aus diesem Reducer plus deterministischen Primitiven produziert der `toRun`-Adapter des Kits ein `run(seed, config, trace)`, das per Konstruktion dem Vertrag entspricht.

```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
```

## Deterministische Primitive

Das Kit gibt dir die zwei Dinge, die am häufigsten den Cross-Runtime-Determinismus brechen, beide geseedet und reproduzierbar:

- `cap.rng(seed)` (und `cap.rngFromState`), ein seedbarer PRNG. Nutz ihn für jede Zufallswahl statt `Math.random()`.
- `cap.math`, deterministische Transzendente (`sin`, `cos`, ...), die über Laufzeiten übereinstimmen, statt der Plattform-`Math`-Funktionen, die es eventuell nicht tun.

## Optionale Shims

- `applyShim()`, neutralisiert die nicht-deterministischen Globals (die Wall-Clock, `Math.random`), sodass ein versehentlicher Aufruf in der Entwicklung laut fehlschlägt, statt beim Replay still zu divergieren.
- `applyDomShim()`, ein minimales Headless-DOM für den Framework-Weg, sodass ein Reducer, der eine winzige DOM-Fläche berührt, trotzdem im Kein-DOM-Isolate abspielt.

## Lokal laufen lassen vor dem Veröffentlichen

Die `replay`-Harness des Kits lässt einen Trace durch deine Engine laufen, genauso wie der Server es tun wird, und `selfCheck` lässt eine Batterie von Fällen laufen und meldet jede Nicht-Determiniertheit **bevor** du veröffentlichst:

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

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

Ein sauberer lokaler `selfCheck` ist der beste Prädiktor, dass die Publish-Selbstprüfung des Marketplace bestehen wird (es ist derselbe Determinismus-Standard). Das Kit liefert auch eine CLI, um dies aus `package.json`-Skripten oder CI zu laufen.

## Trace-Kodierung

`encodeTrace` / `decodeTrace` geben dir ein kompaktes, versioniertes Trace-Format, sodass der Eingabe-Stream, den dein Live-Spiel emittiert, genau das ist, was dein `run` beim Replay dekodiert. Sie auf beiden Seiten zu nutzen hält die zwei im Gleichschritt.

## Wann das Kit überspringen

Überspring es, wenn du schon deterministische Logik hast (eine Festkomma-Simulation, ein für Spec-Floats kompiliertes WASM-Modul) oder wenn dein Spiel einfach genug ist, dass `run` von Hand zu schreiben trivial ist. Die Plattform weiß oder kümmert sich nie darum, ob das Kit dein `run` produziert hat; sie lädt und spielt nur den Vertrag ab.

## Siehe auch

- [Der Replay-Vertrag](/docs/marketplace-game-development/replay-contract): das `run` / Seed / Urteil, das dieses Kit produziert.
- [Ein Marketplace-Spiel bauen](/docs/marketplace-game-development/build-a-marketplace-game): das Spiel, dessen Logik dieses Kit stützen kann.
- [Das caputchin.json-Manifest](/docs/marketplace-game-development/the-caputchin-json-manifest#the-run-artifact): das produzierte `run` als Artefakt ausliefern.
