---
type: tutorial
title: The engine kit
summary: An optional authoring kit that produces a conforming replay run from a plain reducer, handling determinism, the fixed-step loop, trace encoding, and a local self-check for you.
---

`@caputchin/engine-kit` is an optional authoring kit that turns a plain game reducer into a conforming [`run`](/docs/marketplace-game-development/replay-contract), handling determinism, the fixed-step loop, and trace encoding for you. It is one convenient way to produce that artifact, not a requirement: you can ignore the kit entirely and ship a bare `run` you wrote by hand. Reach for it when you would rather write ordinary game logic and have the determinism, the replay loop, and trace encoding handled for you.

The kit re-exports the whole [replay contract](/docs/marketplace-game-development/replay-contract) surface, so kit users have a single import site.

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

## The idea: write a reducer, get a run

The kit's core move is to let you express your game as a **pure reducer**: a function that takes the current state and one tick's input and returns the next state. From that reducer plus deterministic primitives, the kit's `toRun` adapter produces a `run(seed, config, trace)` that conforms to the contract by 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
```

## Deterministic primitives

The kit gives you the two things that most often break cross-runtime determinism, both seeded and reproducible:

- `cap.rng(seed)` (and `cap.rngFromState`) - a seedable PRNG. Use it for every random choice instead of `Math.random()`.
- `cap.math` - deterministic transcendentals (`sin`, `cos`, ...) that agree across runtimes, instead of the platform `Math` ones that may not.

## Optional shims

- `applyShim()` - neutralizes the non-deterministic globals (the wall clock, `Math.random`) so an accidental call fails loud in development instead of silently diverging at replay.
- `applyDomShim()` - a minimal headless DOM for the framework path, so a reducer that touches a tiny DOM surface still replays in the no-DOM isolate.

## Run it locally before publishing

The kit's `replay` harness runs a trace through your engine the same way the server will, and `selfCheck` runs a battery of cases and reports any non-determinism **before** you publish:

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

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

A clean local `selfCheck` is the best predictor that the marketplace's publish self-check will pass (it is the same determinism standard). The kit also ships a CLI for running this from `package.json` scripts or CI.

## Trace encoding

`encodeTrace` / `decodeTrace` give you a compact, versioned trace format so the input stream your live game emits is exactly what your `run` decodes at replay. Using them on both sides keeps the two in lockstep.

## When to skip the kit

Skip it when you already have deterministic logic (a fixed-point simulation, a WASM module compiled for spec-floats) or when your game is simple enough that hand-writing `run` is trivial. The platform never knows or cares whether the kit produced your `run`; it only loads and replays the contract.

## See also

- [The replay contract](/docs/marketplace-game-development/replay-contract): the `run` / seed / verdict this kit produces.
- [Build a marketplace game](/docs/marketplace-game-development/build-a-marketplace-game): the game whose logic this kit can back.
- [The caputchin.json manifest](/docs/marketplace-game-development/the-caputchin-json-manifest#the-run-artifact): shipping the produced `run` as the artifact.
