Kontrak putar-ulang
Kontrak putar-ulang adalah satu permukaan wajib yang disepakati game bisa-diputar-ulang dengan platform. Ia diterbitkan sebagai @caputchin/replay-contract: paket yang sengaja mungil, bebas-dependensi (ia dimuat ke isolate putar-ulang tersegel, jadi ia tak menarik apa pun). Semua hal lain tentang game-mu, engine, renderer, format trace, adalah milikmu.
Sebuah game yang mengirim run yang sesuai bisa-diputar-ulang dan karenanya bisa menggerbang sebuah kunci situs; game tanpa satu tetap bisa-disematkan, tapi hanya sebagai UX (ia menunjukkan Tidak bisa diputar ulang). Lihat Kirim game ke marketplace untuk perbedaan itu.
Fungsi run
Sebuah game bisa-diputar-ulang mengirim modul JS atau WASM yang mengekspor satu fungsi bernama run:
run(seed, config, trace) -> { passed, score, durationMs }type RunFn<C = unknown> = (
seed: Seed,
config: C | null,
trace: Uint8Array | string,
) => Verdict | Promise<Verdict>| Argumen | Sumber | Makna |
|---|---|---|
seed | Server | Seed per-ronde. Penyiapan ronde yang dimiliki-server. |
config | Server | Config gameplay, nullable dan opaque: platform tak pernah memeriksanya, dan ia diselesaikan-ulang di sisi-server saat putar-ulang, tak pernah diklaim-klien. null berarti "pakai default run sendiri". Di MVP server melewatkan null; config per-situs adalah fase yang ditunda. |
trace | Klien | Blob opaque yang dipancarkan klien pemain, yang hanya fungsi ini tafsirkan. Platform tak pernah mengurai atau mengetiknya; ia byte mentah atau string, dibatasi hanya oleh batas ukuran dan batas CPU isolate. |
Urutan argumen mengkodekan model kepercayaan: seed dan config adalah penyiapan server ronde; trace adalah input pemain. Nilai yang memengaruhi-gerbang (ambang lolos, nyawa) aman dibaca dari config tapi akan menjadi bypass jika dibaca dari trace klien.
Modul harus mengekspor fungsi di bawah nama run (konstanta RUN_EXPORT_NAME). Host putar-ulang memanggilnya dan menunggu hasilnya (instansiasi WASM async pada panggilan pertama).
Seed
type Seed = readonly [number, number, number, number] // 128 bits, 4 u32 words, MSW firstSeed adalah 128 bit rendah dari SHA-256(sessionId : gameId : roundIndex), dibawa sebagai empat kata 32-bit tak-bertanda, kata paling-signifikan dulu. deriveSeed(sessionId, gameId, roundIndex) paket menghitungnya; server menurunkannya baik saat menerbitkan ronde maupun lagi saat memutar-ulang, jadi ia tak pernah menumpang kabel sebagai input klien tepercaya.
Krusial, seed mengikat trace ke satu sesi, game, dan ronde: memutar-ulang trace asing atau lebih awal di bawah seed berbeda menghasilkan passed: false. Pengikatan itu adalah cara injeksi trace dan serangan putar-ulang dipertahankan, jadi kamu harus menyemai semua keacakan darinya agar permainan live dan putar-ulang server sepakat.
Vonis
interface Verdict {
readonly passed: boolean // drives the verification decision
readonly score: number // game-defined, any finite number
readonly durationMs: number // finite, non-negative
}passed adalah satu-satunya bidang yang mengemudikan keputusan captcha; score dan durationMs dibawa di token yang diterbitkan (dan papan skor masa depan). parseVerdict(value) paket memvalidasi nilai kembalian tak-tepercaya dan memperlakukan hasil yang cacat sebagai ronde ditolak, tak pernah yang lolos, jadi run yang melempar atau mengembalikan sampah gagal tertutup.
Determinisme adalah seluruh persyaratan
Satu aturan keras kontrak: run harus murni dan deterministik lintas dua runtime, peramban pemain dan isolate server. (seed, config, trace) identik harus menghasilkan vonis identik di keduanya. Cara umum merusak ini, semua ditangkap pemeriksaan-diri terbit sebagai run-not-conforming:
- membaca
Date.now(),performance.now(),Math.random(), atau global non-deterministik lain; - membaca state eksternal (DOM, jaringan, penyimpanan) yang tak disediakan isolate putar-ulang;
- bergantung pada matematika titik-mengambang yang berbeda antar runtime.
Bagaimana kamu mencapai determinisme (titik-tetap, float spec-WASM, atau IEEE-754 plus shim netralisasi) adalah pilihanmu; platform hanya menghosting putar-ulang. Kit engine menyediakan primitif deterministik siap-pakai jika kamu lebih suka tak menggulung sendiri.
Bagaimana server memakainya
Artefak yang dimuat isolate adalah bundel run-mu, entah entry live atau artefak run khusus dari manifest.
Lihat juga
- engine-kit: hasilkan
runyang sesuai dari reducer biasa, dengan determinisme ditangani untukmu. - Manifest caputchin.json: mendeklarasikan artefak
rundan modulnya. - Bangun game marketplace: merekam trace yang diputar-ulang kontrak ini.
- Referensi galat terbit: hasil pemeriksaan-diri
run-not-conforming.