@vgai/engine 0.5.15 → 0.5.16

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 (174) hide show
  1. package/dist/adapter/adapter-module.d.ts +228 -17
  2. package/dist/adapter/adapter-module.d.ts.map +1 -1
  3. package/dist/adapter/adapter-module.js +224 -42
  4. package/dist/adapter/authoring-seam-contract.d.ts +530 -0
  5. package/dist/adapter/authoring-seam-contract.d.ts.map +1 -0
  6. package/dist/adapter/authoring-seam-contract.js +162 -0
  7. package/dist/adapter/authoring.d.ts +237 -50
  8. package/dist/adapter/authoring.d.ts.map +1 -1
  9. package/dist/adapter/authoring.js +2 -1
  10. package/dist/adapter/entrypoint-selection-source.d.ts +35 -0
  11. package/dist/adapter/entrypoint-selection-source.d.ts.map +1 -0
  12. package/dist/adapter/entrypoint-selection-source.js +151 -0
  13. package/dist/adapter/finders/scenes-from-entrypoint-selection.d.ts +7 -1
  14. package/dist/adapter/finders/scenes-from-entrypoint-selection.d.ts.map +1 -1
  15. package/dist/adapter/finders/scenes-from-entrypoint-selection.js +142 -21
  16. package/dist/adapter/first-party-systems.d.ts +13 -3
  17. package/dist/adapter/first-party-systems.d.ts.map +1 -1
  18. package/dist/adapter/first-party-systems.js +10 -3
  19. package/dist/adapter/index.d.ts +7 -2
  20. package/dist/adapter/index.d.ts.map +1 -1
  21. package/dist/adapter/index.js +4 -0
  22. package/dist/adapter/ingest/contract-system-adapters.d.ts +1 -1
  23. package/dist/adapter/ingest/contract-system-adapters.d.ts.map +1 -1
  24. package/dist/adapter/ingest/contract-system-adapters.js +13 -25
  25. package/dist/adapter/ingest/game-contract-seams.d.ts +214 -0
  26. package/dist/adapter/ingest/game-contract-seams.d.ts.map +1 -0
  27. package/dist/adapter/ingest/game-contract-seams.js +62 -0
  28. package/dist/adapter/ingest/game-contract.d.ts +5 -3
  29. package/dist/adapter/ingest/game-contract.d.ts.map +1 -1
  30. package/dist/adapter/ingest/game-contract.js +4 -1
  31. package/dist/adapter/ingest/merge-debug-adapters.d.ts +52 -0
  32. package/dist/adapter/ingest/merge-debug-adapters.d.ts.map +1 -0
  33. package/dist/adapter/ingest/merge-debug-adapters.js +141 -0
  34. package/dist/adapter/ingest/observation-debug-adapter.d.ts +56 -0
  35. package/dist/adapter/ingest/observation-debug-adapter.d.ts.map +1 -0
  36. package/dist/adapter/ingest/observation-debug-adapter.js +131 -0
  37. package/dist/adapter/ingest/scene-capture.d.ts +38 -13
  38. package/dist/adapter/ingest/scene-capture.d.ts.map +1 -1
  39. package/dist/adapter/ingest/scene-capture.js +101 -24
  40. package/dist/adapter/ingest/visible-capture-window.d.ts +22 -5
  41. package/dist/adapter/ingest/visible-capture-window.d.ts.map +1 -1
  42. package/dist/adapter/ingest/visible-capture-window.js +46 -7
  43. package/dist/adapter/native-debug-module.d.ts +43 -0
  44. package/dist/adapter/native-debug-module.d.ts.map +1 -0
  45. package/dist/adapter/native-debug-module.js +230 -0
  46. package/dist/adapter/object3d-authoring-subject.d.ts +32 -0
  47. package/dist/adapter/object3d-authoring-subject.d.ts.map +1 -0
  48. package/dist/adapter/object3d-authoring-subject.js +25 -0
  49. package/dist/adapter/root-adapter.d.ts +21 -56
  50. package/dist/adapter/root-adapter.d.ts.map +1 -1
  51. package/dist/adapter/root-adapter.js +4 -20
  52. package/dist/adapter/root-seam-contract.d.ts +124 -0
  53. package/dist/adapter/root-seam-contract.d.ts.map +1 -0
  54. package/dist/adapter/root-seam-contract.js +36 -0
  55. package/dist/adapter/seam-evidence.d.ts +118 -0
  56. package/dist/adapter/seam-evidence.d.ts.map +1 -0
  57. package/dist/adapter/seam-evidence.js +231 -0
  58. package/dist/adapter/setup-three-root-adapter.d.ts +2 -3
  59. package/dist/adapter/setup-three-root-adapter.d.ts.map +1 -1
  60. package/dist/adapter/setup-three-root-adapter.js +2 -3
  61. package/dist/adapter/system-adapter.d.ts +6 -1
  62. package/dist/adapter/system-adapter.d.ts.map +1 -1
  63. package/dist/adapter/system-seam-contract.d.ts +354 -0
  64. package/dist/adapter/system-seam-contract.d.ts.map +1 -0
  65. package/dist/adapter/system-seam-contract.js +95 -0
  66. package/dist/animation/xstate-animation-binding.d.ts +6 -0
  67. package/dist/animation/xstate-animation-binding.d.ts.map +1 -1
  68. package/dist/animation/xstate-animation-binding.js +142 -4
  69. package/dist/asset-formats/collider.d.ts +1 -1
  70. package/dist/asset-formats/mesh.d.ts +2 -2
  71. package/dist/asset-formats/particles.d.ts +1 -1
  72. package/dist/canvas-react/engine-bridge.d.ts +6 -6
  73. package/dist/canvas-react/engine-bridge.d.ts.map +1 -1
  74. package/dist/canvas-react/engine-bridge.js +2 -2
  75. package/dist/canvas-react/index.d.ts +2 -2
  76. package/dist/canvas-react/index.d.ts.map +1 -1
  77. package/dist/canvas-react/index.js +1 -1
  78. package/dist/canvas-react/pixi-react-adapter.d.ts +15 -9
  79. package/dist/canvas-react/pixi-react-adapter.d.ts.map +1 -1
  80. package/dist/canvas-react/pixi-react-adapter.js +43 -29
  81. package/dist/canvas-react/pixi-react-root-factory.d.ts.map +1 -1
  82. package/dist/canvas-react/pixi-react-root-factory.js +4 -0
  83. package/dist/canvas-react/world-context.d.ts +22 -12
  84. package/dist/canvas-react/world-context.d.ts.map +1 -1
  85. package/dist/canvas-react/world-context.js +12 -51
  86. package/dist/ecs/user-data.d.ts +5 -0
  87. package/dist/ecs/user-data.d.ts.map +1 -1
  88. package/dist/ecs/user-data.js +3 -0
  89. package/dist/input/input-manager.d.ts +49 -0
  90. package/dist/input/input-manager.d.ts.map +1 -1
  91. package/dist/input/input-manager.js +127 -0
  92. package/dist/manifest/schema.d.ts +9 -9
  93. package/dist/pixi/authoring.d.ts.map +1 -1
  94. package/dist/pixi/authoring.js +220 -1
  95. package/dist/pixi/ingest.d.ts +2 -1
  96. package/dist/pixi/ingest.d.ts.map +1 -1
  97. package/dist/pixi/ingest.js +4 -2
  98. package/dist/pixi/scene-capture.d.ts +9 -1
  99. package/dist/pixi/scene-capture.d.ts.map +1 -1
  100. package/dist/pixi/scene-capture.js +9 -6
  101. package/dist/render/particles-factory.d.ts +13 -6
  102. package/dist/render/particles-factory.d.ts.map +1 -1
  103. package/dist/render/particles-factory.js +6 -3
  104. package/dist/runtime/create-runtime.d.ts +23 -46
  105. package/dist/runtime/create-runtime.d.ts.map +1 -1
  106. package/dist/runtime/create-runtime.js +22 -67
  107. package/dist/runtime/game.d.ts +29 -71
  108. package/dist/runtime/game.d.ts.map +1 -1
  109. package/dist/runtime/game.js +15 -54
  110. package/dist/runtime/mount-game.d.ts.map +1 -1
  111. package/dist/runtime/mount-game.js +12 -1
  112. package/dist/runtime/mount-manifest.d.ts.map +1 -1
  113. package/dist/runtime/mount-manifest.js +4 -5
  114. package/dist/runtime/types.d.ts +18 -0
  115. package/dist/runtime/types.d.ts.map +1 -1
  116. package/dist/setup/setup-renderer.d.ts +3 -4
  117. package/dist/setup/setup-renderer.d.ts.map +1 -1
  118. package/dist/setup/setup-renderer.js +3 -4
  119. package/dist/world3d-react/engine-bridge.d.ts +1 -1
  120. package/dist/world3d-react/engine-bridge.js +1 -1
  121. package/dist/world3d-react/r3f-adapter.d.ts +7 -0
  122. package/dist/world3d-react/r3f-adapter.d.ts.map +1 -1
  123. package/dist/world3d-react/r3f-adapter.js +50 -21
  124. package/dist/world3d-react/r3f-root-factory.d.ts.map +1 -1
  125. package/dist/world3d-react/r3f-root-factory.js +4 -0
  126. package/dist/world3d-react/world-context.d.ts +9 -3
  127. package/dist/world3d-react/world-context.d.ts.map +1 -1
  128. package/dist/world3d-react/world-context.js +5 -18
  129. package/package.json +1 -1
  130. package/schemas/engine-capabilities.json +7 -7
  131. package/src/adapter/adapter-module.ts +407 -50
  132. package/src/adapter/authoring-seam-contract.ts +211 -0
  133. package/src/adapter/authoring.ts +242 -50
  134. package/src/adapter/entrypoint-selection-source.ts +159 -0
  135. package/src/adapter/finders/scenes-from-entrypoint-selection.ts +159 -28
  136. package/src/adapter/first-party-systems.ts +17 -3
  137. package/src/adapter/index.ts +51 -1
  138. package/src/adapter/ingest/contract-system-adapters.ts +26 -30
  139. package/src/adapter/ingest/game-contract-seams.ts +85 -0
  140. package/src/adapter/ingest/game-contract.ts +9 -4
  141. package/src/adapter/ingest/merge-debug-adapters.ts +193 -0
  142. package/src/adapter/ingest/observation-debug-adapter.ts +158 -0
  143. package/src/adapter/ingest/scene-capture.ts +126 -23
  144. package/src/adapter/ingest/visible-capture-window.ts +63 -9
  145. package/src/adapter/native-debug-module.ts +307 -0
  146. package/src/adapter/object3d-authoring-subject.ts +50 -0
  147. package/src/adapter/root-adapter.ts +21 -56
  148. package/src/adapter/root-seam-contract.ts +56 -0
  149. package/src/adapter/seam-evidence.ts +336 -0
  150. package/src/adapter/setup-three-root-adapter.ts +4 -6
  151. package/src/adapter/system-adapter.ts +6 -1
  152. package/src/adapter/system-seam-contract.ts +121 -0
  153. package/src/animation/xstate-animation-binding.ts +151 -4
  154. package/src/canvas-react/engine-bridge.ts +6 -6
  155. package/src/canvas-react/index.ts +2 -1
  156. package/src/canvas-react/pixi-react-adapter.tsx +55 -34
  157. package/src/canvas-react/pixi-react-root-factory.tsx +4 -0
  158. package/src/canvas-react/world-context.ts +26 -101
  159. package/src/ecs/user-data.ts +5 -0
  160. package/src/input/input-manager.ts +122 -0
  161. package/src/pixi/authoring.ts +236 -1
  162. package/src/pixi/ingest.ts +9 -2
  163. package/src/pixi/scene-capture.ts +20 -5
  164. package/src/render/particles-factory.ts +16 -6
  165. package/src/runtime/create-runtime.ts +41 -106
  166. package/src/runtime/game.ts +41 -111
  167. package/src/runtime/mount-game.ts +19 -1
  168. package/src/runtime/mount-manifest.ts +4 -5
  169. package/src/runtime/types.ts +22 -0
  170. package/src/setup/setup-renderer.ts +3 -4
  171. package/src/world3d-react/engine-bridge.ts +1 -1
  172. package/src/world3d-react/r3f-adapter.tsx +64 -24
  173. package/src/world3d-react/r3f-root-factory.tsx +4 -0
  174. package/src/world3d-react/world-context.ts +11 -36
@@ -0,0 +1,354 @@
1
+ /** Exhaustive proof requirements for mounted SystemAdapters. A bound slot is
2
+ * availability, not success: each nested operation has its own required proof
3
+ * stage and therefore cannot hide behind `active[slot] != null`. */
4
+ import { type SeamShape } from './seam-evidence';
5
+ import type { SystemAdapters } from './system-adapter';
6
+ export declare const SYSTEM_ADAPTERS_SHAPE: {
7
+ readonly physics: {
8
+ readonly optional: true;
9
+ readonly kind: "value";
10
+ readonly required: "effect";
11
+ };
12
+ readonly networking: {
13
+ readonly optional: true;
14
+ readonly kind: "value";
15
+ readonly required: "operation";
16
+ };
17
+ readonly navigation: {
18
+ readonly optional: true;
19
+ readonly kind: "value";
20
+ readonly required: "operation";
21
+ };
22
+ readonly audio: {
23
+ readonly optional: true;
24
+ readonly kind: "value";
25
+ readonly required: "effect";
26
+ };
27
+ readonly camera: {
28
+ readonly optional: true;
29
+ readonly kind: "value";
30
+ readonly required: "effect";
31
+ };
32
+ readonly debug: {
33
+ readonly optional: true;
34
+ readonly kind: "value";
35
+ readonly required: "operation";
36
+ };
37
+ readonly renderDebug: {
38
+ readonly optional: true;
39
+ readonly kind: "value";
40
+ readonly required: "effect";
41
+ };
42
+ };
43
+ export declare const PHYSICS_ADAPTER_SHAPE: {
44
+ readonly keyedBy: {
45
+ readonly optional: true;
46
+ readonly kind: "value";
47
+ readonly required: "shape";
48
+ };
49
+ readonly ownerOf: {
50
+ readonly optional: false;
51
+ readonly kind: "function";
52
+ readonly required: "operation";
53
+ };
54
+ readonly freeze: {
55
+ readonly optional: false;
56
+ readonly kind: "function";
57
+ readonly required: "effect";
58
+ };
59
+ readonly commit: {
60
+ readonly optional: false;
61
+ readonly kind: "function";
62
+ readonly required: "effect";
63
+ };
64
+ readonly unfreeze: {
65
+ readonly optional: false;
66
+ readonly kind: "function";
67
+ readonly required: "effect";
68
+ };
69
+ readonly debugDraw: {
70
+ readonly optional: true;
71
+ readonly kind: "function";
72
+ readonly required: "operation";
73
+ };
74
+ readonly setDebugDrawEnabled: {
75
+ readonly optional: true;
76
+ readonly kind: "function";
77
+ readonly required: "effect";
78
+ };
79
+ readonly contactPoints: {
80
+ readonly optional: true;
81
+ readonly kind: "function";
82
+ readonly required: "operation";
83
+ };
84
+ readonly colliders: {
85
+ readonly optional: true;
86
+ readonly kind: "function";
87
+ readonly required: "operation";
88
+ };
89
+ readonly previewCollider: {
90
+ readonly optional: true;
91
+ readonly kind: "function";
92
+ readonly required: "effect";
93
+ };
94
+ readonly joints: {
95
+ readonly optional: true;
96
+ readonly kind: "function";
97
+ readonly required: "operation";
98
+ };
99
+ readonly previewJointAnchor: {
100
+ readonly optional: true;
101
+ readonly kind: "function";
102
+ readonly required: "effect";
103
+ };
104
+ };
105
+ export declare const PHYSICS_2D_ADAPTER_SHAPE: {
106
+ readonly keyedBy: {
107
+ readonly optional: false;
108
+ readonly kind: "value";
109
+ readonly required: "shape";
110
+ };
111
+ readonly ownerOf: {
112
+ readonly optional: false;
113
+ readonly kind: "function";
114
+ readonly required: "operation";
115
+ };
116
+ readonly freeze: {
117
+ readonly optional: false;
118
+ readonly kind: "function";
119
+ readonly required: "effect";
120
+ };
121
+ readonly commit: {
122
+ readonly optional: false;
123
+ readonly kind: "function";
124
+ readonly required: "effect";
125
+ };
126
+ readonly unfreeze: {
127
+ readonly optional: false;
128
+ readonly kind: "function";
129
+ readonly required: "effect";
130
+ };
131
+ };
132
+ export declare const NETWORKING_ADAPTER_SHAPE: {
133
+ readonly peers: {
134
+ readonly optional: false;
135
+ readonly kind: "function";
136
+ readonly required: "operation";
137
+ };
138
+ readonly networkId: {
139
+ readonly optional: false;
140
+ readonly kind: "function";
141
+ readonly required: "operation";
142
+ };
143
+ readonly authority: {
144
+ readonly optional: false;
145
+ readonly kind: "function";
146
+ readonly required: "operation";
147
+ };
148
+ readonly editable: {
149
+ readonly optional: false;
150
+ readonly kind: "function";
151
+ readonly required: "operation";
152
+ };
153
+ readonly getConnectionState: {
154
+ readonly optional: false;
155
+ readonly kind: "function";
156
+ readonly required: "operation";
157
+ };
158
+ readonly getRoomInfo: {
159
+ readonly optional: false;
160
+ readonly kind: "function";
161
+ readonly required: "operation";
162
+ };
163
+ readonly getReplicationStats: {
164
+ readonly optional: false;
165
+ readonly kind: "function";
166
+ readonly required: "operation";
167
+ };
168
+ readonly subscribe: {
169
+ readonly optional: false;
170
+ readonly kind: "function";
171
+ readonly required: "effect";
172
+ };
173
+ readonly getStateSnapshot: {
174
+ readonly optional: true;
175
+ readonly kind: "function";
176
+ readonly required: "operation";
177
+ };
178
+ readonly messageEvents: {
179
+ readonly optional: true;
180
+ readonly kind: "function";
181
+ readonly required: "operation";
182
+ };
183
+ readonly getRates: {
184
+ readonly optional: true;
185
+ readonly kind: "function";
186
+ readonly required: "operation";
187
+ };
188
+ readonly getConditioning: {
189
+ readonly optional: true;
190
+ readonly kind: "function";
191
+ readonly required: "operation";
192
+ };
193
+ readonly setConditioning: {
194
+ readonly optional: true;
195
+ readonly kind: "function";
196
+ readonly required: "effect";
197
+ };
198
+ readonly getServerConfig: {
199
+ readonly optional: true;
200
+ readonly kind: "function";
201
+ readonly required: "operation";
202
+ };
203
+ readonly getPlayerIdentity: {
204
+ readonly optional: true;
205
+ readonly kind: "function";
206
+ readonly required: "operation";
207
+ };
208
+ readonly setPlayerIdentity: {
209
+ readonly optional: true;
210
+ readonly kind: "function";
211
+ readonly required: "effect";
212
+ };
213
+ };
214
+ export declare const NAVIGATION_ADAPTER_SHAPE: {
215
+ readonly hasNavMesh: {
216
+ readonly optional: false;
217
+ readonly kind: "function";
218
+ readonly required: "operation";
219
+ };
220
+ readonly findPath: {
221
+ readonly optional: false;
222
+ readonly kind: "function";
223
+ readonly required: "effect";
224
+ };
225
+ readonly debugMesh: {
226
+ readonly optional: false;
227
+ readonly kind: "function";
228
+ readonly required: "operation";
229
+ };
230
+ readonly bake: {
231
+ readonly optional: true;
232
+ readonly kind: "function";
233
+ readonly required: "effect";
234
+ };
235
+ readonly exportData: {
236
+ readonly optional: true;
237
+ readonly kind: "function";
238
+ readonly required: "operation";
239
+ };
240
+ readonly clear: {
241
+ readonly optional: true;
242
+ readonly kind: "function";
243
+ readonly required: "effect";
244
+ };
245
+ readonly crowdAgents: {
246
+ readonly optional: true;
247
+ readonly kind: "function";
248
+ readonly required: "operation";
249
+ };
250
+ };
251
+ export declare const AUDIO_ADAPTER_SHAPE: {
252
+ readonly resume: {
253
+ readonly optional: true;
254
+ readonly kind: "function";
255
+ readonly required: "effect";
256
+ };
257
+ readonly setMuted: {
258
+ readonly optional: false;
259
+ readonly kind: "function";
260
+ readonly required: "effect";
261
+ };
262
+ readonly isMuted: {
263
+ readonly optional: false;
264
+ readonly kind: "function";
265
+ readonly required: "operation";
266
+ };
267
+ readonly graphSnapshot: {
268
+ readonly optional: true;
269
+ readonly kind: "function";
270
+ readonly required: "operation";
271
+ };
272
+ readonly transportState: {
273
+ readonly optional: true;
274
+ readonly kind: "function";
275
+ readonly required: "operation";
276
+ };
277
+ readonly acquireMeters: {
278
+ readonly optional: true;
279
+ readonly kind: "function";
280
+ readonly required: "effect";
281
+ };
282
+ readonly acquireRecordingStream: {
283
+ readonly optional: true;
284
+ readonly kind: "function";
285
+ readonly required: "effect";
286
+ };
287
+ readonly audioEvents: {
288
+ readonly optional: true;
289
+ readonly kind: "function";
290
+ readonly required: "operation";
291
+ };
292
+ };
293
+ export declare const CAMERA_ADAPTER_SHAPE: {
294
+ readonly snapshot: {
295
+ readonly optional: false;
296
+ readonly kind: "function";
297
+ readonly required: "operation";
298
+ };
299
+ readonly subscribe: {
300
+ readonly optional: false;
301
+ readonly kind: "function";
302
+ readonly required: "effect";
303
+ };
304
+ };
305
+ export declare const DEBUG_ADAPTER_SHAPE: {
306
+ readonly providers: {
307
+ readonly optional: false;
308
+ readonly kind: "function";
309
+ readonly required: "operation";
310
+ };
311
+ readonly state: {
312
+ readonly optional: false;
313
+ readonly kind: "function";
314
+ readonly required: "operation";
315
+ };
316
+ readonly stateAll: {
317
+ readonly optional: false;
318
+ readonly kind: "function";
319
+ readonly required: "operation";
320
+ };
321
+ readonly commands: {
322
+ readonly optional: false;
323
+ readonly kind: "function";
324
+ readonly required: "operation";
325
+ };
326
+ readonly invoke: {
327
+ readonly optional: false;
328
+ readonly kind: "function";
329
+ readonly required: "effect";
330
+ };
331
+ readonly events: {
332
+ readonly optional: false;
333
+ readonly kind: "function";
334
+ readonly required: "operation";
335
+ };
336
+ };
337
+ export declare const RENDER_DEBUG_ADAPTER_SHAPE: {
338
+ readonly captureFrame: {
339
+ readonly optional: false;
340
+ readonly kind: "function";
341
+ readonly required: "effect";
342
+ };
343
+ readonly memorySnapshot: {
344
+ readonly optional: true;
345
+ readonly kind: "function";
346
+ readonly required: "operation";
347
+ };
348
+ };
349
+ type NonPhysicsSystemSlot = Exclude<keyof SystemAdapters, 'physics'>;
350
+ export declare const SYSTEM_PROVIDER_SHAPES: {
351
+ readonly [K in NonPhysicsSystemSlot]: SeamShape<NonNullable<SystemAdapters[K]>>;
352
+ };
353
+ export {};
354
+ //# sourceMappingURL=system-seam-contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-seam-contract.d.ts","sourceRoot":"","sources":["../../src/adapter/system-seam-contract.ts"],"names":[],"mappings":"AAAA;;oEAEoE;AAGpE,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,KAAK,EAQV,cAAc,EACf,MAAM,kBAAkB,CAAC;AAE1B,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAQhC,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAahC,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;CAMnC,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiBnC,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAQnC,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAS9B,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;CAG/B,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAO9B,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;;;;;;;;CAGrC,CAAC;AAEH,KAAK,oBAAoB,GAAG,OAAO,CAAC,MAAM,cAAc,EAAE,SAAS,CAAC,CAAC;AAErE,eAAO,MAAM,sBAAsB,EAAE;IACnC,QAAQ,EAAE,CAAC,IAAI,oBAAoB,GAAG,SAAS,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;CAQhF,CAAC"}
@@ -0,0 +1,95 @@
1
+ /** Exhaustive proof requirements for mounted SystemAdapters. A bound slot is
2
+ * availability, not success: each nested operation has its own required proof
3
+ * stage and therefore cannot hide behind `active[slot] != null`. */
4
+ import { defineSeamShape } from './seam-evidence';
5
+ export const SYSTEM_ADAPTERS_SHAPE = defineSeamShape()({
6
+ physics: { optional: true, kind: 'value', required: 'effect' },
7
+ networking: { optional: true, kind: 'value', required: 'operation' },
8
+ navigation: { optional: true, kind: 'value', required: 'operation' },
9
+ audio: { optional: true, kind: 'value', required: 'effect' },
10
+ camera: { optional: true, kind: 'value', required: 'effect' },
11
+ debug: { optional: true, kind: 'value', required: 'operation' },
12
+ renderDebug: { optional: true, kind: 'value', required: 'effect' },
13
+ });
14
+ export const PHYSICS_ADAPTER_SHAPE = defineSeamShape()({
15
+ keyedBy: { optional: true, kind: 'value', required: 'shape' },
16
+ ownerOf: { optional: false, kind: 'function', required: 'operation' },
17
+ freeze: { optional: false, kind: 'function', required: 'effect' },
18
+ commit: { optional: false, kind: 'function', required: 'effect' },
19
+ unfreeze: { optional: false, kind: 'function', required: 'effect' },
20
+ debugDraw: { optional: true, kind: 'function', required: 'operation' },
21
+ setDebugDrawEnabled: { optional: true, kind: 'function', required: 'effect' },
22
+ contactPoints: { optional: true, kind: 'function', required: 'operation' },
23
+ colliders: { optional: true, kind: 'function', required: 'operation' },
24
+ previewCollider: { optional: true, kind: 'function', required: 'effect' },
25
+ joints: { optional: true, kind: 'function', required: 'operation' },
26
+ previewJointAnchor: { optional: true, kind: 'function', required: 'effect' },
27
+ });
28
+ export const PHYSICS_2D_ADAPTER_SHAPE = defineSeamShape()({
29
+ keyedBy: { optional: false, kind: 'value', required: 'shape' },
30
+ ownerOf: { optional: false, kind: 'function', required: 'operation' },
31
+ freeze: { optional: false, kind: 'function', required: 'effect' },
32
+ commit: { optional: false, kind: 'function', required: 'effect' },
33
+ unfreeze: { optional: false, kind: 'function', required: 'effect' },
34
+ });
35
+ export const NETWORKING_ADAPTER_SHAPE = defineSeamShape()({
36
+ peers: { optional: false, kind: 'function', required: 'operation' },
37
+ networkId: { optional: false, kind: 'function', required: 'operation' },
38
+ authority: { optional: false, kind: 'function', required: 'operation' },
39
+ editable: { optional: false, kind: 'function', required: 'operation' },
40
+ getConnectionState: { optional: false, kind: 'function', required: 'operation' },
41
+ getRoomInfo: { optional: false, kind: 'function', required: 'operation' },
42
+ getReplicationStats: { optional: false, kind: 'function', required: 'operation' },
43
+ subscribe: { optional: false, kind: 'function', required: 'effect' },
44
+ getStateSnapshot: { optional: true, kind: 'function', required: 'operation' },
45
+ messageEvents: { optional: true, kind: 'function', required: 'operation' },
46
+ getRates: { optional: true, kind: 'function', required: 'operation' },
47
+ getConditioning: { optional: true, kind: 'function', required: 'operation' },
48
+ setConditioning: { optional: true, kind: 'function', required: 'effect' },
49
+ getServerConfig: { optional: true, kind: 'function', required: 'operation' },
50
+ getPlayerIdentity: { optional: true, kind: 'function', required: 'operation' },
51
+ setPlayerIdentity: { optional: true, kind: 'function', required: 'effect' },
52
+ });
53
+ export const NAVIGATION_ADAPTER_SHAPE = defineSeamShape()({
54
+ hasNavMesh: { optional: false, kind: 'function', required: 'operation' },
55
+ findPath: { optional: false, kind: 'function', required: 'effect' },
56
+ debugMesh: { optional: false, kind: 'function', required: 'operation' },
57
+ bake: { optional: true, kind: 'function', required: 'effect' },
58
+ exportData: { optional: true, kind: 'function', required: 'operation' },
59
+ clear: { optional: true, kind: 'function', required: 'effect' },
60
+ crowdAgents: { optional: true, kind: 'function', required: 'operation' },
61
+ });
62
+ export const AUDIO_ADAPTER_SHAPE = defineSeamShape()({
63
+ resume: { optional: true, kind: 'function', required: 'effect' },
64
+ setMuted: { optional: false, kind: 'function', required: 'effect' },
65
+ isMuted: { optional: false, kind: 'function', required: 'operation' },
66
+ graphSnapshot: { optional: true, kind: 'function', required: 'operation' },
67
+ transportState: { optional: true, kind: 'function', required: 'operation' },
68
+ acquireMeters: { optional: true, kind: 'function', required: 'effect' },
69
+ acquireRecordingStream: { optional: true, kind: 'function', required: 'effect' },
70
+ audioEvents: { optional: true, kind: 'function', required: 'operation' },
71
+ });
72
+ export const CAMERA_ADAPTER_SHAPE = defineSeamShape()({
73
+ snapshot: { optional: false, kind: 'function', required: 'operation' },
74
+ subscribe: { optional: false, kind: 'function', required: 'effect' },
75
+ });
76
+ export const DEBUG_ADAPTER_SHAPE = defineSeamShape()({
77
+ providers: { optional: false, kind: 'function', required: 'operation' },
78
+ state: { optional: false, kind: 'function', required: 'operation' },
79
+ stateAll: { optional: false, kind: 'function', required: 'operation' },
80
+ commands: { optional: false, kind: 'function', required: 'operation' },
81
+ invoke: { optional: false, kind: 'function', required: 'effect' },
82
+ events: { optional: false, kind: 'function', required: 'operation' },
83
+ });
84
+ export const RENDER_DEBUG_ADAPTER_SHAPE = defineSeamShape()({
85
+ captureFrame: { optional: false, kind: 'function', required: 'effect' },
86
+ memorySnapshot: { optional: true, kind: 'function', required: 'operation' },
87
+ });
88
+ export const SYSTEM_PROVIDER_SHAPES = {
89
+ networking: NETWORKING_ADAPTER_SHAPE,
90
+ navigation: NAVIGATION_ADAPTER_SHAPE,
91
+ audio: AUDIO_ADAPTER_SHAPE,
92
+ camera: CAMERA_ADAPTER_SHAPE,
93
+ debug: DEBUG_ADAPTER_SHAPE,
94
+ renderDebug: RENDER_DEBUG_ADAPTER_SHAPE,
95
+ };
@@ -78,6 +78,12 @@ export interface XStateAnimationBindingOptions {
78
78
  * omitted, the caller owns ticking (useful for standalone Three tests).
79
79
  */
80
80
  systems?: Pick<ReturnType<typeof createSystemRunner>, 'add' | 'remove'>;
81
+ /**
82
+ * Publish a seekable transport for an isolated design-time mount such as a
83
+ * CSF story. Never enable this on the live game binding: runtime inspection
84
+ * stays read-only there, while the story deliberately owns this preview.
85
+ */
86
+ previewTransport?: boolean;
81
87
  }
82
88
  export interface XStateAnimationLayerState {
83
89
  readonly layer: string;
@@ -1 +1 @@
1
- {"version":3,"file":"xstate-animation-binding.d.ts","sourceRoot":"","sources":["../../src/animation/xstate-animation-binding.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAKhE,OAAO,EACL,KAAK,iBAAiB,EAOvB,MAAM,yBAAyB,CAAC;AAEjC;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC;mFAC+E;IAC/E,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B;wEACoE;IACpE,QAAQ,CAAC,OAAO,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,uBAAuB,CAAC;IACpD,QAAQ,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,uBAAuB,KAAK,IAAI,KAAK;QACzE,WAAW,EAAE,MAAM,IAAI,CAAC;KACzB,CAAC;CACH;AAED,+EAA+E;AAC/E,qBAAa,qBAAsB,SAAQ,KAAK;IAG5C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM;gBADzB,OAAO,EAAE,MAAM,EACN,OAAO,CAAC,EAAE,MAAM,YAAA;CAK5B;AAED;;;oCAGoC;AACpC,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,oBAAoB,GAAG,eAAe,CASjF;AAED,MAAM,WAAW,6BAA6B;IAC5C,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC;IAC1E,8FAA8F;IAC9F,IAAI,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC;IACtB,yFAAyF;IACzF,KAAK,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC;IACvB;;;;OAIG;IACH,OAAO,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO,kBAAkB,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC,CAAC;CACzE;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,+EAA+E;IAC/E,QAAQ,CAAC,WAAW,EAAE,SAAS;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACpF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,UAAU,GAAG,UAAU,CAAC;IAC5C,QAAQ,CAAC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAED,MAAM,WAAW,sBAAsB;IACrC,iFAAiF;IACjF,IAAI,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,oBAAoB,CAAC;IACrC;;kFAE8E;IAC9E,aAAa,EAAE,MAAM,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC;IAC3D,6EAA6E;IAC7E,eAAe,EAAE,MAAM,SAAS,yBAAyB,EAAE,CAAC;IAC5D,uFAAuF;IACvF,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAKD,yFAAyF;AACzF,wBAAgB,gCAAgC,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAGjF;AAED,6EAA6E;AAC7E,wBAAgB,iCAAiC,IAAI,MAAM,CAE1D;AAqGD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,oBAAoB,EAC3B,KAAK,EAAE,KAAK,CAAC,cAAc,EAC3B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC,EACvC,OAAO,GAAE,6BAAkC,GAC1C,sBAAsB,CAqSxB"}
1
+ {"version":3,"file":"xstate-animation-binding.d.ts","sourceRoot":"","sources":["../../src/animation/xstate-animation-binding.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import * as THREE from 'three';
2
2
  import { deleteUserData, getUserData, setUserData } from '../ecs/user-data';
3
3
  import { evaluateBlendTree } from './blend-node';
4
- import { attachAnimationRuntimeInspection } from './runtime-inspection';
4
+ import { attachAnimationRuntimeInspection, } from './runtime-inspection';
5
5
  import { clipNamesOf, collectMachineAnimationMeta, isBlendTreeAnimationMeta, } from './xstate-animation-meta';
6
6
  /** A binding-time problem such as a missing clip, bone, or ambiguous layer. */
7
7
  export class AnimationBindingError extends Error {
@@ -199,6 +199,83 @@ export function bindXStateAnimation(actor, mixer, clips, options = {}) {
199
199
  const activeLayers = new Map();
200
200
  let disposed = false;
201
201
  let detachRuntimeInspection = () => { };
202
+ let previewClip = null;
203
+ let previewAction = null;
204
+ let previewPlaying = true;
205
+ let previewLoop = true;
206
+ let previewSpeed = 1;
207
+ function controllerPreviewSubject() {
208
+ const layers = [activeLayers.get('base'), ...activeLayers.values()].filter((active, index, all) => Boolean(active) && all.indexOf(active) === index);
209
+ for (const active of layers) {
210
+ const weighted = [...active.natural].sort((left, right) => {
211
+ const leftWeight = actionCache.get(left.actionKey)?.action.getEffectiveWeight() ?? 0;
212
+ const rightWeight = actionCache.get(right.actionKey)?.action.getEffectiveWeight() ?? 0;
213
+ return rightWeight - leftWeight;
214
+ })[0];
215
+ if (weighted) {
216
+ return {
217
+ clip: weighted.clip,
218
+ action: actionCache.get(weighted.actionKey)?.action ?? null,
219
+ };
220
+ }
221
+ }
222
+ return { clip: clips.keys().next().value ?? '', action: null };
223
+ }
224
+ function actionIsControllerOwned(action) {
225
+ for (const cached of actionCache.values()) {
226
+ if (cached.action === action)
227
+ return true;
228
+ }
229
+ return false;
230
+ }
231
+ function releasePreviewAction() {
232
+ const action = previewAction;
233
+ if (!action)
234
+ return;
235
+ action.stop();
236
+ if (!actionIsControllerOwned(action)) {
237
+ mixer.uncacheAction(action.getClip(), action.getRoot());
238
+ }
239
+ previewAction = null;
240
+ }
241
+ function enterClipPreview(name) {
242
+ const clip = clips.get(name);
243
+ if (!clip)
244
+ return;
245
+ releasePreviewAction();
246
+ previewClip = name;
247
+ for (const cached of actionCache.values())
248
+ cached.action.setEffectiveWeight(0);
249
+ const action = mixer.clipAction(clip).reset().play();
250
+ action.setEffectiveWeight(1);
251
+ action.setEffectiveTimeScale(1);
252
+ action.setLoop(previewLoop ? THREE.LoopRepeat : THREE.LoopOnce, previewLoop ? Infinity : 1);
253
+ action.clampWhenFinished = !previewLoop;
254
+ previewAction = action;
255
+ mixer.update(0);
256
+ }
257
+ function restoreControllerPreview() {
258
+ releasePreviewAction();
259
+ previewClip = null;
260
+ const snapshot = actor.getSnapshot();
261
+ reconcile(snapshot);
262
+ const context = snapshot.context;
263
+ for (const cached of actionCache.values())
264
+ cached.action.setEffectiveWeight(0);
265
+ for (const active of activeLayers.values()) {
266
+ active.crossfadeRemaining = 0;
267
+ active.natural = weightsOf(active.stateId, active.meta, context);
268
+ const loop = isBlendTreeAnimationMeta(active.meta) ? true : active.meta.loop;
269
+ const speed = isBlendTreeAnimationMeta(active.meta) ? 1 : active.meta.speed;
270
+ const layerWeight = layerWeightOf(active.meta);
271
+ for (const weighted of active.natural) {
272
+ ensureAction(weighted.actionKey, loop, speed, layerWeight)
273
+ .play()
274
+ .setEffectiveWeight(weighted.weight * layerWeight);
275
+ }
276
+ }
277
+ mixer.update(0);
278
+ }
202
279
  function silence(weights, except, duration) {
203
280
  for (const weighted of weights) {
204
281
  if (weighted.actionKey === except)
@@ -296,16 +373,29 @@ export function bindXStateAnimation(actor, mixer, clips, options = {}) {
296
373
  const initialSnapshot = actor.getSnapshot();
297
374
  reconcile(initialSnapshot);
298
375
  const subscription = actor.subscribe((snapshot) => {
299
- if (!disposed)
376
+ // Isolated clip review deliberately holds behavior output. The actor may
377
+ // keep receiving story args, but its latest state is reconciled only when
378
+ // the user returns to Controller.
379
+ if (!disposed && !previewClip)
300
380
  reconcile(snapshot);
301
381
  });
302
382
  function tick(dt) {
303
383
  if (disposed)
304
384
  return;
385
+ if (options.previewTransport && !previewPlaying)
386
+ return;
387
+ const elapsed = dt * (options.previewTransport ? previewSpeed : 1);
388
+ if (options.previewTransport && previewClip && previewAction) {
389
+ mixer.update(elapsed);
390
+ const clip = clips.get(previewClip);
391
+ if (!previewLoop && clip && previewAction.time >= clip.duration)
392
+ previewPlaying = false;
393
+ return;
394
+ }
305
395
  const context = actor.getSnapshot().context;
306
396
  for (const active of activeLayers.values()) {
307
397
  if (active.crossfadeRemaining > 0) {
308
- active.crossfadeRemaining = Math.max(0, active.crossfadeRemaining - dt);
398
+ active.crossfadeRemaining = Math.max(0, active.crossfadeRemaining - elapsed);
309
399
  if (active.crossfadeRemaining <= 0)
310
400
  applyLiveBlendWeights(active, context);
311
401
  }
@@ -313,8 +403,54 @@ export function bindXStateAnimation(actor, mixer, clips, options = {}) {
313
403
  applyLiveBlendWeights(active, context);
314
404
  }
315
405
  }
316
- mixer.update(dt);
406
+ mixer.update(elapsed);
317
407
  }
408
+ const previewTransport = options.previewTransport
409
+ ? {
410
+ getSnapshot: () => {
411
+ const controller = controllerPreviewSubject();
412
+ return {
413
+ clip: previewClip ?? controller.clip,
414
+ time: previewClip ? (previewAction?.time ?? 0) : (controller.action?.time ?? 0),
415
+ playing: previewPlaying,
416
+ loop: previewLoop,
417
+ speed: previewSpeed,
418
+ mode: previewClip ? 'clip' : 'controller',
419
+ };
420
+ },
421
+ setPlaying(playing) {
422
+ previewPlaying = playing;
423
+ },
424
+ setLoop(loop) {
425
+ previewLoop = loop;
426
+ if (!previewClip)
427
+ enterClipPreview(controllerPreviewSubject().clip);
428
+ previewAction?.setLoop(loop ? THREE.LoopRepeat : THREE.LoopOnce, loop ? Infinity : 1);
429
+ if (previewAction)
430
+ previewAction.clampWhenFinished = !loop;
431
+ },
432
+ setSpeed(speed) {
433
+ previewSpeed = THREE.MathUtils.clamp(speed, 0.05, 4);
434
+ },
435
+ seek(time) {
436
+ if (!previewClip)
437
+ enterClipPreview(controllerPreviewSubject().clip);
438
+ const clip = previewClip ? clips.get(previewClip) : undefined;
439
+ if (!clip || !previewAction)
440
+ return;
441
+ previewAction.time = THREE.MathUtils.clamp(time, 0, Math.max(clip.duration, 0));
442
+ mixer.update(0);
443
+ },
444
+ setClip(name) {
445
+ if (name === null) {
446
+ if (previewClip)
447
+ restoreControllerPreview();
448
+ return;
449
+ }
450
+ enterClipPreview(name);
451
+ },
452
+ }
453
+ : undefined;
318
454
  const binding = {
319
455
  tick,
320
456
  actor,
@@ -336,6 +472,7 @@ export function bindXStateAnimation(actor, mixer, clips, options = {}) {
336
472
  return;
337
473
  disposed = true;
338
474
  detachRuntimeInspection();
475
+ releasePreviewAction();
339
476
  options.systems?.remove('animation', tick);
340
477
  subscription.unsubscribe();
341
478
  for (const { action, clip } of actionCache.values()) {
@@ -353,6 +490,7 @@ export function bindXStateAnimation(actor, mixer, clips, options = {}) {
353
490
  detachRuntimeInspection = attachAnimationRuntimeInspection(owner, {
354
491
  mixer,
355
492
  clips,
493
+ ...(previewTransport ? { previewTransport } : {}),
356
494
  getSnapshot: () => ({
357
495
  layers: [...activeLayers.values()].map((active) => {
358
496
  const parameters = readParameters(actor.getSnapshot().context);
@@ -1,9 +1,9 @@
1
1
  import { z } from 'zod';
2
2
  export declare const ColliderDescriptorSchema: z.ZodObject<{
3
3
  type: z.ZodEnum<{
4
+ capsule: "capsule";
4
5
  cuboid: "cuboid";
5
6
  ball: "ball";
6
- capsule: "capsule";
7
7
  trimesh: "trimesh";
8
8
  }>;
9
9
  halfExtents: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;