@series-inc/rundot-syncplay 6.0.0-rc.4 → 6.0.0-rc.41

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 (257) hide show
  1. package/MIGRATING-RC20-TO-RC22.md +133 -0
  2. package/MIGRATING-RC28-TO-RC29.md +51 -0
  3. package/MIGRATING-RC31-TO-RC32.md +67 -0
  4. package/MIGRATING-RC33-TO-RC34.md +105 -0
  5. package/MIGRATING-RC34-TO-RC35.md +334 -0
  6. package/MIGRATING-RC35-TO-RC36.md +40 -0
  7. package/MIGRATING-RC36-TO-RC37.md +53 -0
  8. package/MIGRATING-RC37-TO-RC38.md +22 -0
  9. package/MIGRATING-RC38-TO-RC39.md +25 -0
  10. package/MIGRATING-RC39-TO-RC40.md +41 -0
  11. package/MIGRATING-RC40-TO-RC41.md +11 -0
  12. package/README.md +165 -0
  13. package/bench/wreck-yard-sleeping-contacts.json +855 -0
  14. package/core/deterministic-math.d.ts +75 -1
  15. package/core/native/instance_ledger.hpp +1095 -0
  16. package/core/native/legacy_checkpoint_ids.hpp +107 -0
  17. package/core/native/physics/abi.cpp +5 -0
  18. package/core/native/physics/abi.hpp +2 -0
  19. package/core/native/physics/buoyancy.cpp +7 -6
  20. package/core/native/physics/capsule_triangle_native.inc +57 -17
  21. package/core/native/physics/certified_sum.hpp +218 -0
  22. package/core/native/physics/checkpoint_schema.hpp +379 -0
  23. package/core/native/physics/constraint_rows.cpp +6 -2
  24. package/core/native/physics/constraint_rows.hpp +4 -1
  25. package/core/native/physics/exact/exact-applied.hpp +57 -1
  26. package/core/native/physics/exact/word-core.hpp +1 -0
  27. package/core/native/physics/geometry_memory.hpp +435 -11
  28. package/core/native/physics/geometry_store.cpp +391 -34
  29. package/core/native/physics/geometry_store.hpp +49 -2
  30. package/core/native/physics/material_pose.hpp +628 -320
  31. package/core/native/physics/physics.cpp +3615 -287
  32. package/core/native/physics/physics.hpp +245 -2
  33. package/core/native/physics/world.cpp +4809 -539
  34. package/core/native/physics/world.hpp +815 -20
  35. package/core/native/physics/world_abi.cpp +4102 -820
  36. package/core/native/physics/world_abi.hpp +478 -5
  37. package/core/native/physics/world_digest_visitor.hpp +277 -0
  38. package/core/native/physics/world_strong_digest.hpp +557 -0
  39. package/core/native/physics2d/ccd.cpp +137 -8
  40. package/core/native/physics2d/checkpoint_memory.hpp +349 -0
  41. package/core/native/physics2d/commands.cpp +163 -25
  42. package/core/native/physics2d/commands.hpp +2 -0
  43. package/core/native/physics2d/contour.cpp +325 -0
  44. package/core/native/physics2d/contour.hpp +143 -0
  45. package/core/native/physics2d/joints.cpp +14 -23
  46. package/core/native/physics2d/memory_private.hpp +125 -0
  47. package/core/native/physics2d/owned_abi.cpp +1351 -898
  48. package/core/native/physics2d/owned_abi.hpp +177 -44
  49. package/core/native/physics2d/physics2d.cpp +1133 -59
  50. package/core/native/physics2d/physics2d.hpp +86 -1
  51. package/core/native/physics2d/queries.cpp +1046 -77
  52. package/core/native/physics2d/queries.hpp +62 -4
  53. package/core/native/physics2d/world.cpp +982 -357
  54. package/core/native/physics2d/world.hpp +109 -11
  55. package/core/native/sha256/sha256_compress_unsigned.hpp +68 -0
  56. package/core/native/sha256/sha256_fips_constants.hpp +24 -0
  57. package/core/native/sha256/sha256_length.hpp +56 -0
  58. package/core/native/sha256/sha256_memo.hpp +48 -0
  59. package/core/native/sha256/sha256_sink.hpp +234 -0
  60. package/core/physics2d-owned.d.ts +327 -154
  61. package/core/runtime.d.ts +192 -19
  62. package/core/scripts/build-native.mjs +12 -0
  63. package/core/scripts/build-wasm-physics.mjs +169 -22
  64. package/core/scripts/generate-physics2d-vectors.mjs +59 -0
  65. package/core/src/kinetix-deterministic-math.d.ts +2 -0
  66. package/core/src/kinetix-deterministic-math.mjs +583 -27
  67. package/core/src/kinetix-deterministic-stdlib.mjs +68 -0
  68. package/core/src/kinetix-owned-runtime-adapter.mjs +788 -0
  69. package/core/src/kinetix-runtime-adapter-utils.mjs +44 -2
  70. package/core/src/kinetix-runtime-contract.mjs +55 -9
  71. package/core/src/kinetix-runtime-identity.mjs +12 -1
  72. package/core/src/kinetix-state-report.mjs +36 -0
  73. package/core/src/physics/abi-constants.mjs +3 -2
  74. package/core/src/physics/buoyancy.d.mts +132 -59
  75. package/core/src/physics/distance.d.mts +160 -7
  76. package/core/src/physics/feature-api.d.mts +13 -585
  77. package/core/src/physics/gear.d.mts +544 -301
  78. package/core/src/physics/mass-properties.d.mts +114 -3
  79. package/core/src/physics/physics-profile-wasm-module.generated.mjs +48 -0
  80. package/core/src/physics/physics-wasm-module.generated.mjs +34 -6
  81. package/core/src/physics/powertrain.d.mts +256 -226
  82. package/core/src/physics/profile.d.mts +2 -0
  83. package/core/src/physics/profile.mjs +14 -0
  84. package/core/src/physics/pulley.d.mts +92 -349
  85. package/core/src/physics/rope.d.mts +230 -29
  86. package/core/src/physics/surface-velocity.d.mts +152 -196
  87. package/core/src/physics/voxel-cooking.d.mts +35 -19
  88. package/core/src/physics/voxel-cooking.mjs +66 -8
  89. package/core/src/physics/voxel-swept-quad.mjs +110 -0
  90. package/core/src/physics/wasm-instance.mjs +154 -26
  91. package/core/src/physics/world.d.mts +60 -0
  92. package/core/src/physics/world.mjs +1944 -233
  93. package/core/src/physics2d/body-state.mjs +45 -5
  94. package/core/src/physics2d/collision.d.mts +13 -11
  95. package/core/src/physics2d/collision.mjs +39 -3
  96. package/core/src/physics2d/contour-state.mjs +771 -0
  97. package/core/src/physics2d/feature-api.d.mts +207 -1
  98. package/core/src/physics2d/owned-queries.mjs +3 -1
  99. package/core/src/physics2d/owned-transport.mjs +245 -113
  100. package/core/src/physics2d/owned-world.mjs +202 -62
  101. package/core/src/physics2d/particle-fluid.d.mts +139 -30
  102. package/core/src/physics2d/particle-fluid.mjs +67 -31
  103. package/core/src/physics2d/physics2d-wasm-module.generated.mjs +25 -8
  104. package/core/src/physics2d/query-codec.mjs +40 -6
  105. package/core/src/physics2d/submerged-geometry.d.mts +35 -16
  106. package/core/src/runtime.mjs +23 -0
  107. package/core/src/shared/bytes.d.mts +2 -0
  108. package/core/src/shared/bytes.mjs +33 -0
  109. package/core/src/shared/sha256.d.mts +3 -0
  110. package/core/src/shared/sha256.mjs +72 -22
  111. package/core/units.d.ts +50 -0
  112. package/core/world.d.ts +223 -1
  113. package/dist/api-deprecations.generated.d.ts +24 -0
  114. package/dist/api-deprecations.generated.js +24 -0
  115. package/dist/authority-room.d.ts +218 -3
  116. package/dist/authority-room.js +979 -62
  117. package/dist/browser.d.ts +7 -5
  118. package/dist/browser.js +4 -3
  119. package/dist/cadence.d.ts +7 -0
  120. package/dist/cadence.js +19 -0
  121. package/dist/canonical.d.ts +1 -0
  122. package/dist/canonical.js +3 -0
  123. package/dist/checksum-policy.d.ts +10 -0
  124. package/dist/checksum-policy.js +14 -0
  125. package/dist/compat/v5.d.ts +5 -1
  126. package/dist/compat/v5.js +52 -9
  127. package/dist/creator.d.ts +10 -6
  128. package/dist/creator.js +5 -3
  129. package/dist/extensions/hub/airlock.d.ts +153 -0
  130. package/dist/extensions/hub/airlock.js +500 -0
  131. package/dist/extensions/hub/contracts.d.ts +369 -0
  132. package/dist/extensions/hub/contracts.js +106 -0
  133. package/dist/extensions/hub/exfil.d.ts +54 -0
  134. package/dist/extensions/hub/exfil.js +110 -0
  135. package/dist/extensions/hub/handoff.d.ts +84 -0
  136. package/dist/extensions/hub/handoff.js +161 -0
  137. package/dist/extensions/hub/index.d.ts +12 -0
  138. package/dist/extensions/hub/index.js +12 -0
  139. package/dist/extensions/hub/inventory.d.ts +86 -0
  140. package/dist/extensions/hub/inventory.js +288 -0
  141. package/dist/extensions/hub/party.d.ts +43 -0
  142. package/dist/extensions/hub/party.js +58 -0
  143. package/dist/extensions/hub/plugin.d.ts +23 -0
  144. package/dist/extensions/hub/plugin.js +37 -0
  145. package/dist/extensions/hub/settlement.d.ts +42 -0
  146. package/dist/extensions/hub/settlement.js +121 -0
  147. package/dist/game-byte-section.d.ts +36 -0
  148. package/dist/game-byte-section.js +350 -0
  149. package/dist/index.d.ts +23 -9
  150. package/dist/index.js +21 -5
  151. package/dist/input-authority.d.ts +13 -0
  152. package/dist/input-authority.js +129 -28
  153. package/dist/instant-replay.d.ts +27 -2
  154. package/dist/instant-replay.js +91 -16
  155. package/dist/lag-compensation3d.js +11 -10
  156. package/dist/match-log.d.ts +21 -4
  157. package/dist/match-log.js +92 -9
  158. package/dist/math.d.ts +4 -0
  159. package/dist/math.js +69 -0
  160. package/dist/modules/character-3d.d.ts +16 -1
  161. package/dist/modules/character-3d.js +42 -5
  162. package/dist/modules/combat.js +6 -5
  163. package/dist/modules/extraction.d.ts +148 -0
  164. package/dist/modules/extraction.js +344 -0
  165. package/dist/modules/rts.js +1 -1
  166. package/dist/movement3d-common.d.ts +57 -0
  167. package/dist/movement3d-common.js +218 -0
  168. package/dist/movement3d-revision1.d.ts +2 -0
  169. package/dist/movement3d-revision1.js +973 -0
  170. package/dist/movement3d-revision3.d.ts +2 -0
  171. package/dist/movement3d-revision3.js +844 -0
  172. package/dist/movement3d.d.ts +106 -3
  173. package/dist/movement3d.js +1292 -456
  174. package/dist/networked-client.d.ts +35 -0
  175. package/dist/networked-client.js +650 -115
  176. package/dist/node.d.ts +3 -2
  177. package/dist/node.js +2 -1
  178. package/dist/physics/2d.d.ts +19 -4
  179. package/dist/physics/2d.js +31 -6
  180. package/dist/physics/3d/profile.d.ts +2 -0
  181. package/dist/physics/3d/profile.js +2 -0
  182. package/dist/physics/3d.d.ts +795 -249
  183. package/dist/physics/3d.js +6382 -454
  184. package/dist/physics/edit-result-graph.d.ts +36 -0
  185. package/dist/physics/edit-result-graph.js +141 -0
  186. package/dist/physics/game-codec3d.d.ts +41 -0
  187. package/dist/physics/game-codec3d.js +544 -0
  188. package/dist/physics/installed-checkpoint3d.d.ts +13 -0
  189. package/dist/physics/installed-checkpoint3d.js +120 -0
  190. package/dist/physics/installed-runtime3d.d.ts +55 -0
  191. package/dist/physics/installed-runtime3d.js +373 -0
  192. package/dist/physics/installed-state-commitment3d.d.ts +2 -0
  193. package/dist/physics/installed-state-commitment3d.js +24 -0
  194. package/dist/physics/portal-render3d.d.ts +328 -0
  195. package/dist/physics/portal-render3d.js +751 -0
  196. package/dist/physics/units.d.ts +103 -0
  197. package/dist/physics/units.js +142 -0
  198. package/dist/physics/vehicle-state2d.d.ts +104 -0
  199. package/dist/physics/vehicle-state2d.js +757 -0
  200. package/dist/physics/vehicle-state3d.d.ts +103 -0
  201. package/dist/physics/vehicle-state3d.js +1539 -0
  202. package/dist/physics/voxel-body-state.d.ts +61 -0
  203. package/dist/physics/voxel-body-state.js +410 -0
  204. package/dist/plugins/index.d.ts +27 -0
  205. package/dist/plugins/index.js +114 -0
  206. package/dist/plugins/types.d.ts +34 -0
  207. package/dist/plugins/types.js +5 -0
  208. package/dist/r3f-render-adapter.d.ts +59 -1
  209. package/dist/r3f-render-adapter.js +137 -2
  210. package/dist/replay.d.ts +13 -0
  211. package/dist/replay.js +95 -70
  212. package/dist/runner.d.ts +17 -2
  213. package/dist/runner.js +472 -84
  214. package/dist/runtime-cleanup.d.ts +54 -0
  215. package/dist/runtime-cleanup.js +266 -0
  216. package/dist/runtime-lease.d.ts +11 -1
  217. package/dist/runtime-lease.js +23 -10
  218. package/dist/runtime-room-metadata.d.ts +2 -8
  219. package/dist/runtime-room-metadata.js +6 -13
  220. package/dist/runtime-session.d.ts +8 -0
  221. package/dist/runtime-session.js +217 -57
  222. package/dist/schema-codegen.js +3 -0
  223. package/dist/schema-dsl-binary.d.ts +10 -4
  224. package/dist/schema-dsl-binary.js +375 -76
  225. package/dist/scratch-pool.d.ts +32 -0
  226. package/dist/scratch-pool.js +60 -0
  227. package/dist/sdk-session.d.ts +1 -0
  228. package/dist/sdk-session.js +4 -0
  229. package/dist/secret-client.d.ts +1 -1
  230. package/dist/secret-client.js +1 -1
  231. package/dist/secret-config.js +2 -60
  232. package/dist/secret-crypto.js +70 -36
  233. package/dist/session-promotion.d.ts +19 -1
  234. package/dist/session-promotion.js +37 -6
  235. package/dist/session-snapshot.d.ts +16 -4
  236. package/dist/session-snapshot.js +36 -33
  237. package/dist/session-wire.d.ts +24 -1
  238. package/dist/session-wire.js +67 -22
  239. package/dist/sparse-set.d.ts +1 -0
  240. package/dist/sparse-set.js +22 -0
  241. package/dist/spatial/spatial-grid-3d.d.ts +41 -0
  242. package/dist/spatial/spatial-grid-3d.js +115 -0
  243. package/dist/synctest.d.ts +9 -0
  244. package/dist/synctest.js +106 -17
  245. package/dist/testing-network.d.ts +2 -0
  246. package/dist/testing-network.js +122 -18
  247. package/dist/testing.d.ts +27 -6
  248. package/dist/testing.js +297 -56
  249. package/dist/tools/index.d.ts +3 -2
  250. package/dist/tools/index.js +3 -2
  251. package/dist/tools/module-certification.d.ts +6 -0
  252. package/dist/tools/module-certification.js +27 -2
  253. package/dist/tools/static-checker.js +9 -2
  254. package/extensions/hub/package.json +1 -0
  255. package/hub/package.json +1 -0
  256. package/package.json +70 -6
  257. package/plugins/package.json +1 -0
@@ -0,0 +1,133 @@
1
+ # Migrating from Syncplay 6.0.0-rc.20 to rc.22
2
+
3
+ Syncplay `6.0.0-rc.22` introduces ergonomics improvements for branded units, public state codecs for game-owned state containing `bigint` physics identifiers, generalized multi-wheel vehicle verification, and explicit guidance for Kinematic Character Controller (KCC) Revision 2.
4
+
5
+ ---
6
+
7
+ ## 1. Branded Vector Helpers & Migration Codemod (Item 10)
8
+
9
+ ### What Changed
10
+ In rc.20, unit branding (`Meters`, `Radians`, `Newtons`, etc.) was tightened across all physics APIs to prevent unit mismatch bugs. However, writing `{ x: meters(a), y: meters(b), z: meters(c) }` across hundreds of lines introduces substantial boilerplate.
11
+
12
+ rc.22 exports convenient vector constructors that accept both positional coordinates and existing `{ x, y, z }` record objects:
13
+
14
+ ```ts
15
+ import {
16
+ meters3,
17
+ radians3,
18
+ metersPerSecond3,
19
+ metersPerSecondSquared3,
20
+ newtons3,
21
+ vec3,
22
+ meters2,
23
+ radians2,
24
+ metersPerSecond2,
25
+ vec2,
26
+ } from '@series-inc/rundot-syncplay/physics/3d';
27
+ ```
28
+
29
+ ### Usage
30
+
31
+ ```ts
32
+ // Positional coordinates
33
+ const pos = meters3(0, 1.5, -2);
34
+ const vel = metersPerSecond3(0, 0, 15);
35
+ const force = newtons3(0, 500, 0);
36
+
37
+ // Object coordinates (drop-in wrapper for legacy vector objects)
38
+ const legacyVec = { x: 10, y: 0, z: -5 };
39
+ const brandedPos = meters3(legacyVec);
40
+
41
+ // Custom brands
42
+ const custom = vec3(turns, 0.1, 0.2, 0.3);
43
+ ```
44
+
45
+ ### Regex / Search & Replace Codemod
46
+
47
+ If your codebase has repetitive manual `{ x: meters(...), y: meters(...), z: meters(...) }` calls, you can migrate them with the following regular expressions:
48
+
49
+ - **Find:**
50
+ ```regexp
51
+ \{\s*x:\s*meters\(([^)]+)\),\s*y:\s*meters\(([^)]+)\),\s*z:\s*meters\(([^)]+)\)\s*\}
52
+ ```
53
+ - **Replace:**
54
+ ```ts
55
+ meters3($1, $2, $3)
56
+ ```
57
+
58
+ - **2D Vectors Find:**
59
+ ```regexp
60
+ \{\s*x:\s*meters\(([^)]+)\),\s*y:\s*meters\(([^)]+)\)\s*\}
61
+ ```
62
+ - **Replace:**
63
+ ```ts
64
+ meters2($1, $2)
65
+ ```
66
+
67
+ ---
68
+
69
+ ## 2. KCC Revision 2: Native Step-Up & Platform Support Persistence (Item 11)
70
+
71
+ ### Native Step-Up (No Custom Raycast Hacks)
72
+ In Revision 1, stepping up over vertical edges (curbs, stairs, debris) often required game-side raycasts to manually nudge the character upward before stepping.
73
+
74
+ In **Revision 2 (`behaviorRevision: 2`)**, the solver natively sweeps the bottom spherical cap against vertical steps up to `stepHeight`.
75
+ - Author `stepHeight: 0.3` (or your desired maximum step height in meters).
76
+ - A 0.2 m vertical edge will be climbed smoothly and deterministically without clipping or snagging.
77
+ - **Action Required:** Remove any custom game-side pre-step raycasts or edge-nudging hacks; they are redundant and can interfere with the native solver's ground alignment.
78
+
79
+ ### Crucial: Persist the `support` Field Across Ticks
80
+ Revision 2 introduces physical moving-platform carry and continuous contact resolution via the `support` property on `DeterministicKccState3D` / step result.
81
+
82
+ ```ts
83
+ // Ticking KCC Revision 2:
84
+ const result = stepDeterministicKcc3D(input, {
85
+ ...currentState,
86
+ // CRITICAL: Pass back the support returned from the previous tick!
87
+ support: lastStepResult.support,
88
+ }, world, options);
89
+ ```
90
+
91
+ > [!IMPORTANT]
92
+ > If your game drops `support` or creates a fresh state object each frame without copying `lastStepResult.support`, the character controller will not inherit platform velocity or maintain stable ground contact.
93
+
94
+ ---
95
+
96
+ ## 3. Game-Owned State Codecs for BigInt Body IDs (Item 8)
97
+
98
+ ### What Changed
99
+ `DeterministicVehicleState3D` and `DeterministicKccSupport3D` (when `kind: 'physics'`) carry native 64-bit `PhysicsBodyId3D` values represented as JavaScript `bigint` primitives.
100
+
101
+ Standard `JSON.stringify(state)` throws:
102
+ ```
103
+ TypeError: Do not know how to serialize a BigInt
104
+ ```
105
+
106
+ ### Solution
107
+ Syncplay rc.22 exports canonical serialization and deserialization helpers that encode `bigint` without loss:
108
+
109
+ ```ts
110
+ import {
111
+ encodeDeterministicVehicleState3D,
112
+ decodeDeterministicVehicleState3D,
113
+ encodeDeterministicVehicleState3DBytes,
114
+ decodeDeterministicVehicleState3DBytes,
115
+ encodeDeterministicKccSupport3D,
116
+ decodeDeterministicKccSupport3D,
117
+ encodeDeterministicKccSupport3DBytes,
118
+ decodeDeterministicKccSupport3DBytes,
119
+ } from '@series-inc/rundot-syncplay/physics/3d';
120
+
121
+ // Save vehicle state to JSON string or binary Uint8Array
122
+ const savedJson = encodeDeterministicVehicleState3D(vehicleState);
123
+ const savedBytes = encodeDeterministicVehicleState3DBytes(vehicleState);
124
+
125
+ // Restore vehicle state
126
+ const restoredState = decodeDeterministicVehicleState3D(savedJson);
127
+
128
+ // Save KCC support state
129
+ const savedSupportJson = encodeDeterministicKccSupport3D(kccResult.support);
130
+ const restoredSupport = decodeDeterministicKccSupport3D(savedSupportJson);
131
+ ```
132
+
133
+ These functions use canonical JSON formatting with BigInt sentinels (`{"$rdm":"bigint","value":"..."}`) ensuring bit-identical hashing and portable network snapshots across clients.
@@ -0,0 +1,51 @@
1
+ # Migrating from Syncplay 6.0.0-rc.28 to rc.29
2
+
3
+ Syncplay `6.0.0-rc.29` resolves partner feedback on portal physics, doorway aperture sliding, character controller pending body references, and output parity across checkpoint restores.
4
+
5
+ ---
6
+
7
+ ## 1. Reserved Collision Layers 24–30 (Portal Host Slots)
8
+
9
+ ### What Changed
10
+ To provide zero-overhead wall aperture cutouts without altering the native C++ physics solver, Syncplay dynamically isolates portal host colliders by temporarily shifting host bodies to dedicated internal filtering layers.
11
+
12
+ - **Bits 24 through 30 (`0x7f000000`)** in the 32-bit collision layer bitmask are now reserved for internal portal host filtering.
13
+ - Up to **7 distinct host bodies** can be registered concurrently across active portal pairs in a physics world.
14
+ - Host slots are dynamically allocated upon portal pair creation and automatically reclaimed when the portal pair is removed via `removePortalPair(handle)`.
15
+
16
+ ### Action Required
17
+ If your game uses layers 24 through 30 for custom gameplay categories (such as projectiles, debris, or triggers), those categories will conflict with portal host suppression.
18
+ - Move custom gameplay categories to unreserved layers (bits 0 through 23).
19
+ - Update any layer bitmasks (`mask` and `layerMask` queries) that reference layers 24–30.
20
+
21
+ ---
22
+
23
+ ## 2. Aperture Containment Tolerance (0.05 m per Boundary)
24
+
25
+ ### What Changed
26
+ In rc.28, resting contact solvers permitted normal micro-penetration (~2 mm under gravity). For bodies sliding into doorways where the portal aperture started at floor height ($y=0$), the body's lower bounds slightly breached the zero margin, causing the wall host collider to remain active and stopping the body at the frame.
27
+
28
+ In rc.29, aperture containment calculations incorporate an explicit margin tolerance of **0.05 m (5 cm)** per projected boundary:
29
+
30
+ $$|x| + e_x \le \frac{W}{2} + 0.05, \qquad |y| + e_y \le \frac{H}{2} + 0.05$$
31
+
32
+ ### Behavior
33
+ - A centered body can be up to **0.10 m wider** than the opening ($0.05\text{ m}$ on each side) and still pass through without being blocked by the host wall.
34
+ - Bodies that protrude more than 0.05 m past any single boundary remain blocked by the wall collider.
35
+ - Floor-level doorways admit resting boxes and angled approaches smoothly without catching.
36
+
37
+ ---
38
+
39
+ ## 3. KCC Explicit Portals: Pending Body References
40
+
41
+ ### What Changed
42
+ When creating a character controller and a portal pair inside the same `world.edit()` transaction, passing `hostBodyId` as the pending body reference object returned by `edit.createBody()` previously threw `SyntaxError: Cannot convert [object Object] to a BigInt`.
43
+
44
+ In rc.29, character controller portal ingestion automatically resolves pending body references through `physics.resolveBody(ref).id`, accepting raw `BigInt`, number, string, live handle, or pending reference objects.
45
+
46
+ ---
47
+
48
+ ## 4. Checkpoint Output Parity
49
+
50
+ ### What Changed
51
+ `world.checkpointLatest(checkpoint)` now satisfies the full `PhysicsLatestOutputs3D` contract, returning frozen empty arrays for `portalCrossings: []` and `motionBatch: { count: 0, bodies: [] }` on checkpoint reads, guaranteeing strict deep-equality against `world.latest()` on non-crossing frames.
@@ -0,0 +1,67 @@
1
+ # Migrating from Syncplay 6.0.0-rc.31 to rc.32
2
+
3
+ `6.0.0-rc.32` was tagged but not published. `6.0.0-rc.33` is the first published release with these changes, and it adds joint island isolation (C1). Use this guide to move from rc.31 to rc.33.
4
+
5
+ Syncplay `6.0.0-rc.32` implements the complete Wreck Yard feature request roadmap (Sections A through E), delivering deterministic math parity, stable body keys, SI vector helpers, velocity retention aliases, KCC portal diagnostics, and partner test repro fixtures.
6
+
7
+ ---
8
+
9
+ ## 1. Deterministic `pow` and Static Checker (D1)
10
+
11
+ ### What Changed
12
+ - `pow(base, exp)` is now provided as a canonical deterministic float function across `@series-inc/rundot-syncplay`, `/core/deterministic-math`, and `DeterministicMath.pow`.
13
+ - IEEE 754 edge cases, negative bases with integral exponents, special powers ($\pm 0, \pm\infty, \pm 1$), and fractional powers are strictly preserved with bit-identical cross-platform determinism via the minimax/fdlibm standard.
14
+ - The static checker (`checkDeterminism`) now rejects the JavaScript exponentiation operators `**` and `**=` as well as direct calls to ambient `Math.pow`, emitting code `SYNCPLAY_MATH_NON_DETERMINISTIC_OPERATOR` and recommending `pow(base, exp)` from `@series-inc/rundot-syncplay`.
15
+
16
+ ### Action Required
17
+ Replace any usage of `Math.pow(x, y)` or `x ** y` in simulation code with `pow(x, y)`:
18
+ ```ts
19
+ import { pow } from '@series-inc/rundot-syncplay';
20
+ const result = pow(base, exponent);
21
+ ```
22
+
23
+ ---
24
+
25
+ ## 2. Stable Body Keys with O(1) Lookup (D2)
26
+
27
+ ### What Changed
28
+ - Physics body inputs now accept an optional `key?: string` in `createBody({ ..., key: 'chassis-root' })`.
29
+ - Keys must be non-empty, trimmed strings not exceeding 128 characters, and must be unique within the physics world.
30
+ - Worlds provide `world.resolveKey(key: string): PhysicsBodyHandle3D`, performing an $O(1)$ lookup to retrieve the current handle. If the key is not found, `world.resolveKey` throws `SyncplayError` with code `physics.handle-missing`.
31
+ - Query hits (`RaycastHit3D`, `ShapeCastHit3D`) and contact manifolds now annotate the resolved `bodyKey?: string` whenever a colliding body possesses a key.
32
+ - Key-to-body bindings are fully serialized in checkpoint trailers and restored bit-identically across rollback and resimulation.
33
+
34
+ ---
35
+
36
+ ## 3. SI Vector and Coordinate Helpers (D3)
37
+
38
+ ### What Changed
39
+ The root package entrypoint `@series-inc/rundot-syncplay` now provides enhanced `vec3` and `meters3` helpers:
40
+ - `vec3(x, y, z)` or `vec3([x, y, z])` or `vec3({ x, y, z }, scale?)`
41
+ - `meters3(x, y, z)` or `meters3([x, y, z])` or `meters3({ x, y, z }, scale?)`
42
+ These functions construct validated `PhysicsVector3D<Meters>` objects from three coordinate arguments, tuple arrays, or existing vector records with an optional uniform scaling factor.
43
+
44
+ ---
45
+
46
+ ## 4. Linear Velocity Retention Alias (D4)
47
+
48
+ ### What Changed
49
+ - Physics body inputs accept `linearVelocityRetention?: number` as an explicit semantic alternative to `linearDamping`.
50
+ - Worlds provide `world.setBodyLinearVelocityRetention(body, retention)` to update velocity retention at runtime.
51
+ - Specifying both `linearDamping` and `linearVelocityRetention` simultaneously throws `SyncplayError` with code `physics.definition-invalid`.
52
+
53
+ ---
54
+
55
+ ## 5. KCC Portal Diagnostics (D5)
56
+
57
+ ### What Changed
58
+ - Character controller traversal through portals now validates character dimensions against the aperture opening.
59
+ - If a capsule's radius or height exceeds the portal aperture, the KCC step blocks entry, zeros forward velocity toward the aperture plane, and emits a `'portal-blocked'` event with diagnostic reason `'capsule_larger_than_opening'`.
60
+
61
+ ---
62
+
63
+ ## 6. Partner Repro Suite & Provenance Tracking (E1, E2)
64
+
65
+ ### What Changed
66
+ - 26 partner repro fixtures are cataloged under `packages/syncplay/tests/fixtures/wreck-yard/` with cryptographic SHA-256 provenance tracking in `manifest.json`.
67
+ - Zero-tolerance CI tests enforce regression gates across all wall cases, latest-parity crossing frames, and rollback bit-identity.
@@ -0,0 +1,105 @@
1
+ # Migrating from Syncplay 6.0.0-rc.33 to rc.34
2
+
3
+ This release closes the rc.33 gaps that Wreck Yard reported and adds query,
4
+ vehicle, and portal work from the full request list. Each section names what
5
+ changes for a game and what does not.
6
+
7
+ ## Behavior changes
8
+
9
+ ### Portal host walls keep their own collision layers (A4)
10
+
11
+ Before rc.34, a portal host wall took one of the reserved layers 24 to 30, and
12
+ every body mask and every query layer mask silently included those layers. A
13
+ world could have at most 7 host walls.
14
+
15
+ From rc.34:
16
+
17
+ - A host wall keeps the layer and mask you gave it. `readBody(host).layer`
18
+ reports that layer.
19
+ - Body masks and query layer masks are exactly what you set. Layers 24 to 30
20
+ follow the normal rules. A body on layer 30 touches only bodies whose mask
21
+ includes layer 30.
22
+ - A query layer mask now applies to host walls like any other body. To hit a
23
+ host wall with a filtered query, include the host's layer.
24
+ - The number of host walls is limited only by body capacity.
25
+ - The step excludes contacts between a host wall and the bodies inside one of
26
+ its openings. Bodies outside an opening still touch the wall.
27
+
28
+ What to check: if a game relied on bodies on layers 24 to 30 touching
29
+ everything, give the other bodies masks that include those layers.
30
+
31
+ ### Portal checkpoints from rc.28 to rc.33
32
+
33
+ Serialized checkpoints that carry portal state now use portal trailer
34
+ version 2. A version 1 trailer (rc.28 through rc.33) stored the reserved host
35
+ layers and fails to restore with `physics.checkpoint-invalid`. Checkpoints with
36
+ no portal state have no trailer and restore as before. Rollback and late join
37
+ between peers on the same version are not affected.
38
+
39
+ ## Additions
40
+
41
+ ### Unit vectors from the physics entrypoint (D3)
42
+
43
+ Import `vec3` and `meters3` from `@series-inc/rundot-syncplay/physics/3d`.
44
+ The unit-typed form takes an optional scale:
45
+
46
+ ```ts
47
+ import { meters, vec3 } from '@series-inc/rundot-syncplay/physics/3d';
48
+
49
+ const offset = vec3(meters, [1, 2, 3], 0.5); // { x: 0.5, y: 1, z: 1.5 }
50
+ ```
51
+
52
+ The root exports stay as deprecated aliases of the same functions.
53
+
54
+ ### Body keys (D2)
55
+
56
+ - `PhysicsContactEvent3D` declares `bodyKeyA` and `bodyKeyB`.
57
+ - `PhysicsFluidInteraction3D` carries `bodyKey`.
58
+ - `world.resolveKeyId(key)` returns the live body id without reading the body.
59
+
60
+ ### Static checker (D1 follow-up)
61
+
62
+ `Math.sqrt` is allowed: IEEE 754 rounds it correctly in every engine. `pow`,
63
+ `hypot`, and `**` stay flagged.
64
+
65
+ ### Query index (B1)
66
+
67
+ Raycast, overlap, and shape cast use a spatial index. A query tests only the
68
+ bodies whose bounds overlap its own bounds, so its cost no longer grows with
69
+ far bodies. Hits, order, points, and normals are bit-identical to the linear
70
+ scan. `world.queryStats().testedBodies` reports the bodies the last query
71
+ tested. `queryIndex: false` in a world definition selects the linear scan.
72
+
73
+ ### Ray batches and the wheel layer mask (B3)
74
+
75
+ - `world.raycastBatch(queries)` runs 1 to 64 rays and returns each ray's hits.
76
+ The results equal separate `raycast` calls.
77
+ - `DeterministicVehicleDefinition3D.wheelCastLayerMask` lets the wheel rays
78
+ skip layers. A mask of `0xffffffff` gives the same results as no mask.
79
+
80
+ ### Vehicle step cost (C2)
81
+
82
+ The revision 2 vehicle step casts all wheels in one native call and reads its
83
+ support bodies in one batch. The tire solve is unchanged, and results are
84
+ bit-identical to separate reads.
85
+
86
+ ### Queries through portals (A3)
87
+
88
+ `shapeCast` and `overlap` now pass through open portals, like `raycast`. Hits
89
+ found through a portal carry `portalHops` and `portalPath`. A query that must
90
+ ignore portals sets `maxPortalDepth: 0`. The character controller already
91
+ handles portals itself and sets it.
92
+
93
+ ### Portal placement (A5)
94
+
95
+ `fitPortalEnd(world, { hostBodyId, point, normal, up, opening })` returns a
96
+ pose that fits fully on a static box host face, or null. Bodies take
97
+ `portalable: false`, and edits take `setPortalable(body, portalable)`.
98
+
99
+ ### Portal render helpers (A6)
100
+
101
+ Render-only helpers in `/physics/3d`: `portalTransformMatrix3D`,
102
+ `portalVirtualCameraMatrix3D`, `portalExitClipPlane3D`,
103
+ `portalPlaneInCameraSpace3D`, `portalObliqueProjection3D`, `planPortalViews3D`,
104
+ `portalPoseJumpBodyIds3D`, `interpolatePortalBodyPose3D`, and
105
+ `multiplyPortalMatrices`. They do not change the simulation.