@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,214 @@
1
+ /** Exhaustive proof requirements for the game→host contract. Declarations are
2
+ * intentionally insufficient for lifecycle, navigation, commands, state, and
3
+ * system carriers: their consumers must produce stronger receipts. */
4
+ export declare const GAME_CONTRACT_SHAPE: {
5
+ readonly contractVersion: {
6
+ readonly optional: false;
7
+ readonly kind: "value";
8
+ readonly required: "shape";
9
+ };
10
+ readonly root: {
11
+ readonly optional: true;
12
+ readonly kind: "value";
13
+ readonly required: "effect";
14
+ };
15
+ readonly presentation: {
16
+ readonly optional: true;
17
+ readonly kind: "value";
18
+ readonly required: "effect";
19
+ };
20
+ readonly world: {
21
+ readonly optional: true;
22
+ readonly kind: "value";
23
+ readonly required: "effect";
24
+ };
25
+ readonly ready: {
26
+ readonly optional: true;
27
+ readonly kind: "value";
28
+ readonly required: "effect";
29
+ };
30
+ readonly lifecycle: {
31
+ readonly optional: true;
32
+ readonly kind: "value";
33
+ readonly required: "effect";
34
+ };
35
+ readonly scenes: {
36
+ readonly optional: true;
37
+ readonly kind: "value";
38
+ readonly required: "effect";
39
+ };
40
+ readonly systems: {
41
+ readonly optional: true;
42
+ readonly kind: "value";
43
+ readonly required: "operation";
44
+ };
45
+ };
46
+ export declare const GAME_LIFECYCLE_SHAPE: {
47
+ readonly start: {
48
+ readonly optional: true;
49
+ readonly kind: "function";
50
+ readonly required: "effect";
51
+ };
52
+ readonly pause: {
53
+ readonly optional: true;
54
+ readonly kind: "function";
55
+ readonly required: "effect";
56
+ };
57
+ readonly resume: {
58
+ readonly optional: true;
59
+ readonly kind: "function";
60
+ readonly required: "effect";
61
+ };
62
+ };
63
+ export declare const GAME_SCENES_SHAPE: {
64
+ readonly list: {
65
+ readonly optional: false;
66
+ readonly kind: "function";
67
+ readonly required: "operation";
68
+ };
69
+ readonly current: {
70
+ readonly optional: false;
71
+ readonly kind: "function";
72
+ readonly required: "operation";
73
+ };
74
+ readonly goTo: {
75
+ readonly optional: false;
76
+ readonly kind: "function";
77
+ readonly required: "effect";
78
+ };
79
+ };
80
+ export declare const GAME_SCENE_SHAPE: {
81
+ readonly id: {
82
+ readonly optional: false;
83
+ readonly kind: "value";
84
+ readonly required: "shape";
85
+ };
86
+ readonly label: {
87
+ readonly optional: false;
88
+ readonly kind: "value";
89
+ readonly required: "shape";
90
+ };
91
+ };
92
+ export declare const GAME_COMMAND_SHAPE: {
93
+ readonly name: {
94
+ readonly optional: false;
95
+ readonly kind: "value";
96
+ readonly required: "shape";
97
+ };
98
+ readonly description: {
99
+ readonly optional: true;
100
+ readonly kind: "value";
101
+ readonly required: "shape";
102
+ };
103
+ readonly argsJsonSchema: {
104
+ readonly optional: true;
105
+ readonly kind: "value";
106
+ readonly required: "shape";
107
+ };
108
+ readonly run: {
109
+ readonly optional: false;
110
+ readonly kind: "function";
111
+ readonly required: "effect";
112
+ };
113
+ };
114
+ export declare const GAME_STATE_PROVIDER_SHAPE: {
115
+ readonly name: {
116
+ readonly optional: false;
117
+ readonly kind: "value";
118
+ readonly required: "shape";
119
+ };
120
+ readonly tier: {
121
+ readonly optional: true;
122
+ readonly kind: "value";
123
+ readonly required: "shape";
124
+ };
125
+ readonly read: {
126
+ readonly optional: false;
127
+ readonly kind: "function";
128
+ readonly required: "operation";
129
+ };
130
+ };
131
+ export declare const GAME_HIERARCHY_GROUP_SHAPE: {
132
+ readonly id: {
133
+ readonly optional: false;
134
+ readonly kind: "value";
135
+ readonly required: "shape";
136
+ };
137
+ readonly label: {
138
+ readonly optional: false;
139
+ readonly kind: "value";
140
+ readonly required: "shape";
141
+ };
142
+ readonly count: {
143
+ readonly optional: false;
144
+ readonly kind: "value";
145
+ readonly required: "operation";
146
+ };
147
+ };
148
+ export declare const GAME_SYSTEMS_SHAPE: {
149
+ readonly commands: {
150
+ readonly optional: true;
151
+ readonly kind: "value";
152
+ readonly required: "operation";
153
+ };
154
+ readonly state: {
155
+ readonly optional: true;
156
+ readonly kind: "value";
157
+ readonly required: "operation";
158
+ };
159
+ readonly hierarchy: {
160
+ readonly optional: true;
161
+ readonly kind: "function";
162
+ readonly required: "operation";
163
+ };
164
+ readonly systemAdapters: {
165
+ readonly optional: true;
166
+ readonly kind: "value";
167
+ readonly required: "operation";
168
+ };
169
+ };
170
+ export declare const GAME_SYSTEM_ADAPTERS_SHAPE: {
171
+ readonly physics: {
172
+ readonly optional: true;
173
+ readonly kind: "value";
174
+ readonly required: "effect";
175
+ };
176
+ readonly networking: {
177
+ readonly optional: true;
178
+ readonly kind: "value";
179
+ readonly required: "operation";
180
+ };
181
+ readonly navigation: {
182
+ readonly optional: true;
183
+ readonly kind: "value";
184
+ readonly required: "operation";
185
+ };
186
+ readonly audio: {
187
+ readonly optional: true;
188
+ readonly kind: "value";
189
+ readonly required: "effect";
190
+ };
191
+ readonly camera: {
192
+ readonly optional: true;
193
+ readonly kind: "value";
194
+ readonly required: "effect";
195
+ };
196
+ readonly renderDebug: {
197
+ readonly optional: true;
198
+ readonly kind: "value";
199
+ readonly required: "effect";
200
+ };
201
+ };
202
+ export declare const GAME_SYSTEM_EMPTY_SHAPE: {
203
+ readonly present: {
204
+ readonly optional: false;
205
+ readonly kind: "value";
206
+ readonly required: "shape";
207
+ };
208
+ readonly evidence: {
209
+ readonly optional: false;
210
+ readonly kind: "value";
211
+ readonly required: "claim";
212
+ };
213
+ };
214
+ //# sourceMappingURL=game-contract-seams.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"game-contract-seams.d.ts","sourceRoot":"","sources":["../../../src/adapter/ingest/game-contract-seams.ts"],"names":[],"mappings":"AAAA;;sEAEsE;AAgBtE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAS9B,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;CAI/B,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;CAI5B,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;CAG3B,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;CAK7B,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;CAIpC,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;CAIrC,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;CAK7B,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAOrC,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;;;;;;;;;CAGlC,CAAC"}
@@ -0,0 +1,62 @@
1
+ /** Exhaustive proof requirements for the game→host contract. Declarations are
2
+ * intentionally insufficient for lifecycle, navigation, commands, state, and
3
+ * system carriers: their consumers must produce stronger receipts. */
4
+ import { defineSeamShape } from '../seam-evidence';
5
+ export const GAME_CONTRACT_SHAPE = defineSeamShape()({
6
+ contractVersion: { optional: false, kind: 'value', required: 'shape' },
7
+ root: { optional: true, kind: 'value', required: 'effect' },
8
+ presentation: { optional: true, kind: 'value', required: 'effect' },
9
+ world: { optional: true, kind: 'value', required: 'effect' },
10
+ ready: { optional: true, kind: 'value', required: 'effect' },
11
+ lifecycle: { optional: true, kind: 'value', required: 'effect' },
12
+ scenes: { optional: true, kind: 'value', required: 'effect' },
13
+ systems: { optional: true, kind: 'value', required: 'operation' },
14
+ });
15
+ export const GAME_LIFECYCLE_SHAPE = defineSeamShape()({
16
+ start: { optional: true, kind: 'function', required: 'effect' },
17
+ pause: { optional: true, kind: 'function', required: 'effect' },
18
+ resume: { optional: true, kind: 'function', required: 'effect' },
19
+ });
20
+ export const GAME_SCENES_SHAPE = defineSeamShape()({
21
+ list: { optional: false, kind: 'function', required: 'operation' },
22
+ current: { optional: false, kind: 'function', required: 'operation' },
23
+ goTo: { optional: false, kind: 'function', required: 'effect' },
24
+ });
25
+ export const GAME_SCENE_SHAPE = defineSeamShape()({
26
+ id: { optional: false, kind: 'value', required: 'shape' },
27
+ label: { optional: false, kind: 'value', required: 'shape' },
28
+ });
29
+ export const GAME_COMMAND_SHAPE = defineSeamShape()({
30
+ name: { optional: false, kind: 'value', required: 'shape' },
31
+ description: { optional: true, kind: 'value', required: 'shape' },
32
+ argsJsonSchema: { optional: true, kind: 'value', required: 'shape' },
33
+ run: { optional: false, kind: 'function', required: 'effect' },
34
+ });
35
+ export const GAME_STATE_PROVIDER_SHAPE = defineSeamShape()({
36
+ name: { optional: false, kind: 'value', required: 'shape' },
37
+ tier: { optional: true, kind: 'value', required: 'shape' },
38
+ read: { optional: false, kind: 'function', required: 'operation' },
39
+ });
40
+ export const GAME_HIERARCHY_GROUP_SHAPE = defineSeamShape()({
41
+ id: { optional: false, kind: 'value', required: 'shape' },
42
+ label: { optional: false, kind: 'value', required: 'shape' },
43
+ count: { optional: false, kind: 'value', required: 'operation' },
44
+ });
45
+ export const GAME_SYSTEMS_SHAPE = defineSeamShape()({
46
+ commands: { optional: true, kind: 'value', required: 'operation' },
47
+ state: { optional: true, kind: 'value', required: 'operation' },
48
+ hierarchy: { optional: true, kind: 'function', required: 'operation' },
49
+ systemAdapters: { optional: true, kind: 'value', required: 'operation' },
50
+ });
51
+ export const GAME_SYSTEM_ADAPTERS_SHAPE = defineSeamShape()({
52
+ physics: { optional: true, kind: 'value', required: 'effect' },
53
+ networking: { optional: true, kind: 'value', required: 'operation' },
54
+ navigation: { optional: true, kind: 'value', required: 'operation' },
55
+ audio: { optional: true, kind: 'value', required: 'effect' },
56
+ camera: { optional: true, kind: 'value', required: 'effect' },
57
+ renderDebug: { optional: true, kind: 'value', required: 'effect' },
58
+ });
59
+ export const GAME_SYSTEM_EMPTY_SHAPE = defineSeamShape()({
60
+ present: { optional: false, kind: 'value', required: 'shape' },
61
+ evidence: { optional: false, kind: 'value', required: 'claim' },
62
+ });
@@ -25,9 +25,11 @@ import type { AudioAdapter, CameraAdapter, NavigationAdapter, NetworkingAdapter,
25
25
  * executes, the game may defer its session side-effects (backend connections,
26
26
  * narrative, audio) and render a quiet, inspectable scene; the host calls
27
27
  * `start()` — at most once per mount — when the user presses ▶. Declaring
28
- * `pause`/`resume` means the game can genuinely freeze/unfreeze itself; the
29
- * host prefers these over its outside-in loop gate (which cannot gate a raw
30
- * requestAnimationFrame loop at all R3F games, notably).
28
+ * `pause`/`resume` means the game can genuinely freeze/unfreeze itself. They
29
+ * are one indivisible pair: the ingest adapter binds that pair as its mounted
30
+ * lifecycle control, or binds its outside-in loop gate when neither is
31
+ * declared. Host consumers see only the bound control; they never mix one
32
+ * declared half with a fallback half.
31
33
  */
32
34
  export interface VgaiGameLifecycle {
33
35
  start?(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"game-contract.d.ts","sourceRoot":"","sources":["../../../src/adapter/ingest/game-contract.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"game-contract.d.ts","sourceRoot":"","sources":["../../../src/adapter/ingest/game-contract.ts"],"names":[],"mappings":"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"}
@@ -18,6 +18,7 @@
18
18
  * Origin (root), F17+F21 (lifecycle), WO-SYS1 (systems), WO-SYS2
19
19
  * (`systems.systemAdapters`).
20
20
  */
21
+ import { GAME_SCENES_SHAPE } from './game-contract-seams';
21
22
  /**
22
23
  * Read the declared contract, if any. The `contractVersion` gate is the
23
24
  * forward-compatibility hinge: a future v2 game on a v1 host is ignored
@@ -38,7 +39,9 @@ export function readGameContract(scope = typeof window === 'undefined' ? null :
38
39
  }
39
40
  /** The endpoints a scene surface must carry: every one of them is called by the
40
41
  * projection, so a declaration missing any cannot be honoured. */
41
- const SCENES_REQUIRED_MEMBERS = ['list', 'current', 'goTo'];
42
+ const SCENES_REQUIRED_MEMBERS = Object.entries(GAME_SCENES_SHAPE)
43
+ .filter(([, spec]) => !spec.optional)
44
+ .map(([member]) => member);
42
45
  /**
43
46
  * Read the declared {@link VgaiGameScenes}, refusing a malformed one BY NAME.
44
47
  *
@@ -0,0 +1,52 @@
1
+ /**
2
+ * ONE `DebugAdapter` out of several projections of the same mount.
3
+ *
4
+ * Two feeders exist today and they are peers, not layers: the game's own
5
+ * declared system surface (`contract-debug-adapter.ts`, from
6
+ * `window.vgaiGame.systems`) and its adapter module's observation table
7
+ * (`observation-debug-adapter.ts`). Both project onto the ONE runtime door the
8
+ * editor and `vgai eval` already read (`SystemAdapters.debug`), so the merge
9
+ * belongs here rather than in a second slot — a consumer must not be able to
10
+ * tell a name's provenance, which is the whole point of both projections.
11
+ *
12
+ * ## A collision REFUSES the name; it never shadows it
13
+ *
14
+ * When two feeders declare the same provider or command name, one of them would
15
+ * otherwise win silently and an agent would read the wrong thing with every log
16
+ * line still saying success. So the merged adapter:
17
+ *
18
+ * - LISTS the name once (it is declared, and hiding it would be its own lie);
19
+ * - REFUSES to answer it with a coded `DEBUG_NAME_COLLISION` naming BOTH
20
+ * sources, at `state()` / `invoke()` and per-key inside `stateAll()`;
21
+ * - reports the collisions to the caller ({@link MergedDebugAdapters}) so the
22
+ * mount can say so out loud where a person will see it, instead of the
23
+ * refusal waiting to be discovered by whoever calls the name first.
24
+ *
25
+ * The refusal is per-NAME, not per-mount, deliberately: killing the mount would
26
+ * cost a user their whole game to protect against one ambiguous read, and the
27
+ * per-name refusal already gives the same guarantee — nothing is silently
28
+ * shadowed — with none of the collateral.
29
+ */
30
+ import type { DebugAdapter } from '../system-adapter';
31
+ /** One feeder, with the words a collision message names it by. */
32
+ export interface DebugAdapterSource {
33
+ /** How this projection is named to a reader — its provenance, in prose. */
34
+ readonly label: string;
35
+ /** `null` when this feeder projected nothing (the honest floor both return). */
36
+ readonly adapter: DebugAdapter | null;
37
+ }
38
+ export interface MergedDebugAdapters {
39
+ /** The one door, or `null` when no feeder projected anything. */
40
+ readonly adapter: DebugAdapter | null;
41
+ /** One sentence per colliding name, naming both sources. Empty is the norm. */
42
+ readonly collisions: readonly string[];
43
+ }
44
+ /**
45
+ * Fold every projection of one mount onto a single {@link DebugAdapter}.
46
+ *
47
+ * `events()` concatenates, because an event ring is append-only and two rings
48
+ * genuinely both happened — there is no name to collide on. Everything else is
49
+ * name-keyed and therefore goes through the collision rule above.
50
+ */
51
+ export declare function mergeDebugAdapters(sources: readonly DebugAdapterSource[]): MergedDebugAdapters;
52
+ //# sourceMappingURL=merge-debug-adapters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge-debug-adapters.d.ts","sourceRoot":"","sources":["../../../src/adapter/ingest/merge-debug-adapters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAsC,MAAM,mBAAmB,CAAC;AAE1F,kEAAkE;AAClE,MAAM,WAAW,kBAAkB;IACjC,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,mBAAmB;IAClC,iEAAiE;IACjE,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;IACtC,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAsCD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,SAAS,kBAAkB,EAAE,GAAG,mBAAmB,CA0F9F"}
@@ -0,0 +1,141 @@
1
+ /**
2
+ * ONE `DebugAdapter` out of several projections of the same mount.
3
+ *
4
+ * Two feeders exist today and they are peers, not layers: the game's own
5
+ * declared system surface (`contract-debug-adapter.ts`, from
6
+ * `window.vgaiGame.systems`) and its adapter module's observation table
7
+ * (`observation-debug-adapter.ts`). Both project onto the ONE runtime door the
8
+ * editor and `vgai eval` already read (`SystemAdapters.debug`), so the merge
9
+ * belongs here rather than in a second slot — a consumer must not be able to
10
+ * tell a name's provenance, which is the whole point of both projections.
11
+ *
12
+ * ## A collision REFUSES the name; it never shadows it
13
+ *
14
+ * When two feeders declare the same provider or command name, one of them would
15
+ * otherwise win silently and an agent would read the wrong thing with every log
16
+ * line still saying success. So the merged adapter:
17
+ *
18
+ * - LISTS the name once (it is declared, and hiding it would be its own lie);
19
+ * - REFUSES to answer it with a coded `DEBUG_NAME_COLLISION` naming BOTH
20
+ * sources, at `state()` / `invoke()` and per-key inside `stateAll()`;
21
+ * - reports the collisions to the caller ({@link MergedDebugAdapters}) so the
22
+ * mount can say so out loud where a person will see it, instead of the
23
+ * refusal waiting to be discovered by whoever calls the name first.
24
+ *
25
+ * The refusal is per-NAME, not per-mount, deliberately: killing the mount would
26
+ * cost a user their whole game to protect against one ambiguous read, and the
27
+ * per-name refusal already gives the same guarantee — nothing is silently
28
+ * shadowed — with none of the collateral.
29
+ */
30
+ import { DebugError } from '../../runtime/debug-registry';
31
+ function collisionError(name, labels) {
32
+ return new DebugError('DEBUG_NAME_COLLISION', `"${name}" is declared by more than one source (${labels.join(' and ')}) — refusing to ` +
33
+ 'answer rather than picking one silently. Rename it in whichever source you own.', { name, sources: [...labels] });
34
+ }
35
+ /** Names each feeder claims, in listing order, de-duplicated within a feeder. */
36
+ function claimedNames(sources, face) {
37
+ const order = [];
38
+ const labelsByName = new Map();
39
+ for (const source of sources) {
40
+ if (!source.adapter)
41
+ continue;
42
+ const names = face === 'state'
43
+ ? source.adapter.providers().map((provider) => provider.name)
44
+ : source.adapter.commands().map((command) => command.name);
45
+ for (const name of new Set(names)) {
46
+ if (!labelsByName.has(name)) {
47
+ labelsByName.set(name, []);
48
+ order.push(name);
49
+ }
50
+ labelsByName.get(name)?.push(source.label);
51
+ }
52
+ }
53
+ return { order, labelsByName };
54
+ }
55
+ /**
56
+ * Fold every projection of one mount onto a single {@link DebugAdapter}.
57
+ *
58
+ * `events()` concatenates, because an event ring is append-only and two rings
59
+ * genuinely both happened — there is no name to collide on. Everything else is
60
+ * name-keyed and therefore goes through the collision rule above.
61
+ */
62
+ export function mergeDebugAdapters(sources) {
63
+ const live = sources.filter((source) => source.adapter !== null);
64
+ if (live.length === 0)
65
+ return { adapter: null, collisions: [] };
66
+ if (live.length === 1)
67
+ return { adapter: live[0].adapter, collisions: [] };
68
+ const providers = claimedNames(live, 'state');
69
+ const commands = claimedNames(live, 'command');
70
+ const collisions = [];
71
+ for (const [face, claimed] of [
72
+ ['state provider', providers],
73
+ ['command', commands],
74
+ ]) {
75
+ for (const name of claimed.order) {
76
+ const labels = claimed.labelsByName.get(name) ?? [];
77
+ if (labels.length > 1) {
78
+ collisions.push(`${face} "${name}" is declared by ${labels.join(' and ')}`);
79
+ }
80
+ }
81
+ }
82
+ /** The feeder that owns `name`, or a thrown collision error when several do. */
83
+ const ownerOf = (claimed, name, face) => {
84
+ const labels = claimed.labelsByName.get(name);
85
+ if (!labels)
86
+ return null;
87
+ if (labels.length > 1)
88
+ throw collisionError(name, labels);
89
+ return (live.find((source) => {
90
+ const owned = face === 'state'
91
+ ? source.adapter?.providers().some((provider) => provider.name === name)
92
+ : source.adapter?.commands().some((command) => command.name === name);
93
+ return owned === true;
94
+ })?.adapter ?? null);
95
+ };
96
+ return {
97
+ adapter: {
98
+ providers: () => live.flatMap((source) => source.adapter?.providers() ?? []).filter(uniqueByName()),
99
+ state: (name) => {
100
+ const owner = ownerOf(providers, name, 'state');
101
+ if (!owner) {
102
+ throw new DebugError('STATE_PROVIDER_NOT_FOUND', `No state provider named "${name}" is declared by this game.`, { registered: providers.order });
103
+ }
104
+ return owner.state(name);
105
+ },
106
+ stateAll: () => {
107
+ const out = {};
108
+ for (const name of providers.order) {
109
+ try {
110
+ out[name] = ownerOf(providers, name, 'state')?.state(name);
111
+ }
112
+ catch (err) {
113
+ out[name] = { __error: String(err) };
114
+ }
115
+ }
116
+ return out;
117
+ },
118
+ commands: () => live.flatMap((source) => source.adapter?.commands() ?? []).filter(uniqueByName()),
119
+ invoke: async (name, args) => {
120
+ const owner = ownerOf(commands, name, 'command');
121
+ if (!owner) {
122
+ throw new DebugError('DEBUG_COMMAND_NOT_REGISTERED', `No command named "${name}" is declared by this game.`, { registered: commands.order });
123
+ }
124
+ return owner.invoke(name, args);
125
+ },
126
+ events: (sinceSeq) => live.flatMap((source) => source.adapter?.events(sinceSeq) ?? []),
127
+ },
128
+ collisions,
129
+ };
130
+ }
131
+ /** Keep the FIRST listing of each name — the merged listing advertises a name
132
+ * once, whatever `state()`/`invoke()` then decide to do with it. */
133
+ function uniqueByName() {
134
+ const seen = new Set();
135
+ return (value) => {
136
+ if (seen.has(value.name))
137
+ return false;
138
+ seen.add(value.name);
139
+ return true;
140
+ };
141
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Projects an ADAPTER's declared observation slots
3
+ * (`AdapterDefinition.observation`, `adapter/adapter-module.ts`) onto the host's
4
+ * existing {@link DebugAdapter} — the one seam `game.providers()` /
5
+ * `game.state()` / `game.commands()` already read through
6
+ * (`command-listener.ts`'s `dispatchBridgeMethod` → `getActiveSystems().debug`).
7
+ *
8
+ * This is the SIBLING of `contract-debug-adapter.ts` and deliberately the same
9
+ * shape: a projection rather than a second door. The two differ only in WHO
10
+ * declared the surface — the game itself, on `window.vgaiGame.systems`, or the
11
+ * game's adapter module beside it — and a consumer downstream must not be able
12
+ * to tell them apart. `merge-debug-adapters.ts` is what folds both onto the one
13
+ * slot.
14
+ *
15
+ * ## What `game` is
16
+ *
17
+ * The host's to hand over, and for an INGEST mount it is the REALM the game's
18
+ * own modules ran in. That is not a convenience: an ingest mount runs the game
19
+ * in the editor's own realm (`game-contract.ts`'s `readGameContract` says so —
20
+ * "the realm every ingest mount runs the game's modules in, where the game and
21
+ * the host share one global"), a vendored bundle's adapter is HOST-realm by the
22
+ * placement rule, and the only handles such a game publishes are the ones on
23
+ * that realm — its runtime's own public registry, or a host-build seam beside
24
+ * it. Handing the realm is therefore handing the game everything it actually
25
+ * exposes; handing anything narrower would make the adapter reach for `window`
26
+ * itself, which is the same read with the provenance hidden.
27
+ *
28
+ * ## The two-state rule, kept
29
+ *
30
+ * Declaring a slot and answering it are separate facts. A declaration with NO
31
+ * `answer` is still listed and refuses BY NAME when read — never omitted,
32
+ * because omitting it would report "the game has no such state" when the truth
33
+ * is "the table declared it and nothing binds it yet". Same for a throwing
34
+ * `answer`: it propagates (exactly as a first-party provider's does), and only
35
+ * `stateAll()` isolates it per key.
36
+ *
37
+ * ## What this deliberately does NOT do
38
+ *
39
+ * - **Validate arguments.** A declared command's `answer` receives the invoked
40
+ * argument list after the game handle; there is no Zod tuple beside a foreign
41
+ * game, so a verb validates itself and throws its own error, surfaced wrapped
42
+ * as `DEBUG_COMMAND_FAILED`. Identical to the contract projection's stance.
43
+ * - **Fabricate an event ring.** Nothing emits behind a declaration, so
44
+ * `events()` is empty — accurate, not a stub.
45
+ */
46
+ import type { ObservationDeclaration } from '../adapter-module';
47
+ import type { DebugAdapter } from '../system-adapter';
48
+ /**
49
+ * Build a {@link DebugAdapter} over an adapter's observation declarations, or
50
+ * `null` when it declares none. `null` is the honest floor — the same one
51
+ * `createContractDebugAdapter` returns — so a game that declared nothing keeps
52
+ * reporting `DEBUG_ADAPTER_UNAVAILABLE` rather than serving an empty adapter
53
+ * that reads as "this game has no state".
54
+ */
55
+ export declare function createObservationDebugAdapter(declarations: readonly ObservationDeclaration[] | undefined | null, game: unknown): DebugAdapter | null;
56
+ //# sourceMappingURL=observation-debug-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observation-debug-adapter.d.ts","sourceRoot":"","sources":["../../../src/adapter/ingest/observation-debug-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAGH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,YAAY,EAAsC,MAAM,mBAAmB,CAAC;AAoB1F;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAC3C,YAAY,EAAE,SAAS,sBAAsB,EAAE,GAAG,SAAS,GAAG,IAAI,EAClE,IAAI,EAAE,OAAO,GACZ,YAAY,GAAG,IAAI,CA+ErB"}