@vgai/engine 0.5.22 → 0.5.23

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 (291) hide show
  1. package/README.md +6 -3
  2. package/dist/adapter/adapter-module.d.ts.map +1 -1
  3. package/dist/adapter/adapter-module.js +2 -4
  4. package/dist/adapter/adapter-surface.d.ts +1 -1
  5. package/dist/adapter/adapter-surface.js +1 -1
  6. package/dist/adapter/authoring.d.ts +19 -21
  7. package/dist/adapter/authoring.d.ts.map +1 -1
  8. package/dist/adapter/authoring.js +2 -2
  9. package/dist/adapter/binding.d.ts +341 -0
  10. package/dist/adapter/binding.d.ts.map +1 -0
  11. package/dist/adapter/binding.js +148 -0
  12. package/dist/adapter/colyseus-networking-adapter.d.ts.map +1 -1
  13. package/dist/adapter/colyseus-networking-adapter.js +23 -4
  14. package/dist/adapter/entrypoint-selection-readers.d.ts +24 -0
  15. package/dist/adapter/entrypoint-selection-readers.d.ts.map +1 -0
  16. package/dist/adapter/entrypoint-selection-readers.js +63 -0
  17. package/dist/adapter/entrypoint-selection-source.d.ts.map +1 -1
  18. package/dist/adapter/entrypoint-selection-source.js +1 -44
  19. package/dist/adapter/finders/scenes-from-entrypoint-selection.d.ts.map +1 -1
  20. package/dist/adapter/finders/scenes-from-entrypoint-selection.js +1 -52
  21. package/dist/adapter/host-context.d.ts +46 -15
  22. package/dist/adapter/host-context.d.ts.map +1 -1
  23. package/dist/adapter/host-context.js +2 -9
  24. package/dist/adapter/index.d.ts +11 -12
  25. package/dist/adapter/index.d.ts.map +1 -1
  26. package/dist/adapter/index.js +9 -10
  27. package/dist/adapter/ingest/game-contract.d.ts +0 -3
  28. package/dist/adapter/ingest/game-contract.d.ts.map +1 -1
  29. package/dist/adapter/ingest/game-contract.js +0 -3
  30. package/dist/adapter/ingest/scene-capture.d.ts +19 -23
  31. package/dist/adapter/ingest/scene-capture.d.ts.map +1 -1
  32. package/dist/adapter/ingest/scene-capture.js +143 -17
  33. package/dist/adapter/ingest/visible-capture-window.d.ts +34 -0
  34. package/dist/adapter/ingest/visible-capture-window.d.ts.map +1 -1
  35. package/dist/adapter/native-debug-module.d.ts +31 -5
  36. package/dist/adapter/native-debug-module.d.ts.map +1 -1
  37. package/dist/adapter/native-debug-module.js +25 -7
  38. package/dist/adapter/rapier-physics-adapter.d.ts +31 -1
  39. package/dist/adapter/rapier-physics-adapter.d.ts.map +1 -1
  40. package/dist/adapter/rapier-physics-adapter.js +50 -36
  41. package/dist/adapter/renderer-config.d.ts +2 -2
  42. package/dist/adapter/renderer-config.js +2 -2
  43. package/dist/adapter/root-adapter.d.ts +7 -7
  44. package/dist/adapter/root-adapter.js +4 -4
  45. package/dist/adapter/system-adapter.d.ts +45 -7
  46. package/dist/adapter/system-adapter.d.ts.map +1 -1
  47. package/dist/adapter/system-seam-contract.d.ts +3 -3
  48. package/dist/adapter/system-seam-contract.js +3 -3
  49. package/dist/adapter/system-slot.d.ts +168 -0
  50. package/dist/adapter/system-slot.d.ts.map +1 -0
  51. package/dist/adapter/system-slot.js +229 -0
  52. package/dist/adapter/transform.d.ts +11 -1
  53. package/dist/adapter/transform.d.ts.map +1 -1
  54. package/dist/ai/navigation.d.ts +17 -1
  55. package/dist/ai/navigation.d.ts.map +1 -1
  56. package/dist/ai/navigation.js +26 -5
  57. package/dist/animation/anim-graph-types.d.ts +11 -3
  58. package/dist/animation/anim-graph-types.d.ts.map +1 -1
  59. package/dist/animation/theatre-clock-binding.d.ts +4 -4
  60. package/dist/animation/theatre-clock-binding.js +4 -4
  61. package/dist/animation/xstate-animation-binding.d.ts.map +1 -1
  62. package/dist/animation/xstate-animation-binding.js +2 -2
  63. package/dist/animation/xstate-animation-meta.d.ts +13 -0
  64. package/dist/animation/xstate-animation-meta.d.ts.map +1 -1
  65. package/dist/animation/xstate-animation-meta.js +14 -0
  66. package/dist/asset-formats/index.d.ts +4 -7
  67. package/dist/asset-formats/index.d.ts.map +1 -1
  68. package/dist/asset-formats/index.js +4 -7
  69. package/dist/asset-formats/render-env.d.ts +5 -8
  70. package/dist/asset-formats/render-env.d.ts.map +1 -1
  71. package/dist/asset-formats/render-env.js +3 -6
  72. package/dist/asset-parse-error.d.ts +2 -5
  73. package/dist/asset-parse-error.d.ts.map +1 -1
  74. package/dist/asset-parse-error.js +2 -5
  75. package/dist/audio/bus-mixer.d.ts +101 -0
  76. package/dist/audio/bus-mixer.d.ts.map +1 -0
  77. package/dist/audio/bus-mixer.js +115 -0
  78. package/dist/core/frame-pacing.d.ts +1 -1
  79. package/dist/core/frame-pacing.js +2 -2
  80. package/dist/core/game-loop.d.ts +1 -3
  81. package/dist/core/game-loop.d.ts.map +1 -1
  82. package/dist/core/game-loop.js +1 -3
  83. package/dist/core/seeded-random.d.ts +1 -1
  84. package/dist/core/sim-clock.d.ts +5 -6
  85. package/dist/core/sim-clock.d.ts.map +1 -1
  86. package/dist/core/sim-clock.js +4 -5
  87. package/dist/core/types.d.ts +1 -3
  88. package/dist/core/types.d.ts.map +1 -1
  89. package/dist/defaults.d.ts +6 -14
  90. package/dist/defaults.d.ts.map +1 -1
  91. package/dist/defaults.js +6 -14
  92. package/dist/dev/register-render-vitals.d.ts +1 -4
  93. package/dist/dev/register-render-vitals.d.ts.map +1 -1
  94. package/dist/dev/register-render-vitals.js +1 -4
  95. package/dist/dev/render-debug-adapter.d.ts +2 -3
  96. package/dist/dev/render-debug-adapter.d.ts.map +1 -1
  97. package/dist/dev/render-debug-adapter.js +2 -3
  98. package/dist/dev/render-vitals.d.ts +3 -3
  99. package/dist/dev/render-vitals.js +3 -3
  100. package/dist/dev/webgl-frame-capture.d.ts +1 -1
  101. package/dist/dev/webgl-frame-capture.js +1 -1
  102. package/dist/index.d.ts +2 -5
  103. package/dist/index.d.ts.map +1 -1
  104. package/dist/index.js +2 -4
  105. package/dist/input/host-pointer.d.ts +122 -0
  106. package/dist/input/host-pointer.d.ts.map +1 -0
  107. package/dist/input/host-pointer.js +160 -0
  108. package/dist/input/input-manager.d.ts +18 -5
  109. package/dist/input/input-manager.d.ts.map +1 -1
  110. package/dist/input/input-manager.js +33 -13
  111. package/dist/input/rebind-controller.d.ts.map +1 -1
  112. package/dist/input/rebind-controller.js +6 -8
  113. package/dist/input/schema.d.ts.map +1 -1
  114. package/dist/input/schema.js +56 -28
  115. package/dist/manifest/filename.d.ts.map +1 -1
  116. package/dist/manifest/filename.js +8 -12
  117. package/dist/manifest/load.d.ts +10 -10
  118. package/dist/manifest/load.d.ts.map +1 -1
  119. package/dist/manifest/load.js +9 -6
  120. package/dist/manifest/schema.d.ts +17 -21
  121. package/dist/manifest/schema.d.ts.map +1 -1
  122. package/dist/manifest/schema.js +45 -35
  123. package/dist/physics/collider-dimensions.d.ts +8 -12
  124. package/dist/physics/collider-dimensions.d.ts.map +1 -1
  125. package/dist/physics/collider-dimensions.js +8 -12
  126. package/dist/pixi/scene-capture.d.ts +11 -13
  127. package/dist/pixi/scene-capture.d.ts.map +1 -1
  128. package/dist/react/world-state.d.ts +1 -1
  129. package/dist/react/world-state.d.ts.map +1 -1
  130. package/dist/render/light-camera-factory.d.ts +5 -7
  131. package/dist/render/light-camera-factory.d.ts.map +1 -1
  132. package/dist/render/light-camera-factory.js +8 -11
  133. package/dist/render/material-factory.js +1 -1
  134. package/dist/render/render-batch-system.d.ts.map +1 -1
  135. package/dist/render/render-features.d.ts +17 -6
  136. package/dist/render/render-features.d.ts.map +1 -1
  137. package/dist/render/render-features.js +0 -28
  138. package/dist/runtime/create-runtime.d.ts +34 -25
  139. package/dist/runtime/create-runtime.d.ts.map +1 -1
  140. package/dist/runtime/create-runtime.js +218 -93
  141. package/dist/runtime/debug-registry.d.ts +77 -8
  142. package/dist/runtime/debug-registry.d.ts.map +1 -1
  143. package/dist/runtime/debug-registry.js +3 -3
  144. package/dist/runtime/dev-build.d.ts +2 -2
  145. package/dist/runtime/dev-build.js +2 -2
  146. package/dist/runtime/game-input-seams.d.ts +2 -2
  147. package/dist/runtime/game-input-seams.d.ts.map +1 -1
  148. package/dist/runtime/game.d.ts +90 -41
  149. package/dist/runtime/game.d.ts.map +1 -1
  150. package/dist/runtime/game.js +80 -54
  151. package/dist/runtime/mount-game.d.ts +0 -16
  152. package/dist/runtime/mount-game.d.ts.map +1 -1
  153. package/dist/runtime/mount-game.js +8 -39
  154. package/dist/runtime/mount-manifest.d.ts +22 -14
  155. package/dist/runtime/mount-manifest.d.ts.map +1 -1
  156. package/dist/runtime/mount-manifest.js +18 -18
  157. package/dist/runtime/playtest.d.ts +22 -0
  158. package/dist/runtime/playtest.d.ts.map +1 -0
  159. package/dist/runtime/playtest.js +12 -0
  160. package/dist/runtime/state-bridge.d.ts +2 -3
  161. package/dist/runtime/state-bridge.d.ts.map +1 -1
  162. package/dist/runtime/state-bridge.js +1 -0
  163. package/dist/setup/setup-audio.d.ts +12 -0
  164. package/dist/setup/setup-audio.d.ts.map +1 -1
  165. package/dist/setup/setup-audio.js +9 -10
  166. package/dist/setup/setup-renderer.d.ts +2 -25
  167. package/dist/setup/setup-renderer.d.ts.map +1 -1
  168. package/dist/setup/setup-renderer.js +2 -31
  169. package/dist/world3d-react/r3f-root-factory.d.ts +7 -7
  170. package/dist/world3d-react/r3f-root-factory.js +7 -7
  171. package/dist/world3d-react/rapier-physics-bridge.d.ts +9 -8
  172. package/dist/world3d-react/rapier-physics-bridge.d.ts.map +1 -1
  173. package/dist/world3d-react/rapier-physics-bridge.js +100 -48
  174. package/package.json +1 -1
  175. package/schemas/engine-capabilities.json +16 -14
  176. package/schemas/vgai-project.schema.json +35 -26
  177. package/src/adapter/adapter-module.ts +2 -4
  178. package/src/adapter/adapter-surface.ts +1 -1
  179. package/src/adapter/authoring.ts +19 -21
  180. package/src/adapter/binding.ts +468 -0
  181. package/src/adapter/colyseus-networking-adapter.ts +20 -5
  182. package/src/adapter/entrypoint-selection-readers.ts +66 -0
  183. package/src/adapter/entrypoint-selection-source.ts +1 -40
  184. package/src/adapter/finders/scenes-from-entrypoint-selection.ts +1 -48
  185. package/src/adapter/host-context.ts +45 -15
  186. package/src/adapter/index.ts +23 -11
  187. package/src/adapter/ingest/game-contract.ts +0 -3
  188. package/src/adapter/ingest/scene-capture.ts +190 -39
  189. package/src/adapter/ingest/visible-capture-window.ts +35 -0
  190. package/src/adapter/native-debug-module.ts +43 -7
  191. package/src/adapter/rapier-physics-adapter.ts +76 -20
  192. package/src/adapter/renderer-config.ts +2 -2
  193. package/src/adapter/root-adapter.ts +7 -7
  194. package/src/adapter/system-adapter.ts +43 -8
  195. package/src/adapter/system-seam-contract.ts +3 -3
  196. package/src/adapter/system-slot.ts +291 -0
  197. package/src/adapter/transform.ts +18 -1
  198. package/src/ai/navigation.ts +30 -3
  199. package/src/animation/anim-graph-types.ts +11 -3
  200. package/src/animation/theatre-clock-binding.ts +4 -4
  201. package/src/animation/xstate-animation-binding.ts +2 -2
  202. package/src/animation/xstate-animation-meta.ts +16 -0
  203. package/src/asset-formats/index.ts +4 -7
  204. package/src/asset-formats/render-env.ts +3 -6
  205. package/src/asset-parse-error.ts +2 -5
  206. package/src/audio/bus-mixer.ts +161 -0
  207. package/src/core/frame-pacing.ts +2 -2
  208. package/src/core/game-loop.ts +1 -3
  209. package/src/core/seeded-random.ts +1 -1
  210. package/src/core/sim-clock.ts +5 -6
  211. package/src/core/types.ts +1 -3
  212. package/src/defaults.ts +6 -14
  213. package/src/dev/register-render-vitals.ts +1 -4
  214. package/src/dev/render-debug-adapter.ts +2 -3
  215. package/src/dev/render-vitals.ts +3 -3
  216. package/src/dev/webgl-frame-capture.ts +1 -1
  217. package/src/index.ts +2 -5
  218. package/src/input/host-pointer.ts +230 -0
  219. package/src/input/input-manager.ts +34 -13
  220. package/src/input/input-types.ts +1 -1
  221. package/src/input/rebind-controller.ts +6 -8
  222. package/src/input/schema.ts +216 -188
  223. package/src/manifest/filename.ts +8 -12
  224. package/src/manifest/load.ts +17 -13
  225. package/src/manifest/schema.ts +55 -47
  226. package/src/physics/collider-dimensions.ts +8 -12
  227. package/src/pixi/scene-capture.ts +12 -15
  228. package/src/react/world-state.tsx +1 -1
  229. package/src/render/light-camera-factory.ts +8 -11
  230. package/src/render/material-factory.ts +1 -1
  231. package/src/render/render-batch-system.ts +14 -6
  232. package/src/render/render-features.ts +17 -35
  233. package/src/runtime/create-runtime.ts +270 -108
  234. package/src/runtime/debug-registry.ts +84 -8
  235. package/src/runtime/dev-build.ts +2 -2
  236. package/src/runtime/game-input-seams.ts +2 -2
  237. package/src/runtime/game.ts +168 -80
  238. package/src/runtime/mount-game.ts +8 -56
  239. package/src/runtime/mount-manifest.ts +43 -34
  240. package/src/runtime/playtest.ts +22 -0
  241. package/src/runtime/state-bridge.ts +3 -3
  242. package/src/setup/setup-audio.ts +21 -11
  243. package/src/setup/setup-renderer.ts +2 -61
  244. package/src/world3d-react/r3f-root-factory.tsx +7 -7
  245. package/src/world3d-react/rapier-physics-bridge.tsx +107 -50
  246. package/dist/adapter/setup-three-root-adapter.d.ts +0 -86
  247. package/dist/adapter/setup-three-root-adapter.d.ts.map +0 -1
  248. package/dist/adapter/setup-three-root-adapter.js +0 -908
  249. package/dist/animation/clip-map.d.ts +0 -12
  250. package/dist/animation/clip-map.d.ts.map +0 -1
  251. package/dist/animation/clip-map.js +0 -31
  252. package/dist/asset-registry.d.ts +0 -38
  253. package/dist/asset-registry.d.ts.map +0 -1
  254. package/dist/asset-registry.js +0 -66
  255. package/dist/canvas-react/engine-bridge.d.ts +0 -45
  256. package/dist/canvas-react/engine-bridge.d.ts.map +0 -1
  257. package/dist/canvas-react/engine-bridge.js +0 -45
  258. package/dist/canvas-react/pixi-react-adapter.d.ts +0 -77
  259. package/dist/canvas-react/pixi-react-adapter.d.ts.map +0 -1
  260. package/dist/canvas-react/pixi-react-adapter.js +0 -294
  261. package/dist/canvas-react/world-context.d.ts +0 -98
  262. package/dist/canvas-react/world-context.d.ts.map +0 -1
  263. package/dist/canvas-react/world-context.js +0 -173
  264. package/dist/dev/debug-draw.d.ts +0 -24
  265. package/dist/dev/debug-draw.d.ts.map +0 -1
  266. package/dist/dev/debug-draw.js +0 -73
  267. package/dist/render/auto-batcher.d.ts +0 -34
  268. package/dist/render/auto-batcher.d.ts.map +0 -1
  269. package/dist/render/auto-batcher.js +0 -140
  270. package/dist/render/lod.d.ts +0 -13
  271. package/dist/render/lod.d.ts.map +0 -1
  272. package/dist/render/lod.js +0 -16
  273. package/dist/runtime/types.d.ts +0 -303
  274. package/dist/runtime/types.d.ts.map +0 -1
  275. package/dist/runtime/types.js +0 -1
  276. package/dist/world3d-react/engine-bridge.d.ts +0 -47
  277. package/dist/world3d-react/engine-bridge.d.ts.map +0 -1
  278. package/dist/world3d-react/engine-bridge.js +0 -73
  279. package/dist/world3d-react/r3f-adapter.d.ts +0 -58
  280. package/dist/world3d-react/r3f-adapter.d.ts.map +0 -1
  281. package/dist/world3d-react/r3f-adapter.js +0 -634
  282. package/dist/world3d-react/world-context.d.ts +0 -182
  283. package/dist/world3d-react/world-context.d.ts.map +0 -1
  284. package/dist/world3d-react/world-context.js +0 -235
  285. package/src/adapter/setup-three-root-adapter.ts +0 -1032
  286. package/src/animation/clip-map.ts +0 -34
  287. package/src/asset-registry.ts +0 -89
  288. package/src/dev/debug-draw.ts +0 -80
  289. package/src/render/auto-batcher.ts +0 -168
  290. package/src/render/lod.ts +0 -17
  291. package/src/runtime/types.ts +0 -328
@@ -34,15 +34,20 @@
34
34
  // injectPointerPosition) through the SAME deadzone/normalize/combine path
35
35
  // real device bindings use.
36
36
  import { z } from 'zod';
37
- const KeyBindingSchema = z.object({
37
+ const KeyBindingSchema = z
38
+ .object({
38
39
  type: z.literal('key').describe('Binding kind: a keyboard key (KeyboardEvent.code)'),
39
40
  code: z.string().describe('KeyboardEvent.code value, e.g. "KeyW", "Space", "ArrowUp"'),
40
- });
41
- const MouseButtonBindingSchema = z.object({
41
+ })
42
+ .strict();
43
+ const MouseButtonBindingSchema = z
44
+ .object({
42
45
  type: z.literal('mouse_button').describe('Binding kind: a mouse button'),
43
46
  button: z.number().describe('MouseEvent.button index (0 = left, 1 = middle, 2 = right)'),
44
- });
45
- const MouseMoveBindingSchema = z.object({
47
+ })
48
+ .strict();
49
+ const MouseMoveBindingSchema = z
50
+ .object({
46
51
  type: z
47
52
  .literal('mouse_move')
48
53
  .describe('Binding kind: raw mouse movement (F2, spec §12 "Complete Device Backends"). Feeds a ' +
@@ -55,20 +60,26 @@ const MouseMoveBindingSchema = z.object({
55
60
  .describe("Radial deadzone magnitude applied only when this binding feeds a 'vector2'-valueType " +
56
61
  "action (default 0 — no deadzone; ignored for 'pointerDelta' reads, which are never " +
57
62
  'deadzoned).'),
58
- });
59
- const GamepadButtonBindingSchema = z.object({
63
+ })
64
+ .strict();
65
+ const GamepadButtonBindingSchema = z
66
+ .object({
60
67
  type: z.literal('gamepad_button').describe('Binding kind: a gamepad face/shoulder button'),
61
68
  button: z.number().describe('Standard Gamepad API button index'),
62
- });
63
- const GamepadAxisBindingSchema = z.object({
69
+ })
70
+ .strict();
71
+ const GamepadAxisBindingSchema = z
72
+ .object({
64
73
  type: z.literal('gamepad_axis').describe('Binding kind: a single thresholded gamepad axis'),
65
74
  axis: z.number().describe('Standard Gamepad API axis index'),
66
75
  direction: z
67
76
  .enum(['positive', 'negative'])
68
77
  .describe('Which side of the deadzone counts as "pressed"'),
69
78
  deadzone: z.number().optional().describe('Deadzone magnitude (default 0.15 if omitted)'),
70
- });
71
- const GamepadAxisPairBindingSchema = z.object({
79
+ })
80
+ .strict();
81
+ const GamepadAxisPairBindingSchema = z
82
+ .object({
72
83
  type: z
73
84
  .literal('gamepad_axis_pair')
74
85
  .describe('Binding kind: a coupled (x, y) gamepad axis pair, e.g. a stick used as a 2D vector ' +
@@ -78,7 +89,8 @@ const GamepadAxisPairBindingSchema = z.object({
78
89
  xAxis: z.number().describe('Standard Gamepad API axis index for the X component'),
79
90
  yAxis: z.number().describe('Standard Gamepad API axis index for the Y component'),
80
91
  deadzone: z.number().optional().describe('Deadzone magnitude (default 0.15 if omitted)'),
81
- });
92
+ })
93
+ .strict();
82
94
  // ---------------------------------------------------------------------------
83
95
  // F1 (spec §12) — injected test input bindings. LIVE (real runtime readers in
84
96
  // InputManager's getScalar/getVector2/getPointerDelta/getPointerPosition),
@@ -86,7 +98,8 @@ const GamepadAxisPairBindingSchema = z.object({
86
98
  // backend: real device kinds F2 adds later feed the same typed-value
87
99
  // aggregation path these exercise today.
88
100
  // ---------------------------------------------------------------------------
89
- const TestAxisBindingSchema = z.object({
101
+ const TestAxisBindingSchema = z
102
+ .object({
90
103
  type: z
91
104
  .literal('test_axis')
92
105
  .describe("Binding kind: an injected synthetic scalar value for a 'scalar'-valueType action " +
@@ -101,8 +114,10 @@ const TestAxisBindingSchema = z.object({
101
114
  .describe('1D deadzone magnitude applied to the injected raw value before combine (default 0 — no ' +
102
115
  'deadzone). Values below it read as 0; values at/above it rescale from 0 (at the ' +
103
116
  'deadzone edge) to ±1 (at |raw| = 1), sign preserved.'),
104
- });
105
- const TestVector2BindingSchema = z.object({
117
+ })
118
+ .strict();
119
+ const TestVector2BindingSchema = z
120
+ .object({
106
121
  type: z
107
122
  .literal('test_vector2')
108
123
  .describe("Binding kind: an injected synthetic {x,y} value for a 'vector2'-valueType action " +
@@ -118,8 +133,10 @@ const TestVector2BindingSchema = z.object({
118
133
  '— no deadzone). Vectors whose magnitude is below it read as {0,0}; at/above it, ' +
119
134
  'direction is preserved and magnitude rescales the same way the scalar deadzone does, ' +
120
135
  'then the result is clamped to the unit circle (magnitude <= 1).'),
121
- });
122
- const TestPointerDeltaBindingSchema = z.object({
136
+ })
137
+ .strict();
138
+ const TestPointerDeltaBindingSchema = z
139
+ .object({
123
140
  type: z
124
141
  .literal('test_pointer_delta')
125
142
  .describe("Binding kind: an injected synthetic per-frame {x,y} delta for a 'pointerDelta'-" +
@@ -128,8 +145,10 @@ const TestPointerDeltaBindingSchema = z.object({
128
145
  sourceId: z
129
146
  .string()
130
147
  .describe('Names the injected test source this binding reads (InputManager.injectPointerDelta).'),
131
- });
132
- const TestPointerPositionBindingSchema = z.object({
148
+ })
149
+ .strict();
150
+ const TestPointerPositionBindingSchema = z
151
+ .object({
133
152
  type: z
134
153
  .literal('test_pointer_position')
135
154
  .describe("Binding kind: an injected synthetic absolute {x,y} position for a 'pointerPosition'-" +
@@ -138,7 +157,8 @@ const TestPointerPositionBindingSchema = z.object({
138
157
  sourceId: z
139
158
  .string()
140
159
  .describe('Names the injected test source this binding reads (InputManager.injectPointerPosition).'),
141
- });
160
+ })
161
+ .strict();
142
162
  // ---------------------------------------------------------------------------
143
163
  // F2 (spec §12 "Complete Device Backends") — touch/virtual-control bindings.
144
164
  // LIVE (real runtime readers in InputManager's isPressed/isJustPressed/
@@ -148,7 +168,8 @@ const TestPointerPositionBindingSchema = z.object({
148
168
  // touchstart/touchmove/touchend handlers would call (that DOM wiring is a
149
169
  // thin adapter at the edge, out of scope here — see input-manager.ts).
150
170
  // ---------------------------------------------------------------------------
151
- const TouchButtonBindingSchema = z.object({
171
+ const TouchButtonBindingSchema = z
172
+ .object({
152
173
  type: z
153
174
  .literal('touch_button')
154
175
  .describe("Binding kind: a virtual on-screen button for a 'digital' action " +
@@ -158,8 +179,10 @@ const TouchButtonBindingSchema = z.object({
158
179
  .string()
159
180
  .describe('Names the virtual control zone this binding reads (InputManager.setTouchButton) — a ' +
160
181
  'touch-UI-chosen id, not a real device index.'),
161
- });
162
- const TouchStickBindingSchema = z.object({
182
+ })
183
+ .strict();
184
+ const TouchStickBindingSchema = z
185
+ .object({
163
186
  type: z
164
187
  .literal('touch_stick')
165
188
  .describe("Binding kind: a virtual on-screen analog stick for a 'vector2' action " +
@@ -174,7 +197,8 @@ const TouchStickBindingSchema = z.object({
174
197
  .optional()
175
198
  .describe('Radial deadzone magnitude applied to the raw {x,y} before combine (default 0 — no ' +
176
199
  'deadzone).'),
177
- });
200
+ })
201
+ .strict();
178
202
  /** A single input binding. Every kind listed here is LIVE — F2 (spec §12) closed the last two
179
203
  * dead stubs (`mouse_move`/`gamepad_axis_pair`) by giving both real `InputManager` readers. */
180
204
  export const InputBindingSchema = z.discriminatedUnion('type', [
@@ -192,7 +216,8 @@ export const InputBindingSchema = z.discriminatedUnion('type', [
192
216
  TouchStickBindingSchema,
193
217
  ]);
194
218
  /** An action has a name (the record key) and one or more bindings. */
195
- export const InputActionSchema = z.object({
219
+ export const InputActionSchema = z
220
+ .object({
196
221
  valueType: z
197
222
  .enum(['digital', 'scalar', 'vector2', 'pointerDelta', 'pointerPosition'])
198
223
  .default('digital')
@@ -212,7 +237,8 @@ export const InputActionSchema = z.object({
212
237
  'by summing contributing {x,y} values then clamping to the unit circle. PointerDelta ' +
213
238
  'actions sum contributing deltas. PointerPosition actions use the most-recently-' +
214
239
  'written contributing source (last-write-wins).'),
215
- });
240
+ })
241
+ .strict();
216
242
  /**
217
243
  * The `.inputmap.json` file format (`InputManager.loadMap`).
218
244
  *
@@ -220,9 +246,11 @@ export const InputActionSchema = z.object({
220
246
  * same convention `2d.version`/`Scene2DSchema` used before T2.3 gave the 3D
221
247
  * scene version axis a real reader; see `schema-consumption-map.ts`).
222
248
  */
223
- export const InputMapFileSchema = z.object({
249
+ export const InputMapFileSchema = z
250
+ .object({
224
251
  version: z.number().describe('Input map file format version (RESERVED — no range check yet)'),
225
252
  actions: z
226
253
  .record(z.string(), InputActionSchema)
227
254
  .describe('Named actions, each with a list of bindings (InputManager.loadMap)'),
228
- });
255
+ })
256
+ .strict();
@@ -1 +1 @@
1
- {"version":3,"file":"filename.d.ts","sourceRoot":"","sources":["../../src/manifest/filename.ts"],"names":[],"mappings":"AAsBA,4EAA4E;AAC5E,eAAO,MAAM,iBAAiB,sBAAsB,CAAC;AAErD,iFAAiF;AACjF,eAAO,MAAM,yBAAyB,mBAAmB,CAAC;AAE1D,4DAA4D;AAC5D,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CASpE"}
1
+ {"version":3,"file":"filename.d.ts","sourceRoot":"","sources":["../../src/manifest/filename.ts"],"names":[],"mappings":"AAkBA,4EAA4E;AAC5E,eAAO,MAAM,iBAAiB,sBAAsB,CAAC;AAErD,iFAAiF;AACjF,eAAO,MAAM,yBAAyB,mBAAmB,CAAC;AAE1D,4DAA4D;AAC5D,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CASpE"}
@@ -1,17 +1,13 @@
1
1
  // The project manifest's FILENAME. There is exactly ONE.
2
2
  //
3
- // The manifest is `vgai.project.json`. It used to be `vgai.game.json`, and for
4
- // a while both names were read — WO-9 #62 recorded that dual-read as
5
- // permanent, on the presumption of an EXTERNAL constituency of projects
6
- // already on disk. The owner reversed that on 2026-08-02 (the legacy-removal
7
- // doctrine, `docs/ARCHITECTURE-CORE.md` §Vocabulary): this is pre-release
8
- // software, no such constituency exists, and a second way to spell the
9
- // manifest is the defect — two accepted names meant both kept being written,
10
- // and copies of the "try both" probe grew in five modules that agreed with the
11
- // real resolver only by coincidence.
3
+ // The manifest is `vgai.project.json`, and NOTHING reads a second spelling
4
+ // (the legacy-removal doctrine, `docs/ARCHITECTURE-CORE.md` §Vocabulary). Two
5
+ // accepted names is the defect, not the convenience: both get written, and
6
+ // copies of the "try both" probe spread into modules that agree with the real
7
+ // resolver only by coincidence.
12
8
  //
13
- // So the old name is REMOVED, and removed means it REJECTS LOUDLY naming the
14
- // exact one-line fix — never silently ignored, never redirected. A directory
9
+ // The removed name REJECTS LOUDLY, naming the exact one-line fix never
10
+ // silently ignored, never redirected. A directory
15
11
  // carrying only `vgai.game.json` is an error with a `git mv` in the message,
16
12
  // not a project that quietly fails to open.
17
13
  //
@@ -35,7 +31,7 @@ export function isManifestFilename(name) {
35
31
  */
36
32
  export function removedManifestFilenameMessage(where) {
37
33
  return (`${where}: found \`${REMOVED_MANIFEST_FILENAME}\` and no \`${MANIFEST_FILENAME}\`. ` +
38
- `\`${REMOVED_MANIFEST_FILENAME}\` was REMOVED (WO-LR1; the legacy-removal doctrine, ` +
34
+ `\`${REMOVED_MANIFEST_FILENAME}\` was REMOVED (the legacy-removal doctrine, ` +
39
35
  'docs/ARCHITECTURE-CORE.md §Vocabulary) — nothing reads it any more, and it is ' +
40
36
  'deliberately NOT read as a fallback, because a second accepted name is the defect.\n' +
41
37
  `Fix: rename it — \`git mv ${REMOVED_MANIFEST_FILENAME} ${MANIFEST_FILENAME}\`. ` +
@@ -31,16 +31,6 @@ export type ResolvedAdapter = {
31
31
  readonly assets: Record<string, string> | undefined;
32
32
  readonly domStubs: string[] | undefined;
33
33
  readonly captureTimeoutMs: number | undefined;
34
- /**
35
- * The component this root'''s WORLD is, in the game'''s own source (see the
36
- * field'''s schema description). Present ⇒ Edit mounts THAT component
37
- * alone as a still design-time document and Play mounts the game
38
- * through `entry`; absent ⇒ `entry` is what both modes mount.
39
- */
40
- readonly world?: {
41
- readonly entry: string;
42
- readonly export?: string | undefined;
43
- } | undefined;
44
34
  };
45
35
  export interface ResolvedAdapterRoot {
46
36
  readonly id: string;
@@ -48,6 +38,16 @@ export interface ResolvedAdapterRoot {
48
38
  readonly description: string | undefined;
49
39
  readonly adapter: ResolvedAdapter;
50
40
  readonly entry: string | undefined;
41
+ /**
42
+ * The component this root's WORLD is, in the game's own source (see the
43
+ * field's schema description). Present ⇒ Edit mounts THAT component alone as
44
+ * its design-time document and Play mounts the game through `entry`;
45
+ * absent ⇒ `entry` is what both modes mount.
46
+ */
47
+ readonly world?: {
48
+ readonly entry: string;
49
+ readonly export: string | undefined;
50
+ } | undefined;
51
51
  readonly zOrder: number;
52
52
  readonly pausable: boolean;
53
53
  readonly loop: 'gated' | 'self-driven';
@@ -1 +1 @@
1
- {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../src/manifest/load.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../src/manifest/load.ts"],"names":[],"mappings":"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"}
@@ -79,7 +79,6 @@ function resolveAdapter(root) {
79
79
  assets: ingest.assets,
80
80
  domStubs: ingest.domStubs,
81
81
  captureTimeoutMs: ingest.captureTimeoutMs,
82
- world: ingest.world,
83
82
  };
84
83
  }
85
84
  function checkEngineVersionPin(version) {
@@ -95,11 +94,14 @@ function checkEngineVersionPin(version) {
95
94
  * `id` drives uniqueness; `adapter` (incl. its surface and
96
95
  * `module`/`ingest.*` sub-fields) drives adapter identity
97
96
  * resolution; `entry` drives the entry cross-field rule and is
98
- * carried through; `zOrder` drives the final sort; `pausable`/`loop` are
97
+ * carried through; `world` is carried through for the ONE reader that mounts a
98
+ * design-time document (the editor's design session) and is deliberately not
99
+ * cross-checked against `entry` — the two name different modules on purpose;
100
+ * `zOrder` drives the final sort; `pausable`/`loop` are
99
101
  * carried through as-is (their consumers are the runtime/CLI, T3.2/T3.3);
100
102
  * `description` (T3.3
101
103
  * slice 3) is carried through as-is — its consumer today is
102
- * `resolveIngestDescriptor` (packages/editor/src/adapter-resolver.ts), which
104
+ * `resolveIngestDescriptor` (packages/editor/src/ingest/resolve-three.ts), which
103
105
  * threads an ingest-three root's description into `IngestGame.description`.
104
106
  */
105
107
  function resolveRoot(root) {
@@ -111,6 +113,7 @@ function resolveRoot(root) {
111
113
  description: root.description,
112
114
  adapter,
113
115
  entry: root.entry,
116
+ world: root.world === undefined ? undefined : { entry: root.world.entry, export: root.world.export },
114
117
  zOrder: root.zOrder,
115
118
  pausable: root.pausable,
116
119
  loop: root.loop,
@@ -126,9 +129,9 @@ function resolveRoot(root) {
126
129
  * any Zod validation failure or cross-field rule violation.
127
130
  */
128
131
  export function loadGameManifest(raw) {
129
- // Removed-format guard FIRST, on the raw value: a legacy `.vscn.json` root
130
- // would otherwise fail Zod's `roots` discriminated union with a confusing
131
- // shape error instead of a migration message (WO-8).
132
+ // Removed-format guard FIRST, on the raw value: a root declaring a removed
133
+ // content field would otherwise fail Zod's `roots` discriminated union with
134
+ // a confusing shape error instead of the named migration message.
132
135
  const parsed = GameManifestSchema.safeParse(raw);
133
136
  if (!parsed.success) {
134
137
  // D-V6: the `roots` `superRefine`'s composition issues — a duplicate root
@@ -28,10 +28,6 @@ export declare const RootAdapterSchema: z.ZodPipe<z.ZodTransform<unknown, unknow
28
28
  moduleAliases: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
29
29
  domStubs: z.ZodOptional<z.ZodArray<z.ZodString>>;
30
30
  captureTimeoutMs: z.ZodOptional<z.ZodNumber>;
31
- world: z.ZodOptional<z.ZodObject<{
32
- entry: z.ZodString;
33
- export: z.ZodOptional<z.ZodString>;
34
- }, z.core.$strict>>;
35
31
  }, z.core.$strict>;
36
32
  }, z.core.$strict>]>>;
37
33
  export type RootAdapter = z.infer<typeof RootAdapterSchema>;
@@ -62,14 +58,14 @@ export declare const AdapterRootSchema: z.ZodObject<{
62
58
  moduleAliases: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
63
59
  domStubs: z.ZodOptional<z.ZodArray<z.ZodString>>;
64
60
  captureTimeoutMs: z.ZodOptional<z.ZodNumber>;
65
- world: z.ZodOptional<z.ZodObject<{
66
- entry: z.ZodString;
67
- export: z.ZodOptional<z.ZodString>;
68
- }, z.core.$strict>>;
69
61
  }, z.core.$strict>;
70
62
  }, z.core.$strict>]>>;
71
63
  entry: z.ZodOptional<z.ZodString>;
72
64
  styles: z.ZodOptional<z.ZodArray<z.ZodString>>;
65
+ world: z.ZodOptional<z.ZodObject<{
66
+ entry: z.ZodString;
67
+ export: z.ZodOptional<z.ZodString>;
68
+ }, z.core.$strict>>;
73
69
  zOrder: z.ZodDefault<z.ZodNumber>;
74
70
  pausable: z.ZodDefault<z.ZodBoolean>;
75
71
  loop: z.ZodDefault<z.ZodEnum<{
@@ -119,7 +115,7 @@ export declare const GameManifestSchema: z.ZodObject<{
119
115
  version: z.ZodString;
120
116
  engine: z.ZodObject<{
121
117
  version: z.ZodString;
122
- }, z.core.$strip>;
118
+ }, z.core.$strict>;
123
119
  roots: z.ZodArray<z.ZodObject<{
124
120
  id: z.ZodString;
125
121
  description: z.ZodOptional<z.ZodString>;
@@ -147,14 +143,14 @@ export declare const GameManifestSchema: z.ZodObject<{
147
143
  moduleAliases: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
148
144
  domStubs: z.ZodOptional<z.ZodArray<z.ZodString>>;
149
145
  captureTimeoutMs: z.ZodOptional<z.ZodNumber>;
150
- world: z.ZodOptional<z.ZodObject<{
151
- entry: z.ZodString;
152
- export: z.ZodOptional<z.ZodString>;
153
- }, z.core.$strict>>;
154
146
  }, z.core.$strict>;
155
147
  }, z.core.$strict>]>>;
156
148
  entry: z.ZodOptional<z.ZodString>;
157
149
  styles: z.ZodOptional<z.ZodArray<z.ZodString>>;
150
+ world: z.ZodOptional<z.ZodObject<{
151
+ entry: z.ZodString;
152
+ export: z.ZodOptional<z.ZodString>;
153
+ }, z.core.$strict>>;
158
154
  zOrder: z.ZodDefault<z.ZodNumber>;
159
155
  pausable: z.ZodDefault<z.ZodBoolean>;
160
156
  loop: z.ZodDefault<z.ZodEnum<{
@@ -169,9 +165,9 @@ export declare const GameManifestSchema: z.ZodObject<{
169
165
  id: z.ZodString;
170
166
  label: z.ZodString;
171
167
  roots: z.ZodArray<z.ZodString>;
172
- }, z.core.$strip>>>;
173
- }, z.core.$strip>>;
174
- }, z.core.$strip>>;
168
+ }, z.core.$strict>>>;
169
+ }, z.core.$strict>>;
170
+ }, z.core.$strict>>;
175
171
  server: z.ZodOptional<z.ZodObject<{
176
172
  room: z.ZodString;
177
173
  endpoint: z.ZodOptional<z.ZodString>;
@@ -181,28 +177,28 @@ export declare const GameManifestSchema: z.ZodObject<{
181
177
  accessToken: z.ZodString;
182
178
  expiresAt: z.ZodNumber;
183
179
  }, z.core.$strict>>;
184
- }, z.core.$strip>>;
180
+ }, z.core.$strict>>;
185
181
  resolution: z.ZodOptional<z.ZodObject<{
186
182
  width: z.ZodNumber;
187
183
  height: z.ZodNumber;
188
- }, z.core.$strip>>;
184
+ }, z.core.$strict>>;
189
185
  rendering: z.ZodOptional<z.ZodObject<{
190
186
  antialias: z.ZodBoolean;
191
187
  }, z.core.$strict>>;
192
188
  debug: z.ZodOptional<z.ZodObject<{
193
189
  allowInProduction: z.ZodBoolean;
194
- }, z.core.$strip>>;
190
+ }, z.core.$strict>>;
195
191
  determinism: z.ZodOptional<z.ZodObject<{
196
192
  seededRandom: z.ZodBoolean;
197
193
  defaultSeed: z.ZodOptional<z.ZodNumber>;
198
- }, z.core.$strip>>;
194
+ }, z.core.$strict>>;
199
195
  budget: z.ZodOptional<z.ZodObject<{
200
196
  frameCpuMsP95: z.ZodOptional<z.ZodNumber>;
201
197
  physicsMsP95: z.ZodOptional<z.ZodNumber>;
202
198
  maxEntities: z.ZodOptional<z.ZodNumber>;
203
199
  maxDrawCalls: z.ZodOptional<z.ZodNumber>;
204
200
  maxTriangles: z.ZodOptional<z.ZodNumber>;
205
- }, z.core.$strip>>;
201
+ }, z.core.$strict>>;
206
202
  learn: z.ZodOptional<z.ZodObject<{
207
203
  kind: z.ZodEnum<{
208
204
  starter: "starter";
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/manifest/schema.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAG,CAAU,CAAC;AAsFhD,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAsJ3B,CAAC;AACJ,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAM5D,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAsDnB,CAAC;AACZ,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAkB5D,eAAO,MAAM,eAAe;;;;;EAMzB,CAAC;AACJ,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,eAAO,MAAM,qBAAqB;;;;EAEa,CAAC;AAChD,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;kBAqC7B,CAAC;AACJ,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAMhE,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAoTyD,CAAC;AAEzF,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/manifest/schema.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAG,CAAU,CAAC;AAsFhD,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;qBA0H3B,CAAC;AACJ,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAM5D,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAqFnB,CAAC;AACZ,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAkB5D,eAAO,MAAM,eAAe;;;;;EAMzB,CAAC;AACJ,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,eAAO,MAAM,qBAAqB;;;;EAEa,CAAC;AAChD,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;kBAqC7B,CAAC;AACJ,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAMhE,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA8TyD,CAAC;AAEzF,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
@@ -7,14 +7,9 @@
7
7
  // has a `.describe()` (repo policy — powers `scripts/generate-schema.ts` and
8
8
  // the T4.1 schema-walk coverage test).
9
9
  //
10
- // Naming: this file follows the repo's `XxxSchema` (Zod schema) / `Xxx`
11
- // (inferred type) convention used throughout `scene/schema/` the design
12
- // doc's §3 sketch names the bare consts (`AdapterRoot`) without the
13
- // `Schema` suffix; that sketch is explicitly a
14
- // "Zod sketch" the doc tells implementers to adapt to real code style
15
- // ("mirror the style in scene/schema/scene-file.ts" per CLAUDE.md), so the
16
- // schema consts here are suffixed and the bare names are reserved for the
17
- // inferred types, matching every other schema file in the repo.
10
+ // Naming: `XxxSchema` is the Zod schema, `Xxx` the inferred type. Every schema
11
+ // file in this repo reads that way, so the bare names stay reserved for the
12
+ // types.
18
13
  //
19
14
  // Adapter surface values mirror `AdapterSurface` in
20
15
  // `packages/engine/src/runtime/game.ts` (`'three' | 'canvas' | 'dom'`)
@@ -53,7 +48,7 @@ export const GAME_MANIFEST_VERSION = 2;
53
48
  // which is exactly why react is a `dom` root rather than its own kind.
54
49
  //
55
50
  // The pre-rename spellings `threejs`/`pixijs`/`react` are REMOVED, not
56
- // normalized (WO-LR1 item 2, the legacy-removal doctrine at
51
+ // normalized (the legacy-removal doctrine at
57
52
  // ARCHITECTURE-CORE §Vocabulary). Normalization was a second way to say the
58
53
  // same thing: two spellings both parsed, so both kept being written, and
59
54
  // SECOND readers grew (the dev server's surface probe, the hosted-editor
@@ -75,8 +70,8 @@ const REMOVED_BARE_ADAPTER_SPELLING = {
75
70
  };
76
71
  function removedSpellingMessage(bad, where) {
77
72
  const canonical = where === 'adapter' ? REMOVED_BARE_ADAPTER_SPELLING[bad] : REMOVED_SURFACE_SPELLING[bad];
78
- return (`Game manifest: \`${where}\`: "${bad}" — that spelling was REMOVED (WO-LR1; ` +
79
- 'ARCHITECTURE-CORE §Vocabulary). The surface vocabulary is ' +
73
+ return (`Game manifest: \`${where}\`: "${bad}" — that spelling was REMOVED ` +
74
+ '(ARCHITECTURE-CORE §Vocabulary). The surface vocabulary is ' +
80
75
  "'three' | 'canvas' | 'dom' — what the HOST HANDS the root, never which " +
81
76
  `library it uses.\nFix: change \`${where}\` to "${canonical}".`);
82
77
  }
@@ -194,28 +189,6 @@ export const RootAdapterSchema = z
194
189
  .describe("How long the host waits for this game's first captured frame before the mount " +
195
190
  'FAILS by name. A game that needs a long boot (streamed world assets, a menu ' +
196
191
  'the player must clear) raises it; the default is 10s.'),
197
- world: z
198
- .object({
199
- entry: z
200
- .string()
201
- .describe("Project-relative path to the game's OWN module exporting that component"),
202
- export: z
203
- .string()
204
- .optional()
205
- .describe('Named export to read from that module; omit when the module default-exports it'),
206
- })
207
- .strict()
208
- .optional()
209
- .describe("The component this root's WORLD is, in the game's own source — a three root " +
210
- 'whose scene is a React/R3F component tree names it here. Two readers, and ' +
211
- 'they mount different things: the editor mounts THIS component alone as the ' +
212
- "root's design-time document (a still scene — its frameloop runs ONE bounded " +
213
- 'settle at mount, so physics-owned bodies rest at their authored spawn, and ' +
214
- 'is then frozen forever; nothing moves in Edit), while `entry` ' +
215
- 'above stays what PLAY mounts (the whole game, its own composition, its own ' +
216
- 'HUD and loop). Declaring it is what lets a scene be a scene in Edit rather ' +
217
- "than the running game's mount surfaces. A game whose world is not a " +
218
- 'component omits it and keeps mounting through `entry` in both modes.'),
219
192
  })
220
193
  .strict()
221
194
  .describe('Ingest adapter configuration for an unmodified game (a repo-vendored game or your ' +
@@ -257,6 +230,33 @@ export const AdapterRootSchema = z
257
230
  "mounts the root's DOM in (`@scope`; packages/editor/server/scoped-game-css.ts), so " +
258
231
  "the HUD is styled on the UI board's story cards and on the game surface without the " +
259
232
  'editor seeing a single one of those rules. The files themselves are never modified.'),
233
+ world: z
234
+ .object({
235
+ entry: z
236
+ .string()
237
+ .describe("Project-relative path to the game's OWN module exporting that component"),
238
+ export: z
239
+ .string()
240
+ .optional()
241
+ .describe('Named export to read from that module; omit when the module default-exports it'),
242
+ })
243
+ .strict()
244
+ .optional()
245
+ .describe("The component this root's WORLD is, in the game's own source. Two readers, and they " +
246
+ "mount different things: the EDITOR mounts THIS component alone as the root's " +
247
+ 'design-time document, while `entry` above stays what PLAY mounts (the whole game — ' +
248
+ 'its own composition, its own HUD, its own loop). It sits on the ROOT rather than ' +
249
+ 'inside any one adapter because the split it names is not about ingest: a game whose ' +
250
+ 'runtime entry is a SHELL over the thing an author actually edits has this shape ' +
251
+ 'whether the source is vendored or first-party. Two shipped cases, one field: an ' +
252
+ 'ingested game whose `entry` mounts game+HUD+loop while the named export is the world ' +
253
+ 'alone; and a translated Unity/Godot port, whose `entry` is a scene HOST that mounts ' +
254
+ 'the scene the built player starts on (`EditorBuildSettings` index 0 — routinely a ' +
255
+ 'menu with no 3D content at all) while the named export opens the scene an author ' +
256
+ "edits. That is Unity's own split: build settings say where the PLAYER starts; the " +
257
+ 'Scene view opens a scene, and Unity keeps that fact somewhere else entirely. A game ' +
258
+ 'whose world is not a separate component omits this and keeps mounting through ' +
259
+ '`entry` in both modes.'),
260
260
  zOrder: z
261
261
  .number()
262
262
  .int()
@@ -350,6 +350,7 @@ export const GameManifestSchema = z
350
350
  .describe('Exact @vgai/engine semver this game was scaffolded/last upgraded against — an ' +
351
351
  'identity pin, not a range'),
352
352
  })
353
+ .strict()
353
354
  .describe('Engine version pin'),
354
355
  roots: z
355
356
  .array(AdapterRootSchema)
@@ -422,20 +423,24 @@ export const GameManifestSchema = z
422
423
  .optional()
423
424
  .describe('Optional editor labels keyed by adapter-root id'),
424
425
  groups: z
425
- .array(z.object({
426
+ .array(z
427
+ .object({
426
428
  id: z.string().describe('Unique editor-only group id'),
427
429
  label: z.string().describe('Editor-only group label'),
428
430
  roots: z
429
431
  .array(z.string())
430
432
  .min(1)
431
433
  .describe('Adapter-root ids shown under this editor-only group'),
432
- }))
434
+ })
435
+ .strict())
433
436
  .optional()
434
437
  .describe('Optional editor-only hierarchy groups'),
435
438
  })
439
+ .strict()
436
440
  .optional()
437
441
  .describe('Editor projection for native adapter roots'),
438
442
  })
443
+ .strict()
439
444
  .optional()
440
445
  .describe('Editor-only authoring metadata; never runtime ownership'),
441
446
  server: z
@@ -469,6 +474,7 @@ export const GameManifestSchema = z
469
474
  .optional()
470
475
  .describe('Deploy-baked managed-relay credentials. NEVER hand-authored in source — written only into the staged manifest by `vgai deploy` and fetched at runtime by the standalone client'),
471
476
  })
477
+ .strict()
472
478
  .optional()
473
479
  .describe('Multiplayer server config (Colyseus), if this game registers a room'),
474
480
  resolution: z
@@ -476,6 +482,7 @@ export const GameManifestSchema = z
476
482
  width: z.number().describe('Canvas width in pixels'),
477
483
  height: z.number().describe('Canvas height in pixels'),
478
484
  })
485
+ .strict()
479
486
  .optional()
480
487
  .describe('Canvas resolution'),
481
488
  rendering: z
@@ -504,6 +511,7 @@ export const GameManifestSchema = z
504
511
  'production builds. Default false: the bridge only installs in dev builds. The ' +
505
512
  'runtime reader is the debug-bridge installer (D18).'),
506
513
  })
514
+ .strict()
507
515
  .optional()
508
516
  .describe('Debug-bridge production gating (D18) — governs whether ?vgai-debug=1 installs ' +
509
517
  'window.__vgai outside dev builds.'),
@@ -530,6 +538,7 @@ export const GameManifestSchema = z
530
538
  'even higher-precedence explicit config value a host passes directly. Optional — ' +
531
539
  "omit to fall back to the runtime's own fixed default seed."),
532
540
  })
541
+ .strict()
533
542
  .optional()
534
543
  .describe('Seeded-RNG determinism contract (D15) — governs ' +
535
544
  'whether ctx.random is boot-seeded from a reproducible seed and whether the ' +
@@ -576,6 +585,7 @@ export const GameManifestSchema = z
576
585
  "(the profiler's per-frame render.triangles, from renderer.info). Exact and " +
577
586
  'deterministic under a seed.'),
578
587
  })
588
+ .strict()
579
589
  .refine((budget) => Object.values(budget).some((value) => value !== undefined), {
580
590
  message: 'Game manifest: `budget` must set at least one metric (frameCpuMsP95, physicsMsP95, ' +
581
591
  'maxEntities, maxDrawCalls, maxTriangles) — an empty budget block gates nothing ' +