---
type: tutorial
title: エンジンキット engine-kit
summary: 素のレデューサーから適合するリプレイの run を生む任意の作成キット、決定論、固定ステップのループ、トレースのエンコード、ローカルのセルフチェックをあなたのために扱います。
---

`@caputchin/engine-kit` は、素のゲームのレデューサーを適合する [`run`](/docs/marketplace-game-development/replay-contract) に変える任意の作成キットで、決定論、固定ステップのループ、トレースのエンコードをあなたのために扱います。それはその成果物を生む 1 つの便利な方法であって、要件ではありません。キットを丸ごと無視して、手で書いた素の `run` を出荷できます。普通のゲームロジックを書いて、決定論、リプレイのループ、トレースのエンコードをあなたのために扱ってほしいときに、これに手を伸ばしてください。

キットは [リプレイ契約](/docs/marketplace-game-development/replay-contract) の面全体を再エクスポートするので、キットのユーザーは単一のインポート先を持ちます。

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

## アイデア：レデューサーを書き、run を得る

キットの核心の一手は、あなたのゲームを **純粋なレデューサー** として表現させることです。現在の状態と 1 ティックの入力を取り、次の状態を返す関数です。そのレデューサーに決定論的なプリミティブを足したものから、キットの `toRun` アダプターは、構成によって契約に適合する `run(seed, config, trace)` を生みます。

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

## 決定論的なプリミティブ

キットは、クロスランタイムの決定論を最もよく壊す 2 つのものを、どちらもシードされ再現可能にして与えます：

- `cap.rng(seed)`（と `cap.rngFromState`）- シード可能な PRNG。`Math.random()` の代わりに、すべてのランダムな選択にそれを使います。
- `cap.math` - ランタイム間で一致する決定論的な超越関数（`sin`、`cos` など）。一致しないかもしれないプラットフォームの `Math` のものの代わりです。

## 任意のシム

- `applyShim()` - 非決定論的なグローバル（壁時計、`Math.random`）を中和するので、うっかりの呼び出しが、リプレイで黙って分岐するのではなく、開発で大声で失敗します。
- `applyDomShim()` - フレームワークのパスのための最小限のヘッドレス DOM。小さな DOM の面に触れるレデューサーも、DOM のないアイソレートでなおリプレイできます。

## 公開の前にローカルで走らせる

キットの `replay` ハーネスは、サーバーがするのと同じやり方でエンジンを通してトレースを走らせ、`selfCheck` はケースの一群を走らせ、**公開する前に** どの非決定論も報告します：

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

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

クリーンなローカルの `selfCheck` は、マーケットプレイスの公開のセルフチェックが通るという最良の予測子です（それは同じ決定論の基準です）。キットは、これを `package.json` のスクリプトや CI から走らせる CLI も出荷します。

## トレースのエンコード

`encodeTrace` / `decodeTrace` は、コンパクトでバージョン管理されたトレースの形式を与えるので、ライブのゲームが発する入力のストリームが、リプレイで `run` がデコードするものとちょうど同じです。両側でそれらを使うと、2 つがロックステップで保たれます。

## キットを飛ばすとき

すでに決定論的なロジック（固定小数点のシミュレーション、仕様の浮動小数点向けにコンパイルされた WASM モジュール）があるとき、またはゲームが、`run` を手で書くのが些末なほど単純なときに、それを飛ばしてください。プラットフォームは、キットがあなたの `run` を生んだかを決して知らず、気にしません。契約を読み込んでリプレイするだけです。

## あわせて読む

- [リプレイ契約](/docs/marketplace-game-development/replay-contract)：このキットが生む `run` / シード / 判定。
- [マーケットプレイスゲームを作る](/docs/marketplace-game-development/build-a-marketplace-game)：このキットが支えられるロジックを持つゲーム。
- [caputchin.json マニフェスト](/docs/marketplace-game-development/the-caputchin-json-manifest#the-run-artifact)：生まれた `run` をアーティファクトとして出荷する。
