{"_id":"@caputchin/determinism","name":"@caputchin/determinism","dist-tags":{"latest":"0.2.0"},"versions":{"0.2.0":{"name":"@caputchin/determinism","version":"0.2.0","description":"Make a JS environment deterministic so the same code runs bit-identically in the browser and on the server: deterministic transcendental math (fdlibm kernels) plus a Math swap. The shared determinism primitive for Caputchin replay presets.","keywords":["caputchin","deterministic","determinism","fdlibm","math","replay","cross-platform"],"homepage":"https://github.com/Caputchin/caputchin-sdk#readme","repository":{"type":"git","url":"git+https://github.com/Caputchin/caputchin-sdk.git","directory":"kits/determinism"},"bugs":{"url":"https://github.com/Caputchin/caputchin-sdk/issues"},"license":"Apache-2.0","type":"module","publishConfig":{"access":"public"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"sideEffects":false,"devDependencies":{"@types/node":"^22.0.0","typescript":"^5.4.0","tsup":"^8.0.0","typedoc":"^0.28.19","typedoc-plugin-markdown":"^4.11.0","vitest":"^2.0.0"},"scripts":{"build":"tsup","typecheck":"tsc --noEmit","test":"vitest run","test:watch":"vitest","docs":"typedoc && node ../../scripts/normalize-docs.mjs docs"},"_id":"@caputchin/determinism@0.2.0","_integrity":"sha512-85HXyRyiLIBxUrn9du4NZffpq3FpHh/xjcoNuu4alS9k28P/GAfu+ywxErzUi3vXUvykFiMFWLc7STpQ2pOw6A==","_resolved":"/tmp/65a4188d243ac9b32082c6ba0a6872b0/caputchin-determinism-0.2.0.tgz","_from":"file:caputchin-determinism-0.2.0.tgz","_nodeVersion":"24.16.0","_npmVersion":"11.13.0","dist":{"integrity":"sha512-85HXyRyiLIBxUrn9du4NZffpq3FpHh/xjcoNuu4alS9k28P/GAfu+ywxErzUi3vXUvykFiMFWLc7STpQ2pOw6A==","shasum":"1b89aa52bc5afbcd737dd52185c32645f10aaa1c","tarball":"https://registry.npmjs.org/@caputchin/determinism/-/determinism-0.2.0.tgz","fileCount":7,"unpackedSize":103435,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDLwxpdONOvTnaM2fAUOIVBpmMk9//ykc/aDApPmmdgEQIhANSfX5ZVzCNca0JxCkguSSX3Hqva2p61j50ETF/63moc"}]},"_npmUser":{"name":"caputchiner","email":"info@caputchin.com"},"directories":{},"maintainers":[{"name":"caputchiner","email":"info@caputchin.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/determinism_0.2.0_1780536352850_0.8706134404585837"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-04T01:25:52.607Z","0.2.0":"2026-06-04T01:25:53.009Z","modified":"2026-06-04T01:25:53.424Z"},"maintainers":[{"name":"caputchiner","email":"info@caputchin.com"}],"description":"Make a JS environment deterministic so the same code runs bit-identically in the browser and on the server: deterministic transcendental math (fdlibm kernels) plus a Math swap. The shared determinism primitive for Caputchin replay presets.","homepage":"https://github.com/Caputchin/caputchin-sdk#readme","keywords":["caputchin","deterministic","determinism","fdlibm","math","replay","cross-platform"],"repository":{"type":"git","url":"git+https://github.com/Caputchin/caputchin-sdk.git","directory":"kits/determinism"},"bugs":{"url":"https://github.com/Caputchin/caputchin-sdk/issues"},"license":"Apache-2.0","readme":"# @caputchin/determinism\n\nMake a JS environment behave deterministically, so the **same code produces the\nsame result in the browser and on the server**. This is the shared determinism\nprimitive the Caputchin replay presets build on: a game library bundled into a\npreset can compute its physics/math bit-for-bit identically in live play and in\nthe headless server replay.\n\nIt is a focused primitive, not a game-authoring model: no reducer, no contract,\nno engine. You depend on it to make the *environment* deterministic, then pair it\nwith a fixed-step seeded loop for full determinism.\n\n## What it provides\n\n- **`capMath`** - deterministic transcendentals (`sin`, `cos`, `tan`, `asin`,\n  `acos`, `atan`, `atan2`, `exp`, `log`, `pow`, `hypot`, `cbrt`, hyperbolics).\n  fdlibm-derived kernels built only from operations that are bit-identical across\n  V8 / JSC / SpiderMonkey and CPU architectures (`+ - * /`, `Math.sqrt`, bit\n  surgery). The native `Math.sin`/`cos`/`pow`/... are libm-approximated and\n  diverge between a player's ARM device and an x86-64 server, which would reject\n  honest players; these do not.\n- **`swapMath(scope?)`** - swap the engine-visible `Math.*` transcendentals to\n  `capMath`, so even a bundled engine that calls `Math.sin(...)` directly becomes\n  deterministic. Leaves the IEEE-754-mandated members (`sqrt`/`abs`/`floor`/...)\n  intact (they are already deterministic). It does NOT neutralize wall-clock /\n  entropy / IO globals; a framework engine needs `requestAnimationFrame` /\n  `performance` / `navigator` to run.\n- **`makeDeterministic(scope?)`** - the single composition point. Today it is\n  `swapMath`; future deterministic stubs (a seeded clock, env-safe RNG) join here.\n\n## Usage\n\n```ts\nimport { makeDeterministic } from '@caputchin/determinism';\n\n// Once, before the bundled engine runs (same call live and on replay):\nmakeDeterministic(globalThis);\n```\n\nOr call the deterministic math directly instead of `Math`:\n\n```ts\nimport { capMath } from '@caputchin/determinism';\nconst a = capMath.atan2(dy, dx); // bit-identical everywhere\n```\n\n## The determinism rule\n\nFloat `+ - * /` and `Math.sqrt`/`abs`/`floor`/`round` are IEEE-754 correctly\nrounded, so they are deterministic by default. The transcendentals are not, which\nis the gap this kit closes. Pair the Math swap with a deterministic loop (fixed\ntimestep, seeded RNG, no wall clock in the sim) and the whole environment is\nreproducible.\n","readmeFilename":"README.md","_rev":"1-a0c5160cf7bc1482778df5cad29f396b"}