---
type: reference
title: O contrato de replay
summary: O contrato obrigatório de run/seed/verdict que torna um jogo reproduzível, o que a função run recebe e retorna, como a semente liga um trace a uma rodada, e como o servidor o reexecuta.
---

O contrato de replay é a única superfície obrigatória que um jogo **reproduzível** acorda com a plataforma. Ele é publicado como `@caputchin/replay-contract`: um pacote deliberadamente minúsculo e sem dependências (ele é carregado em um isolate de replay selado, então não puxa nada). Todo o resto sobre seu jogo, a engine, o renderizador, o formato do trace, é seu.

Um jogo que envia um `run` conforme é **reproduzível** e por isso pode **proteger** uma chave de site; um jogo sem um ainda é embutível, mas só como UX (ele mostra **Não reproduzível**). Veja [Publique um jogo no marketplace](/docs/marketplace-game-development/overview#replayable-vs-not-replayable) para essa distinção.

## A função `run`

Um jogo reproduzível envia um módulo JS ou WASM exportando uma função chamada `run`:

```ts
run(seed, config, trace) -> { passed, score, durationMs }
```

```ts
type RunFn<C = unknown> = (
  seed: Seed,
  config: C | null,
  trace: Uint8Array | string,
) => Verdict | Promise<Verdict>
```

| Argumento | Origem | Significado |
|---|---|---|
| `seed` | Servidor | A [semente](#the-seed) por rodada. A montagem da rodada, de posse do servidor. |
| `config` | Servidor | A config de jogabilidade, **anulável e opaca**: a plataforma nunca a inspeciona, e ela é re-resolvida no servidor no replay, nunca afirmada pelo cliente. `null` significa "use os padrões do próprio run". No MVP o servidor passa `null`; config por site é uma fase adiada. |
| `trace` | Cliente | O blob opaco que o cliente do jogador emitiu, que só esta função interpreta. A plataforma nunca o faz parse nem o tipa; são bytes crus ou uma string, limitados só por um teto de tamanho e o limite de CPU do isolate. |

A ordem dos argumentos codifica o modelo de confiança: `seed` e `config` são a montagem da rodada no servidor; `trace` é a entrada do jogador. **Valores que afetam o portão (um limiar de aprovação, vidas) são seguros para ler de `config` mas seriam um contorno se lidos do `trace` do cliente.**

O módulo precisa exportar a função sob o nome `run` (a constante `RUN_EXPORT_NAME`). O anfitrião de replay a invoca e aguarda o resultado (a instanciação de WASM é assíncrona na primeira chamada).

## A semente [#the-seed]

```ts
type Seed = readonly [number, number, number, number]   // 128 bits, 4 u32 words, MSW first
```

A semente são os 128 bits baixos de `SHA-256(sessionId : gameId : roundIndex)`, carregada como quatro palavras de 32 bits sem sinal, a palavra mais significativa primeiro. O `deriveSeed(sessionId, gameId, roundIndex)` do pacote a computa; o servidor a deriva tanto ao emitir a rodada quanto de novo ao reexecutar, então ela nunca anda pela rede como entrada de cliente confiável.

Crucialmente, a semente **liga um trace a uma sessão, jogo e rodada**: reexecutar um trace estranho ou anterior sob uma semente diferente produz `passed: false`. Essa ligação é como a injeção de trace e os ataques de replay são defendidos, então você precisa semear toda aleatoriedade dela para o jogo ativo e o replay do servidor concordarem.

## O veredito

```ts
interface Verdict {
  readonly passed: boolean      // drives the verification decision
  readonly score: number        // game-defined, any finite number
  readonly durationMs: number   // finite, non-negative
}
```

`passed` é o único campo que conduz a decisão do captcha; `score` e `durationMs` são carregados no token emitido (e em um placar futuro). O `parseVerdict(value)` do pacote valida um valor de retorno não confiável e **trata um resultado malformado como uma rodada rejeitada, nunca uma de aprovação**, então um `run` que lança ou retorna lixo falha de forma fechada.

## O determinismo é o requisito inteiro [#determinism-is-the-whole-requirement]

A única regra rígida do contrato: `run` precisa ser **puro e determinístico em dois runtimes**, o navegador do jogador e o isolate do servidor. `(seed, config, trace)` idênticos precisam produzir um veredito idêntico nos dois. As formas comuns de quebrar isto, todas pegas pela autoverificação de publicação como `run-not-conforming`:

- ler `Date.now()`, `performance.now()`, `Math.random()`, ou outros globais não determinísticos;
- ler estado externo (DOM, rede, armazenamento) que o isolate de replay não fornece;
- depender de matemática de ponto flutuante que difere entre runtimes.

Como você alcança o determinismo (ponto fixo, floats spec-WASM, ou IEEE-754 mais um shim de neutralização) é sua escolha; a plataforma só hospeda o replay. O [kit de engine](/docs/marketplace-game-development/engine-kit) fornece primitivas determinísticas prontas se você preferir não fazer a sua.

## Como o servidor o usa

```mermaid
sequenceDiagram
  participant P as Navegador do jogador
  participant S as Servidor da Caputchin
  participant R as Isolate de replay
  S->>S: deriveSeed(sessionId, gameId, round)
  S->>P: emite a rodada com a semente
  P->>P: joga, registrando o trace
  P->>S: envia o trace na aprovação
  S->>S: re-deriva a mesma semente
  S->>R: run(seed, config, trace)
  R-->>S: verdict { passed, score, durationMs }
  S->>S: parseVerdict, decide
```

O artefato que o isolate carrega é o seu bundle `run`, ou o `entry` ativo ou o [artefato `run`](/docs/marketplace-game-development/the-caputchin-json-manifest#the-run-artifact) dedicado do manifesto.

## Veja também

- [O engine-kit](/docs/marketplace-game-development/engine-kit): produza um `run` conforme a partir de um reducer simples, com o determinismo tratado por você.
- [O manifesto caputchin.json](/docs/marketplace-game-development/the-caputchin-json-manifest#the-run-artifact): declarar o artefato `run` e seus módulos.
- [Construir um jogo de marketplace](/docs/marketplace-game-development/build-a-marketplace-game): registrar o trace que este contrato reexecuta.
- [Referência de erros de publicação](/docs/marketplace-game-development/publish-failed-reference): o resultado `run-not-conforming` da autoverificação.
