@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
@@ -0,0 +1,89 @@
1
+ import { type CanonicalValue } from './canonical.js';
2
+ import { type DeterministicAssetCookResult, type DeterministicAssetSource } from './asset-cooking.js';
3
+ export interface DeterministicConfigBundleSource {
4
+ readonly version: number;
5
+ readonly engineHash: string;
6
+ readonly schemaHash: string;
7
+ readonly sessionConfig: Readonly<Record<string, CanonicalValue>>;
8
+ readonly simulationConfig: Readonly<Record<string, CanonicalValue>>;
9
+ readonly runtimeConfig: Readonly<Record<string, CanonicalValue>>;
10
+ readonly playerConfig: Readonly<Record<string, CanonicalValue>>;
11
+ readonly assets: DeterministicAssetSource;
12
+ readonly migrations?: readonly DeterministicConfigMigration[];
13
+ }
14
+ export interface DeterministicConfigMigration {
15
+ readonly fromVersion: number;
16
+ readonly toVersion: number;
17
+ readonly renameKeys?: Readonly<Record<string, string>>;
18
+ readonly renameSessionKeys?: Readonly<Record<string, string>>;
19
+ readonly renameSimulationKeys?: Readonly<Record<string, string>>;
20
+ readonly renameRuntimeKeys?: Readonly<Record<string, string>>;
21
+ readonly renamePlayerKeys?: Readonly<Record<string, string>>;
22
+ readonly renamePrototypeComponentKeys?: Readonly<Record<string, string>>;
23
+ }
24
+ export interface CookedDeterministicConfigBundle {
25
+ readonly version: number;
26
+ readonly engineHash: string;
27
+ readonly schemaHash: string;
28
+ readonly assetDbHash: string;
29
+ readonly configHash: string;
30
+ readonly bytes: string;
31
+ readonly assets: DeterministicAssetCookResult;
32
+ readonly prototypeCount: number;
33
+ readonly migrationResult: 'none' | 'migrated';
34
+ }
35
+ export interface DeterministicConfigBundleVerification {
36
+ readonly result: 'pass' | 'fail';
37
+ readonly configHash: string;
38
+ readonly assetDbHash: string;
39
+ readonly prototypeCount: number;
40
+ readonly materializedEntityCount: number;
41
+ readonly migrationResult: 'none' | 'migrated';
42
+ readonly failure?: string;
43
+ }
44
+ export interface DeterministicConfigBundleParityMetrics {
45
+ readonly result: 'pass' | 'fail';
46
+ readonly version: number;
47
+ readonly targetVersion: number;
48
+ readonly configHash: string;
49
+ readonly assetDbHash: string;
50
+ readonly prototypeCount: number;
51
+ readonly materializedEntityCount: number;
52
+ readonly migrationResult: 'none' | 'migrated';
53
+ readonly byteStable: boolean;
54
+ readonly staleEngineRejected: boolean;
55
+ readonly staleSchemaRejected: boolean;
56
+ readonly staleConfigRejected: boolean;
57
+ readonly staleAssetDbRejected: boolean;
58
+ readonly tamperedConfigBytesRejected: boolean;
59
+ readonly tamperedAssetBytesRejected: boolean;
60
+ readonly unsupportedFloatRejected: boolean;
61
+ readonly prototypeMaterializationStable: boolean;
62
+ readonly inheritedPrototypeMaterialized: boolean;
63
+ readonly dynamicCollectionsMaterialized: boolean;
64
+ readonly mapMaterializationStable: boolean;
65
+ readonly mapRebakeInvalidated: boolean;
66
+ readonly mapMaterializedEntityCount: number;
67
+ readonly mapBakeHash: string;
68
+ readonly failureReasons: Readonly<Record<string, string>>;
69
+ readonly checksum: string;
70
+ }
71
+ export interface DeterministicConfigBundleFailureReasonInputs {
72
+ readonly staleEngine: DeterministicConfigBundleVerification;
73
+ readonly staleSchema: DeterministicConfigBundleVerification;
74
+ readonly staleConfig: DeterministicConfigBundleVerification;
75
+ readonly staleAssetDb: DeterministicConfigBundleVerification;
76
+ readonly tamperedConfigBytes: DeterministicConfigBundleVerification;
77
+ readonly tamperedAssetBytes: DeterministicConfigBundleVerification;
78
+ }
79
+ export declare function cookDeterministicConfigBundle(source: DeterministicConfigBundleSource, targetVersion?: number): CookedDeterministicConfigBundle;
80
+ export declare function verifyDeterministicConfigBundle(bundle: CookedDeterministicConfigBundle, expected: {
81
+ readonly engineHash: string;
82
+ readonly schemaHash: string;
83
+ readonly configHash?: string;
84
+ readonly assetDbHash?: string;
85
+ }): DeterministicConfigBundleVerification;
86
+ export declare function runDeterministicConfigBundleFixture(): DeterministicConfigBundleVerification;
87
+ export declare function runDeterministicConfigBundleParityFixture(): DeterministicConfigBundleParityMetrics;
88
+ export declare function summarizeDeterministicConfigBundleFailureReasons(inputs: DeterministicConfigBundleFailureReasonInputs): Readonly<Record<keyof DeterministicConfigBundleFailureReasonInputs, string>>;
89
+ export declare function evaluateDeterministicConfigBundleParityResult(verification: DeterministicConfigBundleVerification, invariantChecks: readonly boolean[]): 'pass' | 'fail';
@@ -0,0 +1,483 @@
1
+ import { canonicalStringify, cloneCanonical, defaultChecksum } from './canonical.js';
2
+ import { cookDeterministicAssets, materializeDeterministicMapEntities, materializePrototypeEntities, } from './asset-cooking.js';
3
+ export function cookDeterministicConfigBundle(source, targetVersion = source.version) {
4
+ const migrated = migrateConfigBundle(source, targetVersion);
5
+ validateConfigSource(migrated);
6
+ const assets = cookDeterministicAssets(migrated.assets);
7
+ const payload = {
8
+ version: migrated.version,
9
+ engineHash: migrated.engineHash,
10
+ schemaHash: migrated.schemaHash,
11
+ sessionConfig: cloneCanonical(migrated.sessionConfig),
12
+ simulationConfig: cloneCanonical(migrated.simulationConfig),
13
+ runtimeConfig: cloneCanonical(migrated.runtimeConfig),
14
+ playerConfig: cloneCanonical(migrated.playerConfig),
15
+ assetDbHash: assets.manifest.assetDbHash,
16
+ };
17
+ const bytes = canonicalStringify(payload);
18
+ return {
19
+ version: migrated.version,
20
+ engineHash: migrated.engineHash,
21
+ schemaHash: migrated.schemaHash,
22
+ assetDbHash: assets.manifest.assetDbHash,
23
+ configHash: defaultChecksum(bytes),
24
+ bytes,
25
+ assets,
26
+ prototypeCount: assets.manifest.prototypeIds.length,
27
+ migrationResult: migrated.version === source.version ? 'none' : 'migrated',
28
+ };
29
+ }
30
+ export function verifyDeterministicConfigBundle(bundle, expected) {
31
+ const identityFailure = verifyConfigBundleIdentity(bundle);
32
+ const materializedEntityCount = identityFailure === undefined ? materializedEntityCountOrUndefined(bundle) : undefined;
33
+ const base = {
34
+ configHash: bundle.configHash,
35
+ assetDbHash: bundle.assetDbHash,
36
+ prototypeCount: bundle.prototypeCount,
37
+ materializedEntityCount: materializedEntityCount ?? 0,
38
+ migrationResult: bundle.migrationResult,
39
+ };
40
+ if (identityFailure !== undefined) {
41
+ return { ...base, result: 'fail', failure: identityFailure };
42
+ }
43
+ if (materializedEntityCount === undefined) {
44
+ return { ...base, result: 'fail', failure: 'prototype-materialization-mismatch' };
45
+ }
46
+ if (bundle.engineHash !== expected.engineHash) {
47
+ return { ...base, result: 'fail', failure: 'stale-engine-hash' };
48
+ }
49
+ if (bundle.schemaHash !== expected.schemaHash) {
50
+ return { ...base, result: 'fail', failure: 'stale-schema-hash' };
51
+ }
52
+ if (expected.configHash !== undefined && bundle.configHash !== expected.configHash) {
53
+ return { ...base, result: 'fail', failure: 'stale-config-hash' };
54
+ }
55
+ if (expected.assetDbHash !== undefined && bundle.assetDbHash !== expected.assetDbHash) {
56
+ return { ...base, result: 'fail', failure: 'stale-asset-db-hash' };
57
+ }
58
+ return { ...base, result: 'pass' };
59
+ }
60
+ function materializedEntityCountOrUndefined(bundle) {
61
+ try {
62
+ return bundle.assets.manifest.prototypeIds.reduce((sum, id) => sum + materializePrototypeEntities(bundle.assets, id, 1).length, 0);
63
+ }
64
+ catch {
65
+ return undefined;
66
+ }
67
+ }
68
+ function verifyConfigBundleIdentity(bundle) {
69
+ if (defaultChecksum(bundle.bytes) !== bundle.configHash) {
70
+ return 'config-bytes-hash-mismatch';
71
+ }
72
+ const payload = parseJsonOrUndefined(bundle.bytes);
73
+ if (!isRecord(payload)) {
74
+ return 'config-bytes-payload-invalid';
75
+ }
76
+ if (payload.version !== bundle.version) {
77
+ return 'config-bytes-version-mismatch';
78
+ }
79
+ if (payload.engineHash !== bundle.engineHash) {
80
+ return 'config-bytes-engine-hash-mismatch';
81
+ }
82
+ if (payload.schemaHash !== bundle.schemaHash) {
83
+ return 'config-bytes-schema-hash-mismatch';
84
+ }
85
+ if (payload.assetDbHash !== bundle.assetDbHash) {
86
+ return 'config-bytes-asset-db-hash-mismatch';
87
+ }
88
+ if (!isRecord(payload.sessionConfig)) {
89
+ return 'config-bytes-session-config-mismatch';
90
+ }
91
+ if (!isRecord(payload.simulationConfig)) {
92
+ return 'config-bytes-simulation-config-mismatch';
93
+ }
94
+ if (!isRecord(payload.runtimeConfig)) {
95
+ return 'config-bytes-runtime-config-mismatch';
96
+ }
97
+ if (!isRecord(payload.playerConfig)) {
98
+ return 'config-bytes-player-config-mismatch';
99
+ }
100
+ const assetPayload = parseJsonOrUndefined(bundle.assets.bytes);
101
+ if (assetPayload === undefined || canonicalStringify(assetPayload) !== bundle.assets.bytes) {
102
+ return 'asset-bytes-canonical-mismatch';
103
+ }
104
+ if (canonicalStringify(assetPayload) !== canonicalStringify({ manifest: bundle.assets.manifest, assets: bundle.assets.cookedAssets })) {
105
+ return 'asset-bytes-content-mismatch';
106
+ }
107
+ const cookedAssetHashes = bundle.assets.cookedAssets.map((asset) => ({
108
+ id: asset.id,
109
+ type: asset.type,
110
+ hash: defaultChecksum({ id: asset.id, data: asset.data }),
111
+ }));
112
+ if (canonicalStringify(cookedAssetHashes) !== canonicalStringify(bundle.assets.manifest.assets)) {
113
+ return 'asset-manifest-entry-mismatch';
114
+ }
115
+ const recomputedAssetDbHash = defaultChecksum({
116
+ engineVersion: bundle.assets.manifest.engineVersion,
117
+ schemaHash: bundle.assets.manifest.schemaHash,
118
+ dependencyHash: bundle.assets.manifest.dependencyHash,
119
+ dependencies: bundle.assets.manifest.dependencies,
120
+ cookedAssets: bundle.assets.cookedAssets,
121
+ });
122
+ if (recomputedAssetDbHash !== bundle.assetDbHash || recomputedAssetDbHash !== bundle.assets.manifest.assetDbHash) {
123
+ return 'asset-db-hash-mismatch';
124
+ }
125
+ if (bundle.prototypeCount !== bundle.assets.manifest.prototypeIds.length) {
126
+ return 'prototype-count-mismatch';
127
+ }
128
+ if (bundle.assets.manifest.assetCount !== bundle.assets.cookedAssets.length) {
129
+ return 'asset-count-mismatch';
130
+ }
131
+ return undefined;
132
+ }
133
+ function parseJsonOrUndefined(value) {
134
+ try {
135
+ return JSON.parse(value);
136
+ }
137
+ catch {
138
+ return undefined;
139
+ }
140
+ }
141
+ export function runDeterministicConfigBundleFixture() {
142
+ const bundle = cookDeterministicConfigBundle({
143
+ version: 1,
144
+ engineHash: 'engine@1',
145
+ schemaHash: 'schema@1',
146
+ sessionConfig: { tickRate: 60, players: 128 },
147
+ simulationConfig: { numericModeV1: 'fixed', rollback: true },
148
+ runtimeConfig: { maxRollbackFrames: 12 },
149
+ playerConfig: { defaultTeam: 'blue' },
150
+ assets: {
151
+ schemaVersion: 1,
152
+ engineVersion: 'engine@1',
153
+ assets: [
154
+ { id: 'material.default', type: 'physics-material', friction: 1, restitution: 0 },
155
+ { id: 'player.prototype', type: 'prototype', prototype: true, references: ['material.default'], components: { hp: 100, speed: 12 } },
156
+ ],
157
+ },
158
+ migrations: [{ fromVersion: 1, toVersion: 2, renameKeys: { numericModeV1: 'numericMode' } }],
159
+ }, 2);
160
+ return verifyDeterministicConfigBundle(bundle, {
161
+ engineHash: 'engine@1',
162
+ schemaHash: 'schema@1',
163
+ configHash: bundle.configHash,
164
+ assetDbHash: bundle.assetDbHash,
165
+ });
166
+ }
167
+ export function runDeterministicConfigBundleParityFixture() {
168
+ const source = createConfigBundleParitySource();
169
+ const targetVersion = 2;
170
+ const bundle = cookDeterministicConfigBundle(source, targetVersion);
171
+ const repeated = cookDeterministicConfigBundle(source, targetVersion);
172
+ const verification = verifyDeterministicConfigBundle(bundle, {
173
+ engineHash: 'engine@1',
174
+ schemaHash: 'schema@1',
175
+ configHash: bundle.configHash,
176
+ assetDbHash: bundle.assetDbHash,
177
+ });
178
+ const staleEngine = verifyDeterministicConfigBundle(bundle, {
179
+ engineHash: 'engine@old',
180
+ schemaHash: 'schema@1',
181
+ });
182
+ const staleSchema = verifyDeterministicConfigBundle(bundle, {
183
+ engineHash: 'engine@1',
184
+ schemaHash: 'schema@old',
185
+ });
186
+ const staleConfig = verifyDeterministicConfigBundle(bundle, {
187
+ engineHash: 'engine@1',
188
+ schemaHash: 'schema@1',
189
+ configHash: 'stale-config',
190
+ });
191
+ const staleAssetDb = verifyDeterministicConfigBundle(bundle, {
192
+ engineHash: 'engine@1',
193
+ schemaHash: 'schema@1',
194
+ assetDbHash: 'stale-asset-db',
195
+ });
196
+ const tamperedConfigBytes = verifyDeterministicConfigBundle({
197
+ ...bundle,
198
+ bytes: canonicalStringify({ tampered: true }),
199
+ }, {
200
+ engineHash: 'engine@1',
201
+ schemaHash: 'schema@1',
202
+ });
203
+ const tamperedAssetBytes = verifyDeterministicConfigBundle({
204
+ ...bundle,
205
+ assets: {
206
+ ...bundle.assets,
207
+ bytes: canonicalStringify({ manifest: bundle.assets.manifest, assets: [] }),
208
+ },
209
+ }, {
210
+ engineHash: 'engine@1',
211
+ schemaHash: 'schema@1',
212
+ });
213
+ const unsupportedFloatRejected = throws(() => cookDeterministicConfigBundle({
214
+ ...source,
215
+ sessionConfig: { ...source.sessionConfig, badFloat: 1.5 },
216
+ }, targetVersion));
217
+ const validConfigAccepted = !throws(() => cookDeterministicConfigBundle(source, targetVersion));
218
+ const materializedA = materializePrototypeEntities(bundle.assets, 'player.prototype', 2);
219
+ const materializedB = materializePrototypeEntities(bundle.assets, 'player.prototype', 2);
220
+ const inherited = materializePrototypeEntities(bundle.assets, 'player.prototype', 1, {
221
+ componentOverrides: { Loadout: { slot: 7 } },
222
+ });
223
+ const inheritedComponents = inherited[0]?.components;
224
+ const map = materializeDeterministicMapEntities(bundle.assets, 'map.arena');
225
+ const mapRepeat = materializeDeterministicMapEntities(repeated.assets, 'map.arena');
226
+ const rebaked = materializeDeterministicMapEntities(cookDeterministicConfigBundle({
227
+ ...source,
228
+ assets: {
229
+ ...source.assets,
230
+ assets: source.assets.assets.map((asset) => asset.id === 'map.arena'
231
+ ? { ...asset, spawns: [{ prototypeRef: 'player.prototype', count: 3, startEntityId: 100, overrides: { hp: 80 } }] }
232
+ : asset),
233
+ },
234
+ }, targetVersion).assets, 'map.arena');
235
+ const failureReasons = {
236
+ ...summarizeDeterministicConfigBundleFailureReasons({
237
+ staleEngine,
238
+ staleSchema,
239
+ staleConfig,
240
+ staleAssetDb,
241
+ tamperedConfigBytes,
242
+ tamperedAssetBytes,
243
+ }),
244
+ };
245
+ const withoutChecksum = {
246
+ version: source.version,
247
+ targetVersion,
248
+ configHash: bundle.configHash,
249
+ assetDbHash: bundle.assetDbHash,
250
+ prototypeCount: bundle.prototypeCount,
251
+ materializedEntityCount: verification.materializedEntityCount,
252
+ migrationResult: bundle.migrationResult,
253
+ byteStable: bundle.configHash === repeated.configHash && bundle.assetDbHash === repeated.assetDbHash && bundle.bytes === repeated.bytes,
254
+ staleEngineRejected: staleEngine.failure === 'stale-engine-hash',
255
+ staleSchemaRejected: staleSchema.failure === 'stale-schema-hash',
256
+ staleConfigRejected: staleConfig.failure === 'stale-config-hash',
257
+ staleAssetDbRejected: staleAssetDb.failure === 'stale-asset-db-hash',
258
+ tamperedConfigBytesRejected: tamperedConfigBytes.failure === 'config-bytes-hash-mismatch',
259
+ tamperedAssetBytesRejected: tamperedAssetBytes.failure === 'asset-bytes-content-mismatch',
260
+ unsupportedFloatRejected,
261
+ prototypeMaterializationStable: defaultChecksum(materializedA) === defaultChecksum(materializedB) && materializedA.length === 2,
262
+ inheritedPrototypeMaterialized: inheritedComponents?.hp === 80
263
+ && inheritedComponents.speed === 12
264
+ && inheritedComponents.numericMode === 'fixed'
265
+ && inheritedComponents.Loadout?.slot === 7,
266
+ dynamicCollectionsMaterialized: Array.isArray(inheritedComponents?.Inventory?.items)
267
+ && inheritedComponents.Inventory.items[0] === 'weapon.sword'
268
+ && Array.isArray(inheritedComponents.Inventory.tags)
269
+ && inheritedComponents.Inventory.tags.join(',') === 'player,spawned',
270
+ mapMaterializationStable: map.mapBakeHash === mapRepeat.mapBakeHash && map.materializedEntityCount === 2,
271
+ mapRebakeInvalidated: map.mapBakeHash !== rebaked.mapBakeHash,
272
+ mapMaterializedEntityCount: map.materializedEntityCount,
273
+ mapBakeHash: map.mapBakeHash,
274
+ failureReasons,
275
+ };
276
+ const invariantChecks = [
277
+ withoutChecksum.byteStable,
278
+ withoutChecksum.staleEngineRejected,
279
+ withoutChecksum.staleSchemaRejected,
280
+ withoutChecksum.staleConfigRejected,
281
+ withoutChecksum.staleAssetDbRejected,
282
+ withoutChecksum.tamperedConfigBytesRejected,
283
+ withoutChecksum.tamperedAssetBytesRejected,
284
+ withoutChecksum.unsupportedFloatRejected,
285
+ validConfigAccepted,
286
+ withoutChecksum.prototypeMaterializationStable,
287
+ withoutChecksum.inheritedPrototypeMaterialized,
288
+ withoutChecksum.dynamicCollectionsMaterialized,
289
+ withoutChecksum.mapMaterializationStable,
290
+ withoutChecksum.mapRebakeInvalidated,
291
+ ];
292
+ const result = evaluateDeterministicConfigBundleParityResult(verification, invariantChecks);
293
+ return {
294
+ result,
295
+ ...withoutChecksum,
296
+ checksum: defaultChecksum(withoutChecksum),
297
+ };
298
+ }
299
+ export function summarizeDeterministicConfigBundleFailureReasons(inputs) {
300
+ return {
301
+ staleEngine: inputs.staleEngine.failure ?? '',
302
+ staleSchema: inputs.staleSchema.failure ?? '',
303
+ staleConfig: inputs.staleConfig.failure ?? '',
304
+ staleAssetDb: inputs.staleAssetDb.failure ?? '',
305
+ tamperedConfigBytes: inputs.tamperedConfigBytes.failure ?? '',
306
+ tamperedAssetBytes: inputs.tamperedAssetBytes.failure ?? '',
307
+ };
308
+ }
309
+ export function evaluateDeterministicConfigBundleParityResult(verification, invariantChecks) {
310
+ return verification.result === 'pass'
311
+ && invariantChecks.every((value) => value)
312
+ ? 'pass'
313
+ : 'fail';
314
+ }
315
+ function createConfigBundleParitySource() {
316
+ return {
317
+ version: 1,
318
+ engineHash: 'engine@1',
319
+ schemaHash: 'schema@1',
320
+ sessionConfig: { tickRate: 60, players: 128 },
321
+ simulationConfig: { numericModeV1: 'fixed', rollback: true },
322
+ runtimeConfig: { maxRollbackFrames: 12, snapshotStride: 4 },
323
+ playerConfig: { defaultTeam: 'blue', maxSlots: 128 },
324
+ assets: {
325
+ schemaVersion: 1,
326
+ engineVersion: 'engine@1',
327
+ assets: [
328
+ { id: 'material.default', type: 'physics-material', friction: 1, restitution: 0 },
329
+ { id: 'material.ice', type: 'physics-material', friction: 0, restitution: 1 },
330
+ {
331
+ id: 'base.prototype',
332
+ type: 'prototype',
333
+ prototype: true,
334
+ references: ['material.default'],
335
+ components: {
336
+ hp: 100,
337
+ speed: 12,
338
+ numericModeV1: 'fixed',
339
+ Inventory: {
340
+ items: { collection: 'list', values: ['weapon.sword'] },
341
+ tags: { collection: 'set', values: ['spawned', 'player', 'spawned'] },
342
+ },
343
+ },
344
+ },
345
+ {
346
+ id: 'weapon.sword',
347
+ type: 'item',
348
+ },
349
+ {
350
+ id: 'player.prototype',
351
+ type: 'prototype',
352
+ prototype: true,
353
+ extendsRef: 'base.prototype',
354
+ references: ['base.prototype'],
355
+ components: { hp: 80 },
356
+ },
357
+ {
358
+ id: 'map.arena',
359
+ type: 'map',
360
+ references: ['player.prototype'],
361
+ spawns: [{ prototypeRef: 'player.prototype', count: 2, startEntityId: 100, overrides: { hp: 80 } }],
362
+ },
363
+ ],
364
+ },
365
+ migrations: [{
366
+ fromVersion: 1,
367
+ toVersion: 2,
368
+ renameSimulationKeys: { numericModeV1: 'numericMode' },
369
+ renamePrototypeComponentKeys: { numericModeV1: 'numericMode' },
370
+ }],
371
+ };
372
+ }
373
+ function migrateConfigBundle(source, targetVersion) {
374
+ let current = cloneCanonical(source);
375
+ validateUniqueMigrations(current.migrations ?? []);
376
+ while (current.version < targetVersion) {
377
+ const migration = current.migrations?.find((candidate) => candidate.fromVersion === current.version);
378
+ if (migration === undefined) {
379
+ throw new Error(`Missing config migration from ${current.version}`);
380
+ }
381
+ current = {
382
+ ...current,
383
+ version: migration.toVersion,
384
+ sessionConfig: renameConfigKeys(current.sessionConfig, migration.renameSessionKeys ?? {}),
385
+ simulationConfig: renameConfigKeys(current.simulationConfig, migration.renameSimulationKeys ?? migration.renameKeys ?? {}),
386
+ runtimeConfig: renameConfigKeys(current.runtimeConfig, migration.renameRuntimeKeys ?? {}),
387
+ playerConfig: renameConfigKeys(current.playerConfig, migration.renamePlayerKeys ?? {}),
388
+ assets: renamePrototypeComponentKeys(current.assets, migration.renamePrototypeComponentKeys ?? {}),
389
+ };
390
+ }
391
+ if (current.version !== targetVersion) {
392
+ throw new Error(`Unsupported config version ${current.version}`);
393
+ }
394
+ return current;
395
+ }
396
+ function renamePrototypeComponentKeys(assets, renames) {
397
+ if (stableKeys(renames).length === 0) {
398
+ return assets;
399
+ }
400
+ return {
401
+ ...assets,
402
+ assets: assets.assets.map((asset) => {
403
+ if (asset.prototype !== true || !isRecord(asset.components)) {
404
+ return asset;
405
+ }
406
+ return {
407
+ ...asset,
408
+ components: renameConfigKeys(asset.components, renames),
409
+ };
410
+ }),
411
+ };
412
+ }
413
+ function validateUniqueMigrations(migrations) {
414
+ const fromVersions = new Set();
415
+ for (const migration of migrations) {
416
+ if (!Number.isInteger(migration.fromVersion) || !Number.isInteger(migration.toVersion)) {
417
+ throw new Error('Config migration versions must be integers');
418
+ }
419
+ if (migration.toVersion <= migration.fromVersion) {
420
+ throw new Error(`Config migration from ${migration.fromVersion} must advance to a higher version`);
421
+ }
422
+ if (fromVersions.has(migration.fromVersion)) {
423
+ throw new Error(`Duplicate config migration from ${migration.fromVersion}`);
424
+ }
425
+ fromVersions.add(migration.fromVersion);
426
+ }
427
+ }
428
+ function renameConfigKeys(config, renames) {
429
+ const next = {};
430
+ for (const key of stableKeys(config)) {
431
+ const renamed = renames[key] ?? key;
432
+ if (Object.prototype.hasOwnProperty.call(next, renamed)) {
433
+ throw new Error(`Config migration key collision at ${renamed}`);
434
+ }
435
+ next[renamed] = config[key];
436
+ }
437
+ return next;
438
+ }
439
+ function validateConfigSource(source) {
440
+ if (source.engineHash.length === 0 || source.schemaHash.length === 0) {
441
+ throw new Error('Config bundle requires engine and schema hashes');
442
+ }
443
+ rejectUnsupportedFloats(source.sessionConfig, 'sessionConfig');
444
+ rejectUnsupportedFloats(source.simulationConfig, 'simulationConfig');
445
+ rejectUnsupportedFloats(source.runtimeConfig, 'runtimeConfig');
446
+ rejectUnsupportedFloats(source.playerConfig, 'playerConfig');
447
+ }
448
+ function rejectUnsupportedFloats(value, path) {
449
+ if (typeof value === 'number') {
450
+ if (!Number.isInteger(value)) {
451
+ throw new Error(`Unsupported float in config bundle at ${path}`);
452
+ }
453
+ return;
454
+ }
455
+ if (Array.isArray(value)) {
456
+ value.forEach((entry, index) => rejectUnsupportedFloats(entry, `${path}[${index}]`));
457
+ return;
458
+ }
459
+ if (value !== null && typeof value === 'object') {
460
+ const record = value;
461
+ for (const key of stableKeys(record)) {
462
+ rejectUnsupportedFloats(record[key], `${path}.${key}`);
463
+ }
464
+ }
465
+ }
466
+ function isRecord(value) {
467
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
468
+ }
469
+ function stableKeys(record) {
470
+ return Object.keys(record).sort(compareStrings);
471
+ }
472
+ function compareStrings(left, right) {
473
+ return Number(left > right) - Number(left < right);
474
+ }
475
+ function throws(action) {
476
+ try {
477
+ action();
478
+ return false;
479
+ }
480
+ catch {
481
+ return true;
482
+ }
483
+ }
@@ -0,0 +1,20 @@
1
+ export { canonicalize, canonicalStringify, defaultChecksum } from './canonical.js';
2
+ export { createDeterministicCommandTimeline } from './commands.js';
3
+ export { createInstantReplayRunner, runInstantReplay } from './instant-replay.js';
4
+ export { createOfflineSession } from './offline-session.js';
5
+ export { createPauseController } from './pause-resume.js';
6
+ export { createSessionFromPromotionSnapshot, exportPromotionSnapshot } from './session-promotion.js';
7
+ export { verifyReplay, verifyReplayWithDescriptor } from './replay.js';
8
+ export { defineSyncplayGame } from './schema.js';
9
+ export { createSchemaArtifacts } from './schema-artifacts.js';
10
+ export { createSyncplayOfflineRuntime } from './sdk-offline.js';
11
+ export { runSyncplaySynctest } from './synctest.js';
12
+ export type { SyncplaySynctestConfig, SyncplaySynctestDivergence, SyncplaySynctestInputFuzz, SyncplaySynctestPhase, SyncplaySynctestResult, } from './synctest.js';
13
+ export type { CanonicalValue } from './canonical.js';
14
+ export type { DeterministicCommandChannelDescriptor, DeterministicCommandTimeline, DeterministicCommandTimelineConfig, DeterministicCommandTimelineSnapshot, DeterministicPlayerCommand, DeterministicRejectedCommand, } from './commands.js';
15
+ export type { OfflineSession, RecordedChecksum, RecordedCommandFrame, RecordedDebugEvent, RecordedInputFlags, RecordedInputFrame, ReplayFile, ReplayRecordingMode, ReplayVerificationResult, TickRate, DeterministicSessionConfig, DeterministicStep, DeterministicStepContext, } from './types.js';
16
+ export type { AssetDescriptor, CommandChannelDescriptor, ConfigDescriptor, DeterministicGameDescriptor, EventDescriptor, InputFieldDescriptor, NumericMode, PrototypeDescriptor, SchemaFieldDescriptor, SchemaFieldKind, StateFieldDescriptor, SystemDescriptor, ValidatedDeterministicGameDescriptor, } from './schema.js';
17
+ export type { DeterministicOfflineFrame, DeterministicOfflineRuntime, DeterministicOfflineRuntimeConfig, } from './sdk-offline.js';
18
+ export type { DeterministicSchemaArtifacts, SchemaFrameDump, } from './schema-artifacts.js';
19
+ export type { InstantReplayInputFrame, InstantReplayResult, InstantReplayRunner, InstantReplayRunnerOptions, InstantReplayRunOptions, RunInstantReplayOptions, } from './instant-replay.js';
20
+ export type { DeterministicPauseController, DeterministicPauseState, DeterministicPauseStatus, PauseControllerOptions, PauseWrappedState, } from './pause-resume.js';
@@ -0,0 +1,11 @@
1
+ export { canonicalize, canonicalStringify, defaultChecksum } from './canonical.js';
2
+ export { createDeterministicCommandTimeline } from './commands.js';
3
+ export { createInstantReplayRunner, runInstantReplay } from './instant-replay.js';
4
+ export { createOfflineSession } from './offline-session.js';
5
+ export { createPauseController } from './pause-resume.js';
6
+ export { createSessionFromPromotionSnapshot, exportPromotionSnapshot } from './session-promotion.js';
7
+ export { verifyReplay, verifyReplayWithDescriptor } from './replay.js';
8
+ export { defineSyncplayGame } from './schema.js';
9
+ export { createSchemaArtifacts } from './schema-artifacts.js';
10
+ export { createSyncplayOfflineRuntime } from './sdk-offline.js';
11
+ export { runSyncplaySynctest } from './synctest.js';
@@ -0,0 +1,59 @@
1
+ export interface DeterministicPhysicsMaterial {
2
+ readonly friction: number;
3
+ readonly restitution: number;
4
+ }
5
+ export interface DeterministicStaticCollider {
6
+ readonly id: string;
7
+ readonly x: number;
8
+ readonly y: number;
9
+ readonly halfWidth: number;
10
+ readonly halfHeight: number;
11
+ readonly material?: DeterministicPhysicsMaterial;
12
+ }
13
+ export interface CookedDeterministicStaticCollider {
14
+ readonly id: string;
15
+ readonly x: number;
16
+ readonly y: number;
17
+ readonly halfWidth: number;
18
+ readonly halfHeight: number;
19
+ readonly material: DeterministicPhysicsMaterial;
20
+ }
21
+ export interface CookedStaticColliderSet {
22
+ readonly schemaVersion: 1;
23
+ readonly hash: string;
24
+ readonly bytes: string;
25
+ readonly colliders: readonly CookedDeterministicStaticCollider[];
26
+ }
27
+ export interface MovementBody {
28
+ readonly x: number;
29
+ readonly y: number;
30
+ readonly vx: number;
31
+ readonly vy: number;
32
+ readonly grounded: boolean;
33
+ }
34
+ export interface MovementInput {
35
+ readonly dx: number;
36
+ readonly dy?: number;
37
+ readonly jump?: boolean;
38
+ }
39
+ export interface FpsAimInput {
40
+ readonly yawDelta: number;
41
+ readonly pitchDelta: number;
42
+ }
43
+ export interface QuantizedFpsAim {
44
+ readonly yaw: number;
45
+ readonly pitch: number;
46
+ readonly originX: number;
47
+ readonly originY: number;
48
+ }
49
+ export declare function detectVerticalCcdHit(startX: number, endX: number, wallX: number): boolean;
50
+ export declare function combineDeterministicPhysicsMaterial(left: DeterministicPhysicsMaterial, right: DeterministicPhysicsMaterial): DeterministicPhysicsMaterial;
51
+ export declare function cookStaticColliders(colliders: readonly DeterministicStaticCollider[]): CookedStaticColliderSet;
52
+ export declare function stepTopDownBody(body: MovementBody, input: MovementInput, bounds: {
53
+ readonly minX: number;
54
+ readonly maxX: number;
55
+ readonly minY: number;
56
+ readonly maxY: number;
57
+ }): MovementBody;
58
+ export declare function stepKccLiteBody(body: MovementBody, input: MovementInput): MovementBody;
59
+ export declare function quantizeFpsAim(previous: QuantizedFpsAim, input: FpsAimInput): QuantizedFpsAim;