---
type: tutorial
title: engine-kit
summary: Опциональный кит авторствования, который производит соответствующий run реплея из обычного редьюсера, обрабатывая детерминизм, цикл фиксированного шага, кодирование трассы и локальную самопроверку за тебя.
---

`@caputchin/engine-kit` это опциональный кит авторствования, который превращает обычный игровой редьюсер в соответствующий [`run`](/docs/marketplace-game-development/replay-contract), обрабатывая детерминизм, цикл фиксированного шага и кодирование трассы за тебя. Это один удобный способ произвести этот артефакт, а не требование: ты можешь полностью игнорировать кит и поставить голый `run`, написанный вручную. Тянись к нему, когда предпочитаешь писать обычную игровую логику и иметь детерминизм, цикл реплея и кодирование трассы, обработанные за тебя.

Кит реэкспортирует всю поверхность [контракта реплея](/docs/marketplace-game-development/replay-contract), так что у пользователей кита единственное место импорта.

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

## Идея: напиши редьюсер, получи run

Ключевой ход кита это дать тебе выразить твою игру как **чистый редьюсер**: функцию, которая берёт текущее состояние и ввод одного тика и возвращает следующее состояние. Из этого редьюсера плюс детерминированных примитивов адаптер `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
```

## Детерминированные примитивы

Кит даёт тебе две вещи, которые чаще всего ломают кросс-рантаймовый детерминизм, обе засеваемые и воспроизводимые:

- `cap.rng(seed)` (и `cap.rngFromState`) - засеваемый PRNG. Используй его для каждого случайного выбора вместо `Math.random()`.
- `cap.math` - детерминированные трансцендентные функции (`sin`, `cos`, ...), которые согласуются между рантаймами, вместо платформенных `Math`, которые могут не согласовываться.

## Опциональные шимы

- `applyShim()` - нейтрализует недетерминированные глобалы (настенные часы, `Math.random`), чтобы случайный вызов сбоил громко в разработке, а не молча разошёлся при реплее.
- `applyDomShim()` - минимальный headless-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` это лучший предсказатель того, что самопроверка публикации маркетплейса пройдёт (это тот же стандарт детерминизма). Кит также поставляет CLI для запуска этого из скриптов `package.json` или CI.

## Кодирование трассы

`encodeTrace` / `decodeTrace` дают тебе компактный, версионированный формат трассы, чтобы поток ввода, который испускает твоя живая игра, был ровно тем, что декодирует твой `run` при реплее. Использование их на обеих сторонах держит эти двое в lockstep.

## Когда пропустить кит

Пропусти его, когда у тебя уже есть детерминированная логика (симуляция на фиксированной точке, WASM-модуль, скомпилированный для спецификационных float) или когда твоя игра достаточно проста, чтобы написать `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` как артефакта.
