@series-inc/rundot-syncplay 5.23.0-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/README.md +610 -0
  2. package/dist/animation.d.ts +119 -0
  3. package/dist/animation.js +488 -0
  4. package/dist/asset-cooking.d.ts +82 -0
  5. package/dist/asset-cooking.js +364 -0
  6. package/dist/authority-room.d.ts +217 -0
  7. package/dist/authority-room.js +701 -0
  8. package/dist/bot-documents.d.ts +115 -0
  9. package/dist/bot-documents.js +549 -0
  10. package/dist/bot-primitives.d.ts +152 -0
  11. package/dist/bot-primitives.js +472 -0
  12. package/dist/browser.d.ts +57 -0
  13. package/dist/browser.js +53 -0
  14. package/dist/canonical.d.ts +12 -0
  15. package/dist/canonical.js +288 -0
  16. package/dist/certification.d.ts +455 -0
  17. package/dist/certification.js +1855 -0
  18. package/dist/chaos-certification.d.ts +56 -0
  19. package/dist/chaos-certification.js +1397 -0
  20. package/dist/cjs/animation.js +495 -0
  21. package/dist/cjs/asset-cooking.js +372 -0
  22. package/dist/cjs/authority-room.js +704 -0
  23. package/dist/cjs/bot-documents.js +556 -0
  24. package/dist/cjs/bot-primitives.js +482 -0
  25. package/dist/cjs/browser.js +96 -0
  26. package/dist/cjs/canonical.js +299 -0
  27. package/dist/cjs/certification.js +1860 -0
  28. package/dist/cjs/chaos-certification.js +1402 -0
  29. package/dist/cjs/collections.js +36 -0
  30. package/dist/cjs/collision.js +96 -0
  31. package/dist/cjs/commands.js +987 -0
  32. package/dist/cjs/config-bundle.js +491 -0
  33. package/dist/cjs/creator.js +30 -0
  34. package/dist/cjs/deterministic-primitives.js +134 -0
  35. package/dist/cjs/deterministic-session.js +1410 -0
  36. package/dist/cjs/ecs-lite.js +155 -0
  37. package/dist/cjs/effects-adapter.js +97 -0
  38. package/dist/cjs/engine-complete.js +2297 -0
  39. package/dist/cjs/engine-core-proof.js +70 -0
  40. package/dist/cjs/engine-parity-matrix.js +874 -0
  41. package/dist/cjs/engine-parity.js +3183 -0
  42. package/dist/cjs/engine-runtime.js +3141 -0
  43. package/dist/cjs/errors.js +22 -0
  44. package/dist/cjs/events.js +247 -0
  45. package/dist/cjs/examples/counter-duel.js +157 -0
  46. package/dist/cjs/examples/fixed-arena.js +368 -0
  47. package/dist/cjs/index.js +229 -0
  48. package/dist/cjs/input-authority.js +150 -0
  49. package/dist/cjs/input-button.js +256 -0
  50. package/dist/cjs/input-timeline.js +418 -0
  51. package/dist/cjs/instant-replay.js +66 -0
  52. package/dist/cjs/lag-compensation3d.js +837 -0
  53. package/dist/cjs/local-authority-server-runner.js +1121 -0
  54. package/dist/cjs/local-authority-wire.js +1497 -0
  55. package/dist/cjs/local-authority.js +817 -0
  56. package/dist/cjs/local-ws-adapter.js +150 -0
  57. package/dist/cjs/match-log.js +61 -0
  58. package/dist/cjs/math.js +157 -0
  59. package/dist/cjs/mock-network-adapter.js +26 -0
  60. package/dist/cjs/movement.js +703 -0
  61. package/dist/cjs/movement3d.js +1246 -0
  62. package/dist/cjs/multiclient-authority.js +308 -0
  63. package/dist/cjs/multiplayer-service.js +434 -0
  64. package/dist/cjs/navigation.js +347 -0
  65. package/dist/cjs/navmesh.js +1437 -0
  66. package/dist/cjs/networked-client.js +691 -0
  67. package/dist/cjs/networked-input-authority.js +443 -0
  68. package/dist/cjs/node.js +47 -0
  69. package/dist/cjs/number-lab.js +78 -0
  70. package/dist/cjs/offline-session.js +370 -0
  71. package/dist/cjs/package.json +1 -0
  72. package/dist/cjs/pause-resume.js +43 -0
  73. package/dist/cjs/physics-cert.js +426 -0
  74. package/dist/cjs/physics2d.js +751 -0
  75. package/dist/cjs/physics3d.js +1996 -0
  76. package/dist/cjs/prediction-culling.js +203 -0
  77. package/dist/cjs/protocol-lab.js +1299 -0
  78. package/dist/cjs/r3f-render-adapter.js +209 -0
  79. package/dist/cjs/random.js +59 -0
  80. package/dist/cjs/replay-bundle.js +1598 -0
  81. package/dist/cjs/replay-inspect.js +236 -0
  82. package/dist/cjs/replay-scoring.js +68 -0
  83. package/dist/cjs/replay.js +356 -0
  84. package/dist/cjs/reports.js +181 -0
  85. package/dist/cjs/rollback-history.js +251 -0
  86. package/dist/cjs/runtime-guards.js +111 -0
  87. package/dist/cjs/sample-lab.js +145 -0
  88. package/dist/cjs/sample-scenes.js +752 -0
  89. package/dist/cjs/schema-artifacts.js +359 -0
  90. package/dist/cjs/schema-codegen.js +544 -0
  91. package/dist/cjs/schema-dsl-binary.js +655 -0
  92. package/dist/cjs/schema.js +319 -0
  93. package/dist/cjs/sdk-offline.js +99 -0
  94. package/dist/cjs/session-promotion.js +74 -0
  95. package/dist/cjs/session-snapshot.js +265 -0
  96. package/dist/cjs/session-wire.js +216 -0
  97. package/dist/cjs/signals.js +103 -0
  98. package/dist/cjs/sparse-set.js +169 -0
  99. package/dist/cjs/synctest.js +136 -0
  100. package/dist/cjs/system-lifecycle.js +286 -0
  101. package/dist/cjs/timers.js +61 -0
  102. package/dist/cjs/tools/static-checker.js +1468 -0
  103. package/dist/cjs/types.js +2 -0
  104. package/dist/cjs/venus-mp-budget.js +125 -0
  105. package/dist/cjs/ws-frame.js +255 -0
  106. package/dist/cli.d.ts +2 -0
  107. package/dist/cli.js +11379 -0
  108. package/dist/collections.d.ts +9 -0
  109. package/dist/collections.js +30 -0
  110. package/dist/collision.d.ts +25 -0
  111. package/dist/collision.js +85 -0
  112. package/dist/commands.d.ts +137 -0
  113. package/dist/commands.js +977 -0
  114. package/dist/config-bundle.d.ts +89 -0
  115. package/dist/config-bundle.js +483 -0
  116. package/dist/creator.d.ts +20 -0
  117. package/dist/creator.js +11 -0
  118. package/dist/deterministic-primitives.d.ts +59 -0
  119. package/dist/deterministic-primitives.js +126 -0
  120. package/dist/deterministic-session.d.ts +197 -0
  121. package/dist/deterministic-session.js +1401 -0
  122. package/dist/ecs-lite.d.ts +26 -0
  123. package/dist/ecs-lite.js +152 -0
  124. package/dist/effects-adapter.d.ts +21 -0
  125. package/dist/effects-adapter.js +94 -0
  126. package/dist/engine-complete.d.ts +45 -0
  127. package/dist/engine-complete.js +2292 -0
  128. package/dist/engine-core-proof.d.ts +26 -0
  129. package/dist/engine-core-proof.js +66 -0
  130. package/dist/engine-parity-matrix.d.ts +300 -0
  131. package/dist/engine-parity-matrix.js +869 -0
  132. package/dist/engine-parity.d.ts +74 -0
  133. package/dist/engine-parity.js +3178 -0
  134. package/dist/engine-runtime.d.ts +351 -0
  135. package/dist/engine-runtime.js +3123 -0
  136. package/dist/errors.d.ts +11 -0
  137. package/dist/errors.js +17 -0
  138. package/dist/events.d.ts +45 -0
  139. package/dist/events.js +242 -0
  140. package/dist/examples/counter-duel.d.ts +43 -0
  141. package/dist/examples/counter-duel.js +150 -0
  142. package/dist/examples/fixed-arena.d.ts +110 -0
  143. package/dist/examples/fixed-arena.js +356 -0
  144. package/dist/index.d.ts +101 -0
  145. package/dist/index.js +66 -0
  146. package/dist/input-authority.d.ts +82 -0
  147. package/dist/input-authority.js +147 -0
  148. package/dist/input-button.d.ts +36 -0
  149. package/dist/input-button.js +249 -0
  150. package/dist/input-timeline.d.ts +65 -0
  151. package/dist/input-timeline.js +412 -0
  152. package/dist/instant-replay.d.ts +59 -0
  153. package/dist/instant-replay.js +62 -0
  154. package/dist/lag-compensation3d.d.ts +146 -0
  155. package/dist/lag-compensation3d.js +827 -0
  156. package/dist/local-authority-server-runner.d.ts +79 -0
  157. package/dist/local-authority-server-runner.js +1118 -0
  158. package/dist/local-authority-wire.d.ts +142 -0
  159. package/dist/local-authority-wire.js +1477 -0
  160. package/dist/local-authority.d.ts +160 -0
  161. package/dist/local-authority.js +810 -0
  162. package/dist/local-ws-adapter.d.ts +14 -0
  163. package/dist/local-ws-adapter.js +146 -0
  164. package/dist/match-log.d.ts +74 -0
  165. package/dist/match-log.js +57 -0
  166. package/dist/math.d.ts +41 -0
  167. package/dist/math.js +154 -0
  168. package/dist/mock-network-adapter.d.ts +13 -0
  169. package/dist/mock-network-adapter.js +23 -0
  170. package/dist/movement.d.ts +155 -0
  171. package/dist/movement.js +694 -0
  172. package/dist/movement3d.d.ts +195 -0
  173. package/dist/movement3d.js +1238 -0
  174. package/dist/multiclient-authority.d.ts +30 -0
  175. package/dist/multiclient-authority.js +305 -0
  176. package/dist/multiplayer-service.d.ts +153 -0
  177. package/dist/multiplayer-service.js +429 -0
  178. package/dist/navigation.d.ts +91 -0
  179. package/dist/navigation.js +338 -0
  180. package/dist/navmesh.d.ts +236 -0
  181. package/dist/navmesh.js +1423 -0
  182. package/dist/networked-client.d.ts +124 -0
  183. package/dist/networked-client.js +688 -0
  184. package/dist/networked-input-authority.d.ts +51 -0
  185. package/dist/networked-input-authority.js +439 -0
  186. package/dist/node.d.ts +22 -0
  187. package/dist/node.js +19 -0
  188. package/dist/number-lab.d.ts +15 -0
  189. package/dist/number-lab.js +75 -0
  190. package/dist/offline-session.d.ts +2 -0
  191. package/dist/offline-session.js +367 -0
  192. package/dist/pause-resume.d.ts +48 -0
  193. package/dist/pause-resume.js +40 -0
  194. package/dist/physics-cert.d.ts +40 -0
  195. package/dist/physics-cert.js +389 -0
  196. package/dist/physics2d.d.ts +142 -0
  197. package/dist/physics2d.js +741 -0
  198. package/dist/physics3d.d.ts +285 -0
  199. package/dist/physics3d.js +1979 -0
  200. package/dist/prediction-culling.d.ts +34 -0
  201. package/dist/prediction-culling.js +200 -0
  202. package/dist/protocol-lab.d.ts +115 -0
  203. package/dist/protocol-lab.js +1295 -0
  204. package/dist/r3f-render-adapter.d.ts +61 -0
  205. package/dist/r3f-render-adapter.js +203 -0
  206. package/dist/random.d.ts +13 -0
  207. package/dist/random.js +55 -0
  208. package/dist/replay-bundle.d.ts +150 -0
  209. package/dist/replay-bundle.js +1586 -0
  210. package/dist/replay-inspect.d.ts +60 -0
  211. package/dist/replay-inspect.js +228 -0
  212. package/dist/replay-scoring.d.ts +28 -0
  213. package/dist/replay-scoring.js +65 -0
  214. package/dist/replay.d.ts +17 -0
  215. package/dist/replay.js +351 -0
  216. package/dist/reports.d.ts +176 -0
  217. package/dist/reports.js +174 -0
  218. package/dist/rollback-history.d.ts +46 -0
  219. package/dist/rollback-history.js +247 -0
  220. package/dist/runtime-guards.d.ts +1 -0
  221. package/dist/runtime-guards.js +108 -0
  222. package/dist/sample-lab.d.ts +32 -0
  223. package/dist/sample-lab.js +134 -0
  224. package/dist/sample-scenes.d.ts +86 -0
  225. package/dist/sample-scenes.js +745 -0
  226. package/dist/schema-artifacts.d.ts +49 -0
  227. package/dist/schema-artifacts.js +356 -0
  228. package/dist/schema-codegen.d.ts +21 -0
  229. package/dist/schema-codegen.js +538 -0
  230. package/dist/schema-dsl-binary.d.ts +75 -0
  231. package/dist/schema-dsl-binary.js +648 -0
  232. package/dist/schema.d.ts +87 -0
  233. package/dist/schema.js +315 -0
  234. package/dist/sdk-offline.d.ts +34 -0
  235. package/dist/sdk-offline.js +96 -0
  236. package/dist/session-promotion.d.ts +26 -0
  237. package/dist/session-promotion.js +70 -0
  238. package/dist/session-snapshot.d.ts +95 -0
  239. package/dist/session-snapshot.js +255 -0
  240. package/dist/session-wire.d.ts +89 -0
  241. package/dist/session-wire.js +211 -0
  242. package/dist/signals.d.ts +31 -0
  243. package/dist/signals.js +99 -0
  244. package/dist/sparse-set.d.ts +34 -0
  245. package/dist/sparse-set.js +165 -0
  246. package/dist/synctest.d.ts +31 -0
  247. package/dist/synctest.js +133 -0
  248. package/dist/system-lifecycle.d.ts +72 -0
  249. package/dist/system-lifecycle.js +281 -0
  250. package/dist/timers.d.ts +17 -0
  251. package/dist/timers.js +53 -0
  252. package/dist/tools/index.d.ts +4 -0
  253. package/dist/tools/index.js +4 -0
  254. package/dist/tools/static-checker.d.ts +31 -0
  255. package/dist/tools/static-checker.js +1462 -0
  256. package/dist/tools/vite-plugin.d.ts +69 -0
  257. package/dist/tools/vite-plugin.js +203 -0
  258. package/dist/types.d.ts +148 -0
  259. package/dist/types.js +1 -0
  260. package/dist/venus-mp-budget.d.ts +29 -0
  261. package/dist/venus-mp-budget.js +122 -0
  262. package/dist/ws-frame.d.ts +49 -0
  263. package/dist/ws-frame.js +247 -0
  264. package/package.json +169 -0
package/README.md ADDED
@@ -0,0 +1,610 @@
1
+ # RUN Syncplay
2
+
3
+ Offline-first deterministic multiplayer engine for RUN.game. You author a
4
+ **deterministic** game (`defineSyncplayGame`, `DeterministicSystem`,
5
+ `DeterministicRandom`) and Syncplay runs it — input authority, prediction, and
6
+ rollback — with no game-specific server logic.
7
+
8
+ This package is intentionally standalone. It does not depend on Venus MP,
9
+ Cloud Run, React Three Fiber, Rapier, Firebase, or the SDK bridge.
10
+
11
+ ## Preview Status
12
+
13
+ This is a headless engine and certification package. It is designed to prove
14
+ deterministic simulation behavior from the CLI before renderer integration is
15
+ added, and to hand deploy-check artifacts to Venus backend upload/room-server
16
+ validation when a room bundle opts in.
17
+
18
+ Production matchmaking, ticket UX, client connection flows, and R3F renderer
19
+ proof are not part of this package yet. The current production-facing Venus MP
20
+ changes validate uploaded deterministic room proof metadata and pass normalized
21
+ proof into room startup; they do not add new matchmaking or client connection
22
+ semantics.
23
+
24
+ ## Testing
25
+
26
+ `test:core` is the confidence surface. It runs the behavioral suites that pin
27
+ the engine's observable multiplayer behavior — authority room, offline/session
28
+ wire, snapshot late-join, crash restore, latency/loss convergence,
29
+ replay-verified scoring, bot backfill, time-sync pacing, match logs,
30
+ spectators, synctest, instant replay, session promotion, and pause/resume —
31
+ and it is the PR gate: `ci-syncplay.yml` runs `npm run build` + `npm run
32
+ test:core` on every PR that touches `packages/syncplay/`.
33
+
34
+ The other subsystem test files (physics, navigation, animation, bots, schema,
35
+ and similar) were reduced to determinism + rollback tripwires: same inputs
36
+ twice must produce identical checksums, and snapshot → advance → restore →
37
+ resimulate must match the uninterrupted run. They are regression alarms, not
38
+ coverage suites; their per-subsystem (near-)100% coverage shards were removed,
39
+ and the remaining `coverage:package:*` shards cover the core modules only.
40
+
41
+ The netcode surface has its own behavioral suites: `pumpPaced` pacing with
42
+ ping-adaptive input delay and client `netStats`, desync detection/response,
43
+ match logs via `matchLog`, spectator support, and `runSyncplaySynctest` for
44
+ creators. See `docs/syncplay-netcode-observability.md`,
45
+ `docs/syncplay-replay-verified-leaderboards.md`, and
46
+ `docs/syncplay-wire-format.md`.
47
+
48
+ The deterministic deploy check (`project:deploy-check` /
49
+ `project:deploy-check-verify`) is an internal-consistency **receipt** — it
50
+ proves the bundle it describes is the bundle that was checked — not a
51
+ cryptographic signature or provenance proof
52
+ (see `.plans/deterministic-multiplayer-branch-cleanup.md`).
53
+
54
+ CI lanes:
55
+
56
+ - `ci-syncplay.yml` — PR gate: build + `test:core` on engine changes.
57
+ - `ci-syncplay-services.yml` — mp-room-server deterministic room/gateway tests
58
+ plus the SDK syncplay bridge tests.
59
+ - `ops-syncplay-nightly.yml` — cross-VM replay verification in Chromium and
60
+ WebKit, plus the 128-player/100k-frame stress soak
61
+ (`certify:deterministic-stress`).
62
+
63
+ Heavier local lanes: `npm run verify:deterministic-backend` (repo root) after
64
+ touching the Venus upload/runtime integration, and `npm run test:certification`
65
+ + `npm run certify:standalone-complete` before a deterministic engine release.
66
+ The full certification path intentionally includes 128-player and 100k-frame
67
+ stress runs; keep it out of ordinary PR auto-testing.
68
+
69
+ ## Current Surface
70
+
71
+ ```ts
72
+ import {
73
+ createSyncplayGameRuntime,
74
+ createSyncplayClient,
75
+ createDeterministicR3fAdapter,
76
+ verifyDeterministicReplay,
77
+ } from '@series-inc/rundot-syncplay/browser';
78
+ import { createDeterministicAuthorityServer } from '@series-inc/rundot-syncplay/node';
79
+ import { rundotSyncplayPlugin } from '@series-inc/rundot-syncplay/tools';
80
+ ```
81
+
82
+ The SDK bridge re-exports a browser-safe subset for games that already depend on
83
+ `@series-inc/rundot-game-sdk`:
84
+
85
+ ```ts
86
+ import {
87
+ createSyncplayGameRuntime,
88
+ createSyncplayClient,
89
+ createDeterministicR3fAdapter,
90
+ verifyDeterministicReplay,
91
+ } from '@series-inc/rundot-game-sdk/syncplay/browser';
92
+ import { createDeterministicAuthorityServer } from '@series-inc/rundot-game-sdk/syncplay/node';
93
+ ```
94
+
95
+ Implemented:
96
+
97
+ - Fixed-tick offline runner.
98
+ - 1 to 128 local input slots.
99
+ - Replay export and Node replay verification.
100
+ - Metrics-only replay mode for long performance runs.
101
+ - Bounded snapshots and restore-to-frame.
102
+ - Deterministic RNG, RNG forking, and fixed-point math helpers.
103
+ - Deterministic collection helpers for stable sorted keys, stable indexed maps,
104
+ and seeded shuffles.
105
+ - Deterministic frame timer helpers for frame/ms conversion, cooldown counters,
106
+ and scheduled frame events.
107
+ - Public ECS-lite world API with stable entity IDs, component add/remove,
108
+ singleton state, deterministic queries, snapshot/restore, and checksums.
109
+ - Runtime guard opt-in for blocked globals during simulation.
110
+ - Static checker CLI and Vite-compatible no-dependency plugin/config helpers,
111
+ including diagnostics for random/time/timers/I/O, unordered iteration, random
112
+ sort comparators, render-object mutation, and uncertified physics stepping.
113
+ - AST-backed deterministic static analysis using TypeScript syntax trees, with
114
+ regex scanning retained only as a parser-unavailable fallback.
115
+ - SDK-shaped offline runtime helper that exposes frame subscriptions, replay
116
+ export, schema-backed checksums, and no server dependency.
117
+ - Stable game-facing browser names for the offline runtime, R3F adapter, replay
118
+ verification, and multiplayer client facade.
119
+ - Stable node/server name for an in-process local authority server facade over
120
+ the local authority runtime.
121
+ - Stable multiplayer facade methods for normalized scalar input submission,
122
+ command-channel submission, command polling, command timeline snapshots,
123
+ reconnect, late join, spectator state, bot-controlled slot metadata, and
124
+ checksum convergence.
125
+ - Stable authority certification artifact export plus a verifier that replays
126
+ recorded lifecycle/input history and recomputes snapshot, command timeline,
127
+ and checksum evidence for CLI certification.
128
+ - Render-only r3f-compatible adapter that emits frozen predicted/verified frame
129
+ props, provides normalized input bindings, and blocks render subscribers from
130
+ mutating checksummed session state.
131
+ - Render-only interpolation helpers and immutable debug overlay data for
132
+ predicted frame, verified frame, checksum, and correction count.
133
+ - SDK test-app r3f visual sample that renders Fixed Arena frame props through
134
+ React Three Fiber and verifies deterministic status, r3f metrics, and a
135
+ visible non-empty WebGL canvas with Playwright.
136
+ - Full SDK subpath export at
137
+ `@series-inc/rundot-game-sdk/syncplay`, verified by SDK Jest
138
+ tests, `build:sdk`, and built `dist` import checks.
139
+ - Curated creator subpath export at
140
+ `@series-inc/rundot-game-sdk/syncplay/creator` for
141
+ browser-safe offline runtime, descriptors, commands, schema artifacts, and
142
+ replay verification without Node tooling, local servers, certification labs,
143
+ render adapters, or engine internals.
144
+ - Manifest-driven H5 creator entrypoint certification that requires game code
145
+ to import the safe `/creator` runtime surface and rejects broad SDK, Node,
146
+ tooling, lab, certification, r3f, and internal runtime imports before release
147
+ evidence is written.
148
+ - H5 browser release proof that opens the built `dist/index.html`, steps the
149
+ starter app through its deterministic UI, and records frame, score, checksum,
150
+ and `index.html` hash evidence alongside browser replay verification.
151
+ - Deterministic project release bundle manifests that inventory release
152
+ evidence, project manifests, certification artifacts, replay bundles, browser
153
+ proofs, and recursive `dist/` files with byte counts and checksums, plus a
154
+ fail-closed bundle verifier for creator CI, deploy tooling, and Venus upload
155
+ proof validation.
156
+ - Local mock network adapter over the protocol lab with delay/loss/duplicate
157
+ settings, rollback metrics, and deterministic replay artifact export.
158
+ - Local WebSocket harness with `/health`, `/protocol`, CLI server/client
159
+ commands, result comparison against the in-memory protocol lab, and a
160
+ Node-only SDK subpath so browser bundles stay free of Node `http`/`crypto`.
161
+ - `lab:venus-mp-budget` compatibility gate for current Venus MP defaults
162
+ (`ROOM_DEFAULT_MAX_PLAYERS=10`, 30 msg/s, 16 KB messages) and explicit
163
+ 128-player adapter settings.
164
+ - `mp-room-server` worker-harness compatibility test that runs a deterministic
165
+ room bundle through `RoomManager`, the worker sandbox, room broadcast, and
166
+ `StateStore.save` without Firestore or Venus MP gateway dependencies.
167
+ - `mp-room-server` WebSocket gateway compatibility test that authenticates
168
+ single-use `TicketStore` tickets, joins real `/ws` clients, sends
169
+ deterministic input, broadcasts `rdm:confirmed`, and verifies persisted
170
+ checksum state.
171
+ - POST `/tickets` compatibility test that mocks Firebase token/profile
172
+ dependencies, mints deterministic-room tickets over HTTP, uses those tickets
173
+ on the real `/ws` gateway, and verifies deterministic confirmation plus
174
+ persisted checksum state.
175
+ - In-memory rollback protocol lab with delay, duplication, reordering, loss,
176
+ disconnect/reconnect, resend, retry cancellation, and desync injection.
177
+ - Late join, asymmetric latency, input-delay sweeps, deterministic bot slots,
178
+ and actual bundled input delivery in the protocol lab.
179
+ - Protocol lab game adapters for the synthetic lab shape and Counter Duel.
180
+ - `lab:netcode` 128-player measurement wrapper for input-minimal,
181
+ moderate-state, and command-burst shapes, with RTT/jitter/loss mapping,
182
+ payload estimates, event metrics, and pass/warn/fail classification.
183
+ - `lab:prediction-culling` local-area AOI lab with predicted/verified execution
184
+ checksums, restore/resim proof, visible-correction metrics, and hidden
185
+ authoritative interaction failures.
186
+ - Descriptor validation for deterministic input/state/event/asset/config/system
187
+ schemas with stable replay identity ids.
188
+ - Descriptor artifact helpers, descriptor-backed replay inspection, and
189
+ `schema:dump` for schema-aware input/state/command serialization,
190
+ deserialization, canonicalization, replay metadata, cooked asset manifests,
191
+ checksums, and frame dumps.
192
+ - `schema:types` TypeScript interface generation for descriptor-declared input,
193
+ state, commands, event payloads, event unions, replay metadata, cooked asset
194
+ manifests, replay identity constants, default input factories, and stable
195
+ serializer helpers.
196
+ - Rollback-safe event timeline primitives for predicted, confirmed, canceled,
197
+ and verified-only view events.
198
+ - Stable JSON report emission for protocol rollback lab runs.
199
+ - Manifest-driven `certify` CLI orchestrator for the v1 deterministic
200
+ multiplayer certification suite, with stable per-fixture JSON artifacts,
201
+ deterministic budget gates, required Node replay verification, and optional
202
+ browser replay groups kept outside the offline core gate.
203
+ - `certify:v1` includes a fixed-foundation fixture with stable golden checksums
204
+ for fixed math, fixed collision vectors, seeded RNG, frame timers, scheduled
205
+ frame events, stable maps/sets, and deterministic shuffles.
206
+ - `certify:v1` includes a protocol-matrix fixture for delay/jitter, loss,
207
+ duplicates, reordering, reconnect, late join, asymmetric latency, input
208
+ delay, bot slots, command bursts, expected desync artifacts, and frame-model
209
+ rollback/correction metrics.
210
+ - `certify:v1` includes static-analysis, schema-tooling, event-callbacks,
211
+ built-in physics, and prediction-culling fixtures so existing deterministic
212
+ authoring, replay/debug, callback, physics, and AOI behavior is validated from
213
+ one offline CLI command.
214
+ - Descriptor replay identity includes command-channel schema IDs and
215
+ prototype/entity-template schema IDs, and `certify:v1` verifies those identity
216
+ fields through the schema-tooling fixture.
217
+ - `certify:v1` includes an external-physics policy gate that keeps
218
+ `rapier2d-compat` blocked from checksummed gameplay until its snapshot,
219
+ restore, query-order, callback, snapshot-hash, and version-identity gates pass.
220
+ - `certify:v1` includes headless ECS-lite, KCC-lite, projectile/hitscan,
221
+ bot-replacement, and genre-like 128-player top-down bot workload fixtures
222
+ before any r3f, Venus MP, or browser dependency enters the verification path.
223
+ - `certify:v1` includes deterministic grid navigation/pathfinding with stable
224
+ query order, unreachable-target detection, slot-ordered avoidance, rollback
225
+ equality, and checksum convergence.
226
+ - Public deterministic navigation primitives for cooked graph assets, stable
227
+ A*, region disabling, dynamic blockers, off-mesh links, flow fields, tilemap
228
+ graph cooking, deterministic avoidance ordering, and rollback-equivalent
229
+ agent stepping.
230
+ - Public deterministic bot primitives for typed stable blackboards, HFSM,
231
+ Behavior Tree, Utility selection, deterministic bot asset cooking, mixed-style
232
+ simulation, rollback equivalence, and 128-player bot replacement metrics.
233
+ - `certify:v1` includes headless reference-sample category coverage for
234
+ asteroids-basic, platform-shooter-2d, simple-fps, twin-stick-shooter,
235
+ arena-brawler, racer-25d, and turn-flow-mini-golf mechanics.
236
+ - Protocol reports include bounded predicted/confirmed/canceled event timeline
237
+ summaries.
238
+ - Replay verification first-mismatch diagnostics, replay frame inspect,
239
+ checksum explain tables, and replay diff CLI commands for lab replay frame
240
+ dumps.
241
+ - `certify:v2 -- --profile chaos` fixture coverage for locally provable
242
+ multiplayer failure modes: resync snapshot-tail recovery, disconnect
243
+ recovery, rollback buffer boundaries, hostile protocol rejection, command
244
+ idempotency, event exactly-once semantics, replay identity failures, random
245
+ rollback, tick catch-up guards, asset/config mismatches, physics/movement
246
+ rollback boundaries, and 128-player command-burst chaos.
247
+ - Fixed-point collision primitives and a Fixed Arena package-local example with
248
+ 128-player replay verification and render projection output.
249
+ - `lab:physics-cert` built-in fixed physics certification for fixed-arena and
250
+ 128-slot load shapes with snapshot/restore, stable collision/query ordering,
251
+ and timing metrics.
252
+ - `lab:physics-cert -- --engine rapier2d-compat` certification for
253
+ `@dimforge/rapier2d-compat@0.19.3`; the current pinned cert reproduces
254
+ snapshot/restore nondeterminism, so Rapier remains render/prototype-only for
255
+ checksummed gameplay.
256
+ - Public deterministic 2D physics primitives for static/dynamic/kinematic AABB
257
+ bodies, sensors/triggers, enter/stay/exit callbacks, layer masks,
258
+ deterministic AABB and ray queries, material response, simple fixed/distance/
259
+ spring/motor constraints, rollback-equivalent stepping, and budget metrics.
260
+ - Public deterministic movement primitives for KCC-like slopes, steps, ledges,
261
+ moving platforms, elevators, one-way platforms, wall slides, jump buffering,
262
+ coyote time, top-down acceleration/drag/sliding, nav steering, quantized FPS
263
+ aim, deterministic recoil, lag-compensated target rewind, and rollback
264
+ equivalence.
265
+ - Public headless sample-scene fixtures for Asteroids, Simple FPS, Twin Stick,
266
+ Platform Shooter, Arena Brawler, Vehicle, Mini Golf, Waiting Room, Boat/Water,
267
+ and Animator mechanics, each with named counters, rollback-equivalent
268
+ checksums, and CLI-certified mechanic invariants.
269
+ - Counter Duel package-local example with replay verification and event output.
270
+
271
+ ## Commands
272
+
273
+ ```bash
274
+ npm test
275
+ npm run build
276
+
277
+ npm run project:scaffold -- ./deterministic-game --name "Arena Test"
278
+ npm run project:certify -- ./deterministic-game/syncplay.project.json --require descriptor,assets,config,replay-runtime,static-determinism --frames 32 --out-dir ./deterministic-game/artifacts/deterministic --json ./deterministic-game/artifacts/deterministic/project-certification.json
279
+ npm run project:summary -- ./deterministic-game/artifacts/deterministic/project-certification.json --out ./deterministic-game/artifacts/deterministic/project-certification-summary.md --json ./deterministic-game/artifacts/deterministic/project-certification-summary.json
280
+ npm run project:preflight -- ./deterministic-game/syncplay.project.json --certification ./deterministic-game/artifacts/deterministic/project-certification.json --summary ./deterministic-game/artifacts/deterministic/project-certification-summary.md --dist ./deterministic-game/dist --out ./deterministic-game/artifacts/deterministic/project-preflight.md --json ./deterministic-game/artifacts/deterministic/project-preflight.json
281
+ npm run project:check -- ./deterministic-game/syncplay.project.json --require descriptor,assets,config,replay-runtime,static-determinism --frames 32 --out-dir ./deterministic-game/artifacts/deterministic --dist ./deterministic-game/dist --out ./deterministic-game/artifacts/deterministic/project-check.md --json ./deterministic-game/artifacts/deterministic/project-check.json --junit ./deterministic-game/artifacts/deterministic/project-check.xml --release-json ./deterministic-game/artifacts/deterministic/project-release-evidence.json
282
+ npm run project:release-verify -- ./deterministic-game/artifacts/deterministic/project-release-evidence.json --json ./deterministic-game/artifacts/deterministic/project-release-verification.json
283
+ npm run project:release-bundle -- ./deterministic-game/artifacts/deterministic/project-release-evidence.json --json ./deterministic-game/artifacts/deterministic/project-release-bundle.json
284
+ npm run project:release-bundle-verify -- ./deterministic-game/artifacts/deterministic/project-release-bundle.json --out ./deterministic-game/artifacts/deterministic/project-release-bundle-verification.md --json ./deterministic-game/artifacts/deterministic/project-release-bundle-verification.json --junit ./deterministic-game/artifacts/deterministic/project-release-bundle-verification.xml
285
+ npm run project:release-bundle-schema -- --json artifacts/reports/project-release-bundle-schema.json
286
+ npm run project:deploy-check -- ./deterministic-game/syncplay.project.json --bundle ./deterministic-game/artifacts/deterministic/project-release-bundle.json --out ./deterministic-game/artifacts/deterministic/project-deploy-check.md --json ./deterministic-game/artifacts/deterministic/project-deploy-check.json --junit ./deterministic-game/artifacts/deterministic/project-deploy-check.xml
287
+ npm run project:deploy-check-verify -- ./deterministic-game/artifacts/deterministic/project-deploy-check.json --out ./deterministic-game/artifacts/deterministic/project-deploy-check-verification.md --json ./deterministic-game/artifacts/deterministic/project-deploy-check-verification.json --junit ./deterministic-game/artifacts/deterministic/project-deploy-check-verification.xml
288
+ npm run project:ci-workflow -- --out .github/workflows/syncplay-ci.yml --json artifacts/reports/project-ci-workflow.json
289
+ npm run project:scaffold -- ./deterministic-h5 --name "H5 Arena" --template h5 --sdk-version ^0.8.0 --deterministic-version ^0.3.0
290
+ npm run project:check -- ./deterministic-h5/syncplay.project.json --require descriptor,assets,config,replay-runtime,creator-boundary,static-determinism --frames 32 --out-dir ./deterministic-h5/artifacts/deterministic --dist ./deterministic-h5/dist --out ./deterministic-h5/artifacts/deterministic/project-check-browser.md --json ./deterministic-h5/artifacts/deterministic/project-check-browser.json --junit ./deterministic-h5/artifacts/deterministic/project-check-browser.xml --release-json ./deterministic-h5/artifacts/deterministic/project-release-evidence-browser.json --browser-runtime chromium --browser-json ./deterministic-h5/artifacts/deterministic/project-browser-proof-chromium.json
291
+ npm run project:release-verify -- ./deterministic-h5/artifacts/deterministic/project-release-evidence-browser.json --require-browser-proof --json ./deterministic-h5/artifacts/deterministic/project-release-verification-browser.json
292
+ npm run project:release-bundle -- ./deterministic-h5/artifacts/deterministic/project-release-evidence-browser.json --require-browser-proof --json ./deterministic-h5/artifacts/deterministic/project-release-bundle-browser.json
293
+ npm run project:release-bundle-verify -- ./deterministic-h5/artifacts/deterministic/project-release-bundle-browser.json --out ./deterministic-h5/artifacts/deterministic/project-release-bundle-verification-browser.md --json ./deterministic-h5/artifacts/deterministic/project-release-bundle-verification-browser.json --junit ./deterministic-h5/artifacts/deterministic/project-release-bundle-verification-browser.xml
294
+ npm run project:deploy-check -- ./deterministic-h5/syncplay.project.json --require-browser-proof --bundle ./deterministic-h5/artifacts/deterministic/project-release-bundle-browser.json --out ./deterministic-h5/artifacts/deterministic/project-deploy-check.md --json ./deterministic-h5/artifacts/deterministic/project-deploy-check.json --junit ./deterministic-h5/artifacts/deterministic/project-deploy-check.xml
295
+ npm run project:deploy-check-verify -- ./deterministic-h5/artifacts/deterministic/project-deploy-check.json --out ./deterministic-h5/artifacts/deterministic/project-deploy-check-verification.md --json ./deterministic-h5/artifacts/deterministic/project-deploy-check-verification.json --junit ./deterministic-h5/artifacts/deterministic/project-deploy-check-verification.xml
296
+ npm run project:doctor -- ./deterministic-h5/syncplay.project.json --require-browser-proof --json ./deterministic-h5/artifacts/deterministic/project-doctor-ci.json --junit ./deterministic-h5/artifacts/deterministic/project-doctor-ci.xml
297
+ npm run --prefix ./deterministic-h5 build
298
+ npm run project:scaffold -- ./deterministic-systems --name "Systems Test" --template systems
299
+ npm run project:certify -- ./deterministic-systems/syncplay.project.json --require all --frames 12 --agents 4 --slots 1,2 --out-dir ./deterministic-systems/artifacts/deterministic --json ./deterministic-systems/artifacts/deterministic/project-certification-full.json
300
+ npm run project:summary -- ./deterministic-systems/artifacts/deterministic/project-certification-full.json --out ./deterministic-systems/artifacts/deterministic/project-certification-summary.md --json ./deterministic-systems/artifacts/deterministic/project-certification-summary.json
301
+ npm run project:certify -- ./deterministic-game/syncplay.project.json --require all --frames 128 --agents 128 --out-dir ./deterministic-game/artifacts/deterministic --json ./deterministic-game/artifacts/deterministic/project-certification-full.json
302
+ npm run certify:v1
303
+ npm run certify:v1 -- --json artifacts/certification/suite.json
304
+ npm run certify:v2 -- --profile required-full --json artifacts/certification/v2-full.json
305
+ npm run certify:v2 -- --profile chaos --json artifacts/certification/chaos.json --junit artifacts/certification/chaos.xml
306
+ npm run certify:v2 -- --profile chaos --filter resync --json artifacts/certification/chaos-resync.json
307
+ npm run certify:v2 -- --profile chaos --filter hostile --json artifacts/certification/chaos-hostile.json
308
+ npm run certify:v2 -- --profile chaos --filter rollback-boundary --json artifacts/certification/chaos-rollback-boundary.json
309
+ npm run certify:v2 -- --profile chaos --filter replay-identity --json artifacts/certification/chaos-replay-identity.json
310
+ npm run certify:v2 -- --profile chaos --filter commands --json artifacts/certification/chaos-commands.json
311
+ npm run certify:v2 -- --profile chaos --filter events --json artifacts/certification/chaos-events.json
312
+ npm run certify:v2 -- --profile chaos --filter input-policy --json artifacts/certification/chaos-input-policy.json
313
+ npm run certify:v2 -- --profile chaos --filter network --json artifacts/certification/chaos-network.json
314
+ npm run certify:v2 -- --profile chaos --filter random --json artifacts/certification/chaos-random.json
315
+ npm run certify:v2 -- --profile chaos --filter tick --json artifacts/certification/chaos-tick.json
316
+ npm run certify:v2 -- --profile chaos --filter assets --json artifacts/certification/chaos-assets.json
317
+ npm run certify:v2 -- --profile chaos --filter physics --json artifacts/certification/chaos-physics.json
318
+ npm run certify:v2 -- --profile chaos --filter movement --json artifacts/certification/chaos-movement.json
319
+ npm run certify:v2 -- --profile chaos --filter scale-128 --json artifacts/certification/chaos-scale-128.json
320
+ npm run certify:v2 -- --profile chaos --explain-fixture resync.snapshot-tail
321
+ npm run static:determinism -- --json artifacts/certification/static-determinism.json --junit artifacts/certification/static-determinism.xml
322
+ npm run test:pack-smoke
323
+ npm run certify:standalone-complete
324
+ npm run certify:engine-complete -- --players 128 --frames 5000 --seed 71 --json artifacts/certification/engine-complete.json --junit artifacts/certification/engine-complete.xml
325
+ npm run benchmark:engine-complete -- --players 128 --frames 100000 --seed 71 --enforce-thresholds --json artifacts/certification/engine-complete-stress.json --junit artifacts/certification/engine-complete-stress.xml
326
+ npm run certify:v2 -- --profile required-full --players 128 --frames 1000 --seed 71 --json artifacts/certification/engine-parity-required-full.json --junit artifacts/certification/engine-parity-required-full.xml
327
+ npm run benchmark:engine-parity -- --profile stress --players 128 --frames 100000 --seed 71 --json artifacts/certification/engine-parity-stress-100k.json --junit artifacts/certification/engine-parity-stress-100k.xml
328
+ npm run report:engine-parity-matrix:certified
329
+ npm run static:determinism -- --json artifacts/certification/static-engine-current.json
330
+ npm run certify:v2 -- --runtime chromium --filter browser-boundary --json artifacts/certification/engine-parity-v2-browser-runtime.json
331
+ npm run certify:v2 -- --stress --filter performance-128 --frames 1000 --json artifacts/certification/engine-parity-v2-stress-shortcut.json
332
+ npm run report:diff -- artifacts/certification/engine-parity-required-full.json artifacts/certification/engine-parity-stress-100k.json --max-differences 20 --json artifacts/certification/engine-parity-benchmark-diff.json
333
+ npm run check -- tests/fixtures/pass --strict
334
+ { npm run check -- tests/fixtures/fail --strict; test "$?" -eq 1; }
335
+
336
+ npm run lab:offline-replay -- --players 128 --frames 100000 --seed 3
337
+ npm run lab:offline-replay -- --players 4 --frames 1000 --seed 7 --out artifacts/replays/browser-p4-seed7.json
338
+ npm run lab:replay-inspect -- artifacts/replays/browser-p4-seed7.json --frame 120 --explain-checksum --out artifacts/reports/browser-p4-frame120.json
339
+ { npm run lab:replay-diff -- artifacts/replays/lab-p4-seed11.json artifacts/replays/lab-p4-seed12.json --frame 60 --max-differences 20 --json; test "$?" -eq 1; }
340
+ npm run build
341
+ npm run lab:replay-verify-browser -- artifacts/replays/browser-p4-seed7.json --runtime chromium
342
+ npm run lab:replay-verify-browser -- artifacts/replays/browser-p4-seed7.json --runtime webkit
343
+ npm run lab:protocol-rollback -- --players 128 --frames 1000 --seed 19 --min-delay 1 --max-delay 8 --duplicate-permille 100 --loss-permille 100 --resend-interval 9 --max-resend-attempts 14 --disconnect-start 100 --disconnect-end 130
344
+ npm run lab:protocol-rollback -- --players 8 --frames 300 --seed 47 --min-delay 1 --max-delay 6 --bundle-size 5 --json artifacts/reports/protocol-p8.json
345
+ npm run lab:protocol-rollback -- --players 4 --frames 120 --seed 57 --min-delay 1 --max-delay 5 --duplicate-permille 100 --event-timeline-limit 3
346
+ npm run lab:protocol-rollback -- --game counter-duel --players 4 --frames 300 --seed 53 --min-delay 1 --max-delay 7 --duplicate-permille 100 --json artifacts/reports/counter-duel-protocol-p4.json
347
+ npm run lab:netcode -- --shape input-minimal --players 128 --hz 10 --frames 1000 --rtt 200 --jitter 100 --loss 2 --duplicate-permille 100 --event-timeline-limit 0 --json artifacts/reports/netcode-p128-input-minimal.json
348
+ npm run lab:netcode -- --shape moderate-state --players 128 --hz 10 --frames 1000 --rtt 200 --jitter 100 --loss 2 --duplicate-permille 100 --event-timeline-limit 0 --json artifacts/reports/netcode-p128-moderate-state.json
349
+ npm run lab:netcode -- --shape command-bursts --players 128 --hz 10 --frames 1000 --rtt 200 --jitter 100 --loss 2 --duplicate-permille 100 --event-timeline-limit 0 --json artifacts/reports/netcode-p128-command-bursts.json
350
+ npm run lab:prediction-culling -- --mode off --players 128 --objects-per-player 8 --frames 1000 --seed 19 --radius 180 --json artifacts/reports/prediction-culling-off-p128.json
351
+ npm run lab:prediction-culling -- --mode local-area --players 128 --objects-per-player 8 --frames 1000 --seed 19 --radius 180 --json artifacts/reports/prediction-culling-local-area-p128.json
352
+ npm run lab:netcode -- --shape moderate-state --players 128 --hz 10 --frames 1000 --rtt 200 --jitter 100 --loss 2 --duplicate-permille 100 --prediction-culling local-area --objects-per-player 8 --prediction-radius 180 --event-timeline-limit 0 --json artifacts/reports/netcode-p128-moderate-state-culling.json
353
+ npm run lab:local-ws-server -- --port 9301 &
354
+ server_pid=$!
355
+ trap 'kill $server_pid' EXIT
356
+ npm run lab:wait-for-url -- --url http://127.0.0.1:9301/health --timeout-ms 10000
357
+ npm run lab:ws-adapter-test -- --url ws://127.0.0.1:9301/protocol --players 4 --frames 120 --seed 17 --min-delay 1 --max-delay 5 --loss-permille 10 --duplicate-permille 100
358
+ npm run lab:r3f-render-adapter -- --players 4 --frames 120 --seed 9
359
+ { npm run lab:venus-mp-budget -- --players 128 --hz 30 --frames-per-message 1 --max-players 10 --json; test "$?" -eq 1; }
360
+ npm run lab:venus-mp-budget -- --players 128 --hz 30 --frames-per-message 3 --max-players 128 --json
361
+ npm run lab:physics-cert -- --engine builtin-fixed --shape fixed-arena --players 8 --frames 1000 --seed 7 --snapshot-every 1 --json artifacts/reports/physics-builtin-fixed-arena-p8.json
362
+ npm run lab:physics-cert -- --engine builtin-fixed --shape slot-load --players 128 --frames 1000 --seed 11 --snapshot-every 8 --json artifacts/reports/physics-builtin-slot-load-p128.json
363
+ { npm run lab:physics-cert -- --engine rapier2d-compat --shape fixed-arena --players 4 --frames 60 --seed 17 --snapshot-every 2 --json artifacts/reports/physics-rapier2d-compat-known-fail.json; test "$?" -eq 1; }
364
+ npm run lab:number -- --mode fixed-q16 --frames 100000 --seed 7
365
+ npm run lab:number-browser -- --mode fixed-q16 --frames 100000 --seed 7 --runtime chromium --json artifacts/certification/number-fixed-q16-chromium.json
366
+ npm run lab:number-browser -- --mode integer --frames 100000 --seed 7 --runtime chromium --json artifacts/certification/number-integer-chromium.json
367
+ npm run lab:number-browser -- --mode fixed-q16 --frames 100000 --seed 7 --runtime webkit --json artifacts/certification/number-fixed-q16-webkit.json
368
+ npm run lab:number-browser -- --mode integer --frames 100000 --seed 7 --runtime webkit --json artifacts/certification/number-integer-webkit.json
369
+ npm run lab:replay-verify-browser -- artifacts/replays/browser-p4-seed7.json --runtime chromium --playwright-module /tmp/rdm-missing-playwright --json artifacts/certification/browser-replay-skip-proof.json
370
+ npm run lab:number-browser -- --mode fixed-q16 --frames 10 --seed 7 --runtime chromium --playwright-module /tmp/rdm-missing-playwright --json artifacts/certification/number-browser-skip-proof.json
371
+ npm run example:counter-duel -- --players 4 --frames 300 --seed 3 --verify --out artifacts/replays/counter-duel-p4.json --json artifacts/reports/counter-duel-p4.json
372
+ npm run example:fixed-arena -- --players 128 --frames 240 --seed 19 --verify --out artifacts/replays/fixed-arena-p128.json --json artifacts/reports/fixed-arena-p128.json
373
+ npm run schema:validate -- tests/fixtures/descriptors/pass
374
+ npm run schema:dump -- tests/fixtures/descriptors/pass/counter-duel.json --state tests/fixtures/descriptors/state/counter-duel-state.json --frame 42 --out artifacts/reports/counter-duel-schema-frame42.json
375
+ npm run schema:types -- tests/fixtures/descriptors/pass/counter-duel.json --name CounterDuel --out artifacts/reports/counter-duel-types.ts
376
+ npm run schema:binary -- tests/fixtures/descriptors/pass/counter-duel.json --name CounterDuel --out artifacts/reports/counter-duel-binary.ts --json artifacts/reports/counter-duel-binary.json
377
+ cd ../../server/mp-room-server && npm run build
378
+ cd ../../server/mp-room-server && npm test -- --run src/rooms/deterministicMultiplayerRoom.integration.test.ts
379
+ cd ../../server/mp-room-server && npm test -- --run src/routes/deterministicTicketsGateway.integration.test.ts
380
+ ```
381
+
382
+ Generated project scaffolds include a `.gitignore` for `node_modules/`, `dist/`,
383
+ and generated `artifacts/`; keep certification/release evidence with CI logs
384
+ unless your project has a separate artifact archive policy.
385
+
386
+ ## Report Schema
387
+
388
+ All CLI reports are stable JSON intended for terminal review and CI parsing.
389
+ Certification reports include `schemaVersion`, `result`, `failures`, category or
390
+ fixture records, invariant maps, metrics, checksums, and profile/seed/frame
391
+ identity. Replay reports include aggregate file/frame/checksum counts plus
392
+ per-file mismatch records. Asset-cook reports include per-file expected/actual
393
+ outcomes, stable asset DB hashes, schema hashes, dependency hashes, lookup
394
+ hashes, stable dependency ordering, stable recook checks, prototype-spawn
395
+ checks, and stale manifest rejection checks.
396
+
397
+ TypeScript report types are exported for certification, chaos certification,
398
+ Engine-parity certification, protocol rollback reports, replay inspect/diff
399
+ reports, asset cooking, static determinism suppressions, and generic report
400
+ diffs. Use `report:diff` for category-level artifact regression review and
401
+ `lab:replay-diff` for frame-level replay state diffs.
402
+
403
+ ## Asset Cooking
404
+
405
+ `cook:syncplay-assets -- --verify fixtures/assets --json <path>` cooks every
406
+ valid asset fixture and expects every invalid fixture to fail. The command proves
407
+ byte-stable recooking under reordered source assets, stable asset DB and lookup
408
+ hashes, stable schema hashes, stable dependency hashes, deterministic dependency
409
+ ordering, prototype spawn identity, duplicate ID rejection, unresolved reference
410
+ rejection, unquantized float rejection, schema mismatch rejection,
411
+ nondeterministic dependency rejection, stale engine rejection, and stale asset
412
+ database hash rejection.
413
+
414
+ Runtime code can call `cookDeterministicAssets`,
415
+ `materializePrototypeEntities`, and `assertAssetManifestMatches` directly. Asset
416
+ manifests should be treated as replay identity inputs: changing the asset DB
417
+ hash or deterministic asset engine version invalidates old replays unless a
418
+ migration explicitly maps the old identity to the new one.
419
+
420
+ ## Replay Debugging
421
+
422
+ `replay:verify` verifies single replay files or directories, supports frame
423
+ ranges, emits aggregate and per-file mismatch counts, and returns first-mismatch
424
+ diagnostics. `lab:offline-replay` can export small replay artifacts for browser
425
+ or debugger use and refuses oversized materialized transcripts; use metrics-only
426
+ long runs for 128-player/100,000-frame stress proofs. `lab:replay-inspect`
427
+ dumps a stable frame state, and `lab:replay-diff` emits capped state-path
428
+ differences between two replay frames.
429
+
430
+ Snapshot-tail reconstruction is covered by chaos certification for late
431
+ spectator, killcam, and resync-style workflows. Corrupted replay fixtures under
432
+ `fixtures/replays/corrupt` are expected failures and must stay deterministic.
433
+
434
+ ## Static Determinism
435
+
436
+ `static:determinism` runs the static checker against known-good package fixtures
437
+ and known-bad fixtures, writes JSON and JUnit, and fails if package source emits
438
+ strict errors or if known-bad fixtures stop failing. Diagnostics include
439
+ remediation text. Valid suppressions must use
440
+ `// rdm-ignore-next-line <rule-id>: <reason>` and are reported with file, line,
441
+ rule, and reason; invalid suppressions are errors.
442
+
443
+ The checker covers host random/time, timers, async simulation work, I/O,
444
+ unordered object iteration, random sort comparators, render-object mutation,
445
+ uncertified physics stepping, and descriptor-declared state-field access.
446
+
447
+ ## Browser Certification
448
+
449
+ Browser replay and number labs run through Playwright when the requested browser
450
+ runtime is available. Chromium pass artifacts are required when Chromium is
451
+ installed; WebKit writes either a pass artifact or an explicit skip artifact.
452
+ Standalone provisioning can pass `--playwright-module`; missing tooling writes
453
+ clean skip artifacts instead of fabricating checksum or value matches.
454
+
455
+ The optional browser profile checks package and SDK-facing browser-safe exports
456
+ for Node-only module imports, filesystem APIs, local server APIs, and
457
+ certification-only APIs. Node WebSocket helpers remain available only through
458
+ the `./node` subpath. V2 certification accepts `--runtime node|chromium|webkit`
459
+ and records the selected runtime in the suite and category reports; actual
460
+ browser execution remains in the browser replay and number lab commands.
461
+
462
+ ## Performance And Stress
463
+
464
+ `benchmark:engine-parity` emits diffable 128-player metrics for input-minimal,
465
+ moderate-state, protocol, bot, projectile/sample, replay, and performance
466
+ workloads. Timing thresholds are reported but non-blocking unless
467
+ `--enforce-thresholds` is set. The opt-in stress profile supports
468
+ 100,000-frame/128-player runs and fails on desync, missing rollback history, or
469
+ corrupted replay output. `certify:v2 -- --stress` is a shortcut for selecting
470
+ the stress profile when no explicit `--profile` is provided.
471
+
472
+ Use the generated benchmark and stress artifacts with `report:diff` to review
473
+ regressions from the terminal. Long stress runs should stay opt-in for local and
474
+ CI workflows unless a separate CI policy requires them.
475
+
476
+ Use `certify:standalone-complete` to refresh the standalone proof contract in
477
+ the required order. It regenerates `engine-complete`,
478
+ `engine-complete-stress`, `engine-parity-required-full`,
479
+ `engine-parity-stress-100k`, the evidence-backed parity matrix, and the static
480
+ determinism audit. Use `report:engine-parity-matrix:certified` after refreshing
481
+ individual artifacts manually; it loads evidence from
482
+ `artifacts/certification`, enforces zero required CLI-verifiable gaps, and
483
+ writes the canonical `engine-parity-matrix.json` artifact consumed by
484
+ `static:determinism`.
485
+
486
+ ## Parity Claims
487
+
488
+ The parity claim is standalone, headless, CLI-verifiable deterministic
489
+ multiplayer parity for the locally provable deterministic engine engine capabilities:
490
+ rollback, replay, fixed numerics, deterministic authoring checks, asset
491
+ cooking, protocol delay/fault handling, browser runtime parity, and 128-player
492
+ stress readiness.
493
+
494
+ This does not include Venus MP integration, production backend certification,
495
+ or renderer/r3f parity. Working with third-party game engines is not a goal. Navigation
496
+ and bot parity are headless exported runtime primitives, not external engine
497
+ project importers, visual editors, production cloud services, or polished
498
+ creator-facing sample scenes.
499
+
500
+ ## Chaos Certification
501
+
502
+ The chaos profile is CLI-only and standalone. It does not use Venus MP, Cloud
503
+ Run, Firebase, r3f, browser rendering, or production room servers. It is meant
504
+ to prove rollback/resync protocol behavior before external adapters make
505
+ failures harder to isolate.
506
+
507
+ Chaos fixtures are nested under the normal `certify:v2` report model as a
508
+ single `chaos` category. Each fixture has a stable `fixtureId`, `category`,
509
+ `expectedResult`, seed, players, frames, network model, invariant map, metrics,
510
+ artifact path, checksum, and result. `expected-failure` means the fixture passes
511
+ only when the bad input, corrupted replay, evicted rollback history, or config
512
+ mismatch is detected deterministically.
513
+
514
+ Fixture categories are `resync`, `hostile`, `rollback-boundary`,
515
+ `replay-identity`, `commands`, `events`, `input-policy`, `network`, `random`,
516
+ `tick`, `assets`, `physics`, `movement`, and `scale-128`. Use `--filter` with
517
+ any category or fixture id to run a focused subset. Use `--explain-fixture` to
518
+ print what a fixture proves, its expected result mode, artifact path, and pass
519
+ invariants.
520
+
521
+ `static:determinism` remains the prerequisite source-text lint proof for chaos
522
+ certification. The chaos profile intentionally focuses on runtime protocol,
523
+ replay, rollback, and asset/config behavior rather than duplicating static
524
+ analysis.
525
+
526
+ Use `report:diff` for benchmark, certification, and chaos JSON artifacts. It
527
+ compares stable report JSON by path, emits capped differences, and exits
528
+ nonzero when reports differ. Use `lab:replay-diff` for frame-level replay state
529
+ diffs.
530
+
531
+ ## r3f Boundary
532
+
533
+ r3f is a view layer for this package. Simulation state remains plain
534
+ checksummed data, the r3f adapter projects a frozen render frame, and React
535
+ components render that frame without mutating session state.
536
+
537
+ Input should be captured in DOM/r3f/UI code, normalized through
538
+ `bindInput(slot, normalize)`, and submitted as descriptor-shaped deterministic
539
+ input before the next fixed tick. React render timing, Three.js objects,
540
+ materials, vectors, and interpolation floats stay outside replay checksums.
541
+
542
+ ## Known Gaps
543
+
544
+ - Browser replay verification passes locally in Chromium and WebKit for the lab
545
+ replay when Playwright browser runtimes are available. The optional browser
546
+ profile also checks that package and SDK-facing browser-safe exports exclude
547
+ Node-only modules, local servers, filesystem APIs, and certification-only APIs.
548
+ Browser replay and browser number labs accept `--playwright-module` for
549
+ standalone provisioning tests and emit explicit skip artifacts when Playwright
550
+ is unavailable.
551
+ Package-local fixtures under `fixtures/assets`, `fixtures/replays`,
552
+ `fixtures/static`, and `fixtures/browser-safe` are the reusable corpus for
553
+ asset cooking, replay verification, static determinism, and browser-boundary
554
+ certification.
555
+ `tests/apps/android-webview-deterministic` currently provides an Android
556
+ WebView APK harness, but Android emulator/logcat verification is not part of
557
+ the required local proof set.
558
+ - Vite plugin/config helpers intentionally use structural Vite-compatible types
559
+ instead of importing Vite, so creator projects can gate builds without a Vite
560
+ peer dependency from the deterministic package.
561
+ - Static checker can optionally load a descriptor and fail strict mode for
562
+ undeclared `state.foo`/`state["foo"]` references in simulation code.
563
+ - Schema descriptors validate shape and identity, produce schema-aware
564
+ serializers/deserializers and frame dumps, and generate TypeScript types plus
565
+ default input factories. `schema:binary` emits separate descriptor-derived
566
+ binary serializer source with an embedded schema hash and round-trip proof.
567
+ - Replay inspect/diff and `verifyReplayWithDescriptor` support descriptor-backed
568
+ arbitrary game replays when the caller supplies the game step/default input.
569
+ - Protocol rollback reports include bounded event timeline summaries, and
570
+ generic r3f/audio/UI/custom effect consumers can read frozen event payloads.
571
+ - The r3f-compatible adapter is verified as a render boundary, Fixed Arena
572
+ exports a creator-facing r3f reference view model, and the SDK test-app
573
+ renders that view in a visual sample.
574
+ - Prediction culling is a local AOI execution lab, not a production-optimized
575
+ partial resimulation scheduler yet.
576
+ - Reference sample certification is headless mechanics coverage, not polished
577
+ creator-facing r3f sample scenes yet.
578
+ - Sample-scene fixtures expose reusable headless mechanics counters for CLI
579
+ certification. They are not polished game templates, rendered examples, or
580
+ creator-facing r3f scenes yet.
581
+ - Navigation primitives include cooked graph assets, A*, regions, blockers,
582
+ off-mesh links, flow fields, tilemap graphs, and deterministic agent stepping.
583
+ They do not yet include deterministic navmesh import/baking from DCC or r3f
584
+ scene geometry.
585
+ - Bot primitives include typed blackboards, HFSM, Behavior Tree, Utility
586
+ selection, deterministic asset hashes, and rollback tests. They do not yet
587
+ include a visual bot authoring editor or creator-facing bot asset pipeline.
588
+ - Movement primitives cover the CLI-verifiable mechanics needed by platformer,
589
+ top-down, simple-FPS, and 3D KCC fixtures, including rollback-safe capsule
590
+ movement, slopes, steps, moving platforms, and physics queries. They do not
591
+ yet include authored r3f scene collision import or visual controller tooling.
592
+ - `mp-room-server` compatibility currently proves worker harness and
593
+ `RoomManager` behavior, direct `TicketStore` `/ws` auth, and mocked-auth
594
+ POST `/tickets` ticket minting. SDK transport compatibility proves public
595
+ `WsMultiplayerApi` deterministic input/confirmation traffic plus forced
596
+ reconnect with a fresh ticket. Gateway negative-path coverage proves expired
597
+ tickets, unauthenticated deterministic messages, auth timeout, stale socket
598
+ replacement, and server pre-timeout reconnect instructions. When Firebase
599
+ Auth and Firestore emulators are configured, the optional Firebase integration
600
+ test covers Auth ID-token verification and Firestore `profiles/{uid}` lookup
601
+ through the same POST `/tickets` and `/ws` deterministic gateway path.
602
+ - Built-in fixed physics certification includes package-local 2D/2.5D and 3D
603
+ deterministic worlds with sensors/triggers, queries, layer masks, callbacks,
604
+ constraints, CCD helpers, boxes, spheres, capsules, mesh static bounds,
605
+ deterministic angular state, and 128/512/2048-body stress samples. Remaining
606
+ limits are production-grade stacked rigid-body solving, visual collision
607
+ authoring/import, and replacing external physics engines; Rapier cert
608
+ currently fails with `knownIssueRapier910=reproduced`,
609
+ `uninterruptedChecksum=916fe725ae2e3215`, and
610
+ `restoredChecksum=9e42622842bffff6`.