@vgai/engine 0.5.11 → 0.5.13

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 (152) hide show
  1. package/README.md +6 -5
  2. package/dist/adapter/authoring.d.ts +51 -28
  3. package/dist/adapter/authoring.d.ts.map +1 -1
  4. package/dist/adapter/body-marks.d.ts +59 -0
  5. package/dist/adapter/body-marks.d.ts.map +1 -0
  6. package/dist/adapter/body-marks.js +62 -0
  7. package/dist/adapter/constraint.d.ts +41 -0
  8. package/dist/adapter/constraint.d.ts.map +1 -0
  9. package/dist/adapter/constraint.js +27 -0
  10. package/dist/adapter/hierarchy-marks.d.ts +138 -0
  11. package/dist/adapter/hierarchy-marks.d.ts.map +1 -0
  12. package/dist/adapter/hierarchy-marks.js +148 -0
  13. package/dist/adapter/index.d.ts +1 -1
  14. package/dist/adapter/index.d.ts.map +1 -1
  15. package/dist/adapter/ingest/contract-system-adapters.d.ts +64 -0
  16. package/dist/adapter/ingest/contract-system-adapters.d.ts.map +1 -0
  17. package/dist/adapter/ingest/contract-system-adapters.js +134 -0
  18. package/dist/adapter/ingest/game-contract.d.ts +87 -9
  19. package/dist/adapter/ingest/game-contract.d.ts.map +1 -1
  20. package/dist/adapter/ingest/game-contract.js +7 -6
  21. package/dist/adapter/ingest/scene-capture.d.ts +31 -4
  22. package/dist/adapter/ingest/scene-capture.d.ts.map +1 -1
  23. package/dist/adapter/ingest/scene-capture.js +29 -7
  24. package/dist/adapter/ingest/structural-ids.d.ts +1 -1
  25. package/dist/adapter/ingest/structural-ids.js +2 -2
  26. package/dist/adapter/reflection-probe.d.ts +53 -0
  27. package/dist/adapter/reflection-probe.d.ts.map +1 -0
  28. package/dist/adapter/reflection-probe.js +18 -0
  29. package/dist/asset-formats/index.d.ts +4 -10
  30. package/dist/asset-formats/index.d.ts.map +1 -1
  31. package/dist/asset-formats/index.js +3 -8
  32. package/dist/asset-formats/material.d.ts +0 -66
  33. package/dist/asset-formats/material.d.ts.map +1 -1
  34. package/dist/asset-formats/material.js +0 -8
  35. package/dist/asset-formats/mesh.d.ts +1 -2
  36. package/dist/asset-formats/mesh.d.ts.map +1 -1
  37. package/dist/asset-formats/mesh.js +3 -13
  38. package/dist/asset-formats/render-env.d.ts +2 -2
  39. package/dist/asset-parse-error.d.ts +4 -5
  40. package/dist/asset-parse-error.d.ts.map +1 -1
  41. package/dist/asset-parse-error.js +4 -5
  42. package/dist/config.d.ts +7 -0
  43. package/dist/config.d.ts.map +1 -1
  44. package/dist/config.js +7 -0
  45. package/dist/data/curve.d.ts +116 -0
  46. package/dist/data/curve.d.ts.map +1 -0
  47. package/dist/data/curve.js +230 -0
  48. package/dist/data/vite-plugin-data.d.ts +2 -2
  49. package/dist/data/vite-plugin-data.d.ts.map +1 -1
  50. package/dist/data/vite-plugin-data.js +24 -15
  51. package/dist/dev/performance-profiler.d.ts +1 -0
  52. package/dist/dev/performance-profiler.d.ts.map +1 -1
  53. package/dist/dev/performance-profiler.js +25 -2
  54. package/dist/ecs/user-data.d.ts +49 -1
  55. package/dist/ecs/user-data.d.ts.map +1 -1
  56. package/dist/ecs/user-data.js +34 -0
  57. package/dist/index.d.ts +2 -3
  58. package/dist/index.d.ts.map +1 -1
  59. package/dist/index.js +2 -3
  60. package/dist/manifest/index.d.ts +3 -3
  61. package/dist/manifest/index.d.ts.map +1 -1
  62. package/dist/manifest/index.js +2 -2
  63. package/dist/manifest/load.d.ts +15 -67
  64. package/dist/manifest/load.d.ts.map +1 -1
  65. package/dist/manifest/load.js +11 -103
  66. package/dist/manifest/schema.d.ts +18 -103
  67. package/dist/manifest/schema.d.ts.map +1 -1
  68. package/dist/manifest/schema.js +59 -179
  69. package/dist/pixi/index.d.ts +2 -3
  70. package/dist/pixi/index.d.ts.map +1 -1
  71. package/dist/pixi/index.js +2 -3
  72. package/dist/pixi/ingest.d.ts +7 -75
  73. package/dist/pixi/ingest.d.ts.map +1 -1
  74. package/dist/pixi/ingest.js +6 -14
  75. package/dist/pixi/scene-capture.d.ts +2 -2
  76. package/dist/pixi/scene-capture.js +2 -2
  77. package/dist/react/use-data.d.ts +10 -5
  78. package/dist/react/use-data.d.ts.map +1 -1
  79. package/dist/react/use-data.js +15 -15
  80. package/dist/render/viewport-shading.d.ts +1 -1
  81. package/dist/render/viewport-shading.d.ts.map +1 -1
  82. package/dist/render/viewport-shading.js +14 -0
  83. package/dist/runtime/create-runtime.d.ts +12 -0
  84. package/dist/runtime/create-runtime.d.ts.map +1 -1
  85. package/dist/runtime/create-runtime.js +7 -2
  86. package/dist/runtime/mount-game.d.ts +1 -1
  87. package/dist/runtime/mount-game.d.ts.map +1 -1
  88. package/dist/runtime/mount-manifest.d.ts.map +1 -1
  89. package/dist/runtime/mount-manifest.js +5 -1
  90. package/dist/world3d-react/r3f-adapter.d.ts.map +1 -1
  91. package/dist/world3d-react/r3f-adapter.js +69 -39
  92. package/dist/world3d-react/renderer-config.d.ts +15 -0
  93. package/dist/world3d-react/renderer-config.d.ts.map +1 -1
  94. package/dist/world3d-react/renderer-config.js +15 -0
  95. package/dist/world3d-react/world-context.d.ts +2 -1
  96. package/dist/world3d-react/world-context.d.ts.map +1 -1
  97. package/dist-config/config.js +140 -20
  98. package/dist-config/config.js.map +4 -4
  99. package/package.json +1 -1
  100. package/schemas/engine-capabilities.json +10 -10
  101. package/schemas/vgai-project.schema.json +21 -76
  102. package/src/adapter/authoring.ts +54 -31
  103. package/src/adapter/body-marks.ts +69 -0
  104. package/src/adapter/constraint.ts +71 -0
  105. package/src/adapter/hierarchy-marks.ts +155 -0
  106. package/src/adapter/index.ts +2 -3
  107. package/src/adapter/ingest/contract-system-adapters.ts +174 -0
  108. package/src/adapter/ingest/game-contract.ts +98 -9
  109. package/src/adapter/ingest/scene-capture.ts +61 -11
  110. package/src/adapter/ingest/structural-ids.ts +2 -2
  111. package/src/adapter/reflection-probe.ts +75 -0
  112. package/src/asset-formats/index.ts +4 -10
  113. package/src/asset-formats/material.ts +0 -11
  114. package/src/asset-formats/mesh.ts +3 -16
  115. package/src/asset-parse-error.ts +4 -5
  116. package/src/config.ts +13 -0
  117. package/src/data/curve.ts +263 -0
  118. package/src/data/vite-plugin-data.ts +48 -14
  119. package/src/dev/performance-profiler.ts +21 -2
  120. package/src/ecs/user-data.ts +50 -0
  121. package/src/index.ts +2 -3
  122. package/src/manifest/index.ts +3 -15
  123. package/src/manifest/load.ts +27 -143
  124. package/src/manifest/schema.ts +65 -223
  125. package/src/pixi/index.ts +2 -15
  126. package/src/pixi/ingest.ts +13 -87
  127. package/src/pixi/scene-capture.ts +2 -2
  128. package/src/react/use-data.ts +15 -20
  129. package/src/render/viewport-shading.ts +16 -1
  130. package/src/runtime/create-runtime.ts +30 -5
  131. package/src/runtime/mount-game.ts +1 -1
  132. package/src/runtime/mount-manifest.ts +5 -1
  133. package/src/world3d-react/r3f-adapter.tsx +73 -39
  134. package/src/world3d-react/renderer-config.ts +31 -0
  135. package/src/world3d-react/world-context.ts +2 -1
  136. package/dist/asset-formats/instances.d.ts +0 -17
  137. package/dist/asset-formats/instances.d.ts.map +0 -1
  138. package/dist/asset-formats/instances.js +0 -31
  139. package/dist/asset-formats/parse.d.ts +0 -20
  140. package/dist/asset-formats/parse.d.ts.map +0 -1
  141. package/dist/asset-formats/parse.js +0 -34
  142. package/dist/pixi/ingest-iframe.d.ts +0 -82
  143. package/dist/pixi/ingest-iframe.d.ts.map +0 -1
  144. package/dist/pixi/ingest-iframe.js +0 -166
  145. package/dist/render/instance-mesh.d.ts +0 -5
  146. package/dist/render/instance-mesh.d.ts.map +0 -1
  147. package/dist/render/instance-mesh.js +0 -19
  148. package/schemas/mat.schema.json +0 -255
  149. package/src/asset-formats/instances.ts +0 -38
  150. package/src/asset-formats/parse.ts +0 -39
  151. package/src/pixi/ingest-iframe.ts +0 -255
  152. package/src/render/instance-mesh.ts +0 -25
@@ -0,0 +1,230 @@
1
+ /**
2
+ * Curve FIELDS in data assets — a response curve a designer shapes, living
3
+ * inside an ordinary `.data.json` like any other tunable value.
4
+ *
5
+ * A curve is a FIELD TYPE, never a file type: there is no `.curve.json`, no
6
+ * curve asset class, no baked LUT, and no document. `curve(axes)` is a real
7
+ * Zod schema you drop into a `*.schema.ts` beside `z.number()`, so the value
8
+ * lives in the same data file, hot-swaps through the same `defineData` handle,
9
+ * and is edited by the same Data panel that edits everything else.
10
+ *
11
+ * The JSON a designer (or an agent) reads and writes:
12
+ *
13
+ * ```json
14
+ * { "interpolation": "smooth",
15
+ * "points": [{ "x": 0, "y": 1 }, { "x": 12, "y": 0.85 }, { "x": 30, "y": 0.2 }] }
16
+ * ```
17
+ *
18
+ * TWO MODES, NO TANGENTS. `linear` and `smooth`, and nothing else. Per-key
19
+ * tangent handles would double the JSON, make it unreadable to an agent, and
20
+ * hand every author a way to make a curve overshoot its own points. Smoothness
21
+ * is DERIVED instead — Fritsch–Carlson monotone cubic tangents, computed from
22
+ * the points themselves — so the interpolant is guaranteed to stay inside each
23
+ * segment's `[yLeft, yRight]` band. "Shape it by moving points" is the whole
24
+ * authoring model.
25
+ *
26
+ * RUNG AUDIT (recorded decision, 2026-08-14): no npm dependency. The candidate
27
+ * packages (`monotone-cubic-spline` and its siblings) are unmaintained
28
+ * micro-packages, and d3's `curveMonotoneX` is an SVG PATH GENERATOR — it
29
+ * draws, it does not sample `y` at an `x`. What we need is ~40 lines of
30
+ * well-known numerics with no API surface, so it is written here.
31
+ *
32
+ * `sampleCurve` is the entire runtime: a pure function, no class, no cache
33
+ * object, no "curve system". Game code calls it every frame from its own
34
+ * update, the same way it reads any other tuning value.
35
+ */
36
+ import { z } from 'zod';
37
+ /** How the marker rides out to the emitted JSON Schema — the editor's and the dev menu's detection key, the exact shape `dataRef` uses with `x-vgai-ref`. */
38
+ const CURVE_META_KEY = 'x-vgai-curve';
39
+ function axisLabel(axes, axis) {
40
+ return axes[axis].label ?? axis;
41
+ }
42
+ /** Every out-of-domain / ordering problem in one pass, as teaching issues (`parseDataJson`'s "errors teach" doctrine, §6.5). */
43
+ function checkPoints(value, axes, ctx) {
44
+ const points = value.points;
45
+ for (let i = 0; i < points.length; i++) {
46
+ const point = points[i];
47
+ for (const axis of ['x', 'y']) {
48
+ const { min, max } = axes[axis];
49
+ if (point[axis] < min || point[axis] > max) {
50
+ ctx.addIssue({
51
+ code: 'custom',
52
+ path: ['points', i, axis],
53
+ message: `${point[axis]} is outside this curve's ${axisLabel(axes, axis)} domain ` +
54
+ `[${min}, ${max}] — move the point inside the domain, or widen the axis in the ` +
55
+ `schema (curve({ ${axis}: { min, max } })).`,
56
+ });
57
+ }
58
+ }
59
+ if (i === 0)
60
+ continue;
61
+ const previous = points[i - 1];
62
+ if (point.x <= previous.x) {
63
+ ctx.addIssue({
64
+ code: 'custom',
65
+ path: ['points', i, 'x'],
66
+ message: `${point.x} must be strictly greater than the previous point's x (${previous.x}) — ` +
67
+ 'curve points run left to right along x, with no duplicate x. Sort the points, or ' +
68
+ 'nudge this one.',
69
+ });
70
+ }
71
+ }
72
+ }
73
+ /**
74
+ * A Zod schema for a data-asset FIELD holding a response curve. Use it in a
75
+ * `.schema.ts` exactly like any other field:
76
+ *
77
+ * ```ts
78
+ * export const TuningSchema = z.object({
79
+ * spawnRate: z.number().min(0).max(10).default(1),
80
+ * difficultyRamp: curve({
81
+ * x: { min: 0, max: 300, label: 'Sim time (s)' },
82
+ * y: { min: 0, max: 2, label: 'Spawn multiplier' },
83
+ * }).describe('How hard the game leans on the player as the round runs.'),
84
+ * });
85
+ * ```
86
+ *
87
+ * The schema is STRICT (an unrecognized key is an error, never a silent
88
+ * strip), demands at least two points, and enforces strictly-increasing `x`
89
+ * with every point inside the declared axes — each with a message that names
90
+ * the fix rather than the rule.
91
+ *
92
+ * The emitted JSON Schema (`toDataJsonSchema`) carries
93
+ * `"x-vgai-curve": axes` — a Zod `.meta()`, which survives `z.toJSONSchema`
94
+ * including inside a table's `additionalProperties` row schema, exactly the
95
+ * way `dataRef`'s `"x-vgai-ref"` does. That marker is what makes the editor's
96
+ * Data panel render a curve EDITOR instead of a raw-JSON cell, with no emitter
97
+ * changes anywhere.
98
+ */
99
+ export function curve(axes) {
100
+ const point = z.strictObject({
101
+ x: z.number().describe(`Position along ${axisLabel(axes, 'x')}.`),
102
+ y: z.number().describe(`Value at that position, along ${axisLabel(axes, 'y')}.`),
103
+ });
104
+ return z
105
+ .strictObject({
106
+ interpolation: z
107
+ .enum(['linear', 'smooth'])
108
+ .describe('How the value moves between points: "linear" for straight segments, ' +
109
+ '"smooth" for a monotone cubic that never overshoots them.'),
110
+ points: z
111
+ .array(point)
112
+ .min(2, {
113
+ message: 'a curve needs at least two points — add another { "x": …, "y": … } so the ' +
114
+ 'value has somewhere to travel between.',
115
+ })
116
+ .describe('Keys in increasing x order; the value is clamped outside the first/last x.'),
117
+ })
118
+ .superRefine((value, ctx) => checkPoints(value, axes, ctx))
119
+ .meta({ [CURVE_META_KEY]: axes });
120
+ }
121
+ /**
122
+ * Read a curve field's declared axes back off a LIVE Zod schema (as opposed to
123
+ * the emitted JSON Schema, which the editor's Data panel reads instead).
124
+ *
125
+ * This is the dev-menu capability's detection door: it derives its rows by
126
+ * walking the game's own `TuningSchema` object, so it needs the axes from the
127
+ * schema in hand. Wrappers (`.optional()`, `.default(…)`, `.describe(…)` chains
128
+ * that re-wrap) hide the metadata behind an inner type, so a bounded unwrap
129
+ * walks down to it.
130
+ */
131
+ export function curveAxesOf(schema) {
132
+ let current = schema;
133
+ for (let depth = 0; depth < 5 && current; depth++) {
134
+ const meta = current.meta?.();
135
+ const axes = meta?.[CURVE_META_KEY];
136
+ if (axes && typeof axes === 'object' && 'x' in axes && 'y' in axes)
137
+ return axes;
138
+ current = current.def?.innerType;
139
+ }
140
+ return undefined;
141
+ }
142
+ /**
143
+ * Fritsch–Carlson tangents: the ordinary cubic-Hermite slopes, then limited so
144
+ * the interpolant cannot overshoot the data. This is what makes "smooth" safe
145
+ * to hand a designer — a curve that dips below its own points would silently
146
+ * feed the game a value nobody authored.
147
+ */
148
+ function monotoneTangents(points) {
149
+ const n = points.length;
150
+ const secants = [];
151
+ for (let i = 0; i < n - 1; i++) {
152
+ const left = points[i];
153
+ const right = points[i + 1];
154
+ secants.push((right.y - left.y) / (right.x - left.x));
155
+ }
156
+ const tangents = [secants[0]];
157
+ for (let i = 1; i < n - 1; i++) {
158
+ tangents.push((secants[i - 1] + secants[i]) / 2);
159
+ }
160
+ tangents.push(secants[n - 2]);
161
+ for (let i = 0; i < n - 1; i++) {
162
+ const secant = secants[i];
163
+ if (secant === 0) {
164
+ // A flat segment must stay flat: any slope at either end would bulge.
165
+ tangents[i] = 0;
166
+ tangents[i + 1] = 0;
167
+ continue;
168
+ }
169
+ let alpha = tangents[i] / secant;
170
+ let beta = tangents[i + 1] / secant;
171
+ // A tangent fighting the segment's own direction is a local extremum the
172
+ // data does not have.
173
+ if (alpha < 0) {
174
+ tangents[i] = 0;
175
+ alpha = 0;
176
+ }
177
+ if (beta < 0) {
178
+ tangents[i + 1] = 0;
179
+ beta = 0;
180
+ }
181
+ const radius = alpha * alpha + beta * beta;
182
+ if (radius > 9) {
183
+ const scale = 3 / Math.sqrt(radius);
184
+ tangents[i] = scale * alpha * secant;
185
+ tangents[i + 1] = scale * beta * secant;
186
+ }
187
+ }
188
+ return tangents;
189
+ }
190
+ /**
191
+ * The curve's value at `x` — the whole runtime API.
192
+ *
193
+ * Read it every frame from the game's own update, the way every other data
194
+ * value is read (`tuning.get()` then sample); never precompute a table, and
195
+ * never hold the result across frames — an edit to the `.data.json` hot-swaps
196
+ * underneath you and that is the point.
197
+ *
198
+ * Outside `[first.x, last.x]` the value CLAMPS to the nearest endpoint: a
199
+ * curve declares what it knows about, and extrapolating past it would invent
200
+ * numbers nobody authored.
201
+ */
202
+ export function sampleCurve(value, x) {
203
+ const points = value.points;
204
+ if (points.length === 0)
205
+ return 0;
206
+ const first = points[0];
207
+ const last = points[points.length - 1];
208
+ if (points.length === 1 || x <= first.x)
209
+ return first.y;
210
+ if (x >= last.x)
211
+ return last.y;
212
+ let i = 0;
213
+ while (i < points.length - 2 && x >= points[i + 1].x)
214
+ i++;
215
+ const left = points[i];
216
+ const right = points[i + 1];
217
+ const span = right.x - left.x;
218
+ if (span <= 0)
219
+ return left.y; // duplicate x — the schema rejects it; a hand-built value might not
220
+ const t = (x - left.x) / span;
221
+ if (value.interpolation === 'linear')
222
+ return left.y + (right.y - left.y) * t;
223
+ const tangents = monotoneTangents(points);
224
+ const t2 = t * t;
225
+ const t3 = t2 * t;
226
+ return ((2 * t3 - 3 * t2 + 1) * left.y +
227
+ (t3 - 2 * t2 + t) * span * tangents[i] +
228
+ (-2 * t3 + 3 * t2) * right.y +
229
+ (t3 - t2) * span * tangents[i + 1]);
230
+ }
@@ -54,10 +54,10 @@ export interface VgaiDataCheckOptions {
54
54
  * The fs half of checks 1 + 2, extracted from the plugin hook so it is
55
55
  * directly unit-testable against a fixture folder (no rollup context needed).
56
56
  */
57
- export declare function collectDataCheckProblems(options: VgaiDataCheckOptions): {
57
+ export declare function collectDataCheckProblems(options: VgaiDataCheckOptions): Promise<{
58
58
  errors: string[];
59
59
  warnings: string[];
60
- };
60
+ }>;
61
61
  /** True iff a bundled module id is tool code that must never ship (§4). Pure, unit-tested. */
62
62
  export declare function isToolModuleId(id: string): boolean;
63
63
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"vite-plugin-data.d.ts","sourceRoot":"","sources":["../../src/data/vite-plugin-data.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQ7B,4GAA4G;AAC5G,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC;IAC3B,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;IAC3C,mGAAmG;IACnG,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAuGD;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,oBAAoB,GAAG;IACvE,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CA2DA;AAED,8FAA8F;AAC9F,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAGlD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAmCnE"}
1
+ {"version":3,"file":"vite-plugin-data.d.ts","sourceRoot":"","sources":["../../src/data/vite-plugin-data.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAUH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQ7B,4GAA4G;AAC5G,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC;IAC3B,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;IAC3C,mGAAmG;IACnG,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AA4HD;;;GAGG;AACH,wBAAsB,wBAAwB,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC;IACrF,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC,CAkED;AAED,8FAA8F;AAC9F,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAGlD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAmCnE"}
@@ -37,24 +37,32 @@
37
37
  * and runtime parse-on-load, but no build-time schema check — the warning
38
38
  * names the registry file to fix.
39
39
  */
40
- import { readdirSync, readFileSync, statSync } from 'node:fs';
41
- import { join, relative } from 'node:path';
42
40
  import { parseDataJson, toDataJsonSchema } from './data-asset';
43
41
  import { collectDeclaredRefFields, findDanglingDataRefs, findMissingRefTargets, } from './data-check-core';
42
+ async function loadNodeIo() {
43
+ const [fs, path] = await Promise.all([import('node:fs'), import('node:path')]);
44
+ return {
45
+ readdirSync: fs.readdirSync,
46
+ readFileSync: fs.readFileSync,
47
+ statSync: fs.statSync,
48
+ join: path.join,
49
+ relative: path.relative,
50
+ };
51
+ }
44
52
  /** Recursively collect `*.data.json` under `dir` (absent dir → empty — a project with no data assets builds fine). */
45
- function findDataFiles(dir) {
53
+ function findDataFiles(io, dir) {
46
54
  let entries;
47
55
  try {
48
- entries = readdirSync(dir);
56
+ entries = io.readdirSync(dir);
49
57
  }
50
58
  catch {
51
59
  return [];
52
60
  }
53
61
  const out = [];
54
62
  for (const entry of entries) {
55
- const full = join(dir, entry);
56
- if (statSync(full).isDirectory())
57
- out.push(...findDataFiles(full));
63
+ const full = io.join(dir, entry);
64
+ if (io.statSync(full).isDirectory())
65
+ out.push(...findDataFiles(io, full));
58
66
  else if (entry.endsWith('.data.json'))
59
67
  out.push(full);
60
68
  }
@@ -68,11 +76,11 @@ function assetStem(sourcePath) {
68
76
  .pop()
69
77
  ?.replace(/\.data\.json$/, '') ?? rel);
70
78
  }
71
- function parseAllDataFiles(root, registered, errors, warnings) {
79
+ function parseAllDataFiles(io, root, registered, errors, warnings) {
72
80
  const parsedByStem = new Map();
73
81
  const pathsByStem = new Map();
74
- for (const abs of findDataFiles(join(root, 'src', 'data'))) {
75
- const rel = relative(root, abs).split('\\').join('/');
82
+ for (const abs of findDataFiles(io, io.join(root, 'src', 'data'))) {
83
+ const rel = io.relative(root, abs).split('\\').join('/');
76
84
  const stem = assetStem(rel);
77
85
  const paths = pathsByStem.get(stem);
78
86
  if (paths)
@@ -80,7 +88,7 @@ function parseAllDataFiles(root, registered, errors, warnings) {
80
88
  else
81
89
  pathsByStem.set(stem, [rel]);
82
90
  try {
83
- parsedByStem.set(stem, JSON.parse(readFileSync(abs, 'utf-8')));
91
+ parsedByStem.set(stem, JSON.parse(io.readFileSync(abs, 'utf-8')));
84
92
  }
85
93
  catch (err) {
86
94
  errors.push(`"${rel}" is not valid JSON: ${err instanceof Error ? err.message : String(err)}`);
@@ -109,12 +117,13 @@ function parseAllDataFiles(root, registered, errors, warnings) {
109
117
  * The fs half of checks 1 + 2, extracted from the plugin hook so it is
110
118
  * directly unit-testable against a fixture folder (no rollup context needed).
111
119
  */
112
- export function collectDataCheckProblems(options) {
120
+ export async function collectDataCheckProblems(options) {
121
+ const io = await loadNodeIo();
113
122
  const root = options.root ?? process.cwd();
114
123
  const errors = [];
115
124
  const warnings = [];
116
125
  const registered = new Set(options.assets.map((a) => a.sourcePath.split('\\').join('/')));
117
- const { parsedByStem, ambiguousStems } = parseAllDataFiles(root, registered, errors, warnings);
126
+ const { parsedByStem, ambiguousStems } = parseAllDataFiles(io, root, registered, errors, warnings);
118
127
  // Check 1 — registered assets validate through the exact runtime parse.
119
128
  for (const asset of options.assets) {
120
129
  const rel = asset.sourcePath.split('\\').join('/');
@@ -184,8 +193,8 @@ export function vgaiDataCheck(options) {
184
193
  return {
185
194
  name: 'vgai:data-check',
186
195
  apply: 'build',
187
- buildStart() {
188
- const { errors, warnings } = collectDataCheckProblems(options);
196
+ async buildStart() {
197
+ const { errors, warnings } = await collectDataCheckProblems(options);
189
198
  for (const warning of warnings)
190
199
  this.warn(warning);
191
200
  if (errors.length > 0) {
@@ -85,6 +85,7 @@ export interface PerformanceSnapshot {
85
85
  /** Game-owned, bounded external store for browser-native performance diagnostics. */
86
86
  export declare function createPerformanceProfiler(initiallyEnabled?: boolean): {
87
87
  enabled: boolean;
88
+ telemetryEnabled: boolean;
88
89
  readonly recording: boolean;
89
90
  startRecording(): void;
90
91
  stopRecording(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"performance-profiler.d.ts","sourceRoot":"","sources":["../../src/dev/performance-profiler.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,yEAAyE;AACzE,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;;;;OAOG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC9C;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS,eAAe,EAAE,CAAC;IAChD;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAC;CACzC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC7C,QAAQ,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC9C,QAAQ,CAAC,OAAO,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC/C,QAAQ,CAAC,UAAU,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAClD,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAC;CACzC;AAUD,qFAAqF;AACrF,wBAAgB,yBAAyB,CAAC,gBAAgB,UAAQ;aA8E3C,OAAO;;;;;;;mBA8CX,MAAM;;;yBAqBF,MAAM,SAAS,MAAM,QAAQ,MAAM;;;uBAiBnC,MAAM;wBAWL;QAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB;2DACmD;QACnD,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB;;wBAqCmB,MAAM,IAAI;;;EAejC;AAED,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC"}
1
+ {"version":3,"file":"performance-profiler.d.ts","sourceRoot":"","sources":["../../src/dev/performance-profiler.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,yEAAyE;AACzE,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;;;;OAOG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC9C;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS,eAAe,EAAE,CAAC;IAChD;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAC;CACzC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC7C,QAAQ,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC9C,QAAQ,CAAC,OAAO,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC/C,QAAQ,CAAC,UAAU,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAClD,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAC;CACzC;AAUD,qFAAqF;AACrF,wBAAgB,yBAAyB,CAAC,gBAAgB,UAAQ;aAoF3C,OAAO;sBASE,OAAO;;;;;;;mBAkDpB,MAAM;;;yBAqBF,MAAM,SAAS,MAAM,QAAQ,MAAM;;;uBAiBnC,MAAM;wBAWL;QAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB;2DACmD;QACnD,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB;;wBAqCmB,MAAM,IAAI;;;EAejC;AAED,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC"}
@@ -19,6 +19,12 @@ export function createPerformanceProfiler(initiallyEnabled = false) {
19
19
  let frameSystems = [];
20
20
  let frameComponents = [];
21
21
  let enabled = initiallyEnabled;
22
+ // The header's always-visible FPS sparkline needs frame INTERVALS without
23
+ // turning on the full profiler. Full profiling measures phases/systems,
24
+ // issues GPU timer queries at render sites, and intentionally warns about
25
+ // overhead; a glanceable heartbeat must not silently opt the user into all
26
+ // of that work. `telemetryEnabled` records only the frame envelope.
27
+ let telemetryEnabled = false;
22
28
  let recording = false;
23
29
  let frameId = 0;
24
30
  let frameStart = 0;
@@ -87,13 +93,30 @@ export function createPerformanceProfiler(initiallyEnabled = false) {
87
93
  if (enabled === value)
88
94
  return;
89
95
  enabled = value;
96
+ if (value && !telemetryEnabled)
97
+ lastFrameStart = 0;
98
+ publish();
99
+ },
100
+ get telemetryEnabled() {
101
+ return telemetryEnabled;
102
+ },
103
+ set telemetryEnabled(value) {
104
+ if (telemetryEnabled === value)
105
+ return;
106
+ const wasInactive = !enabled && !telemetryEnabled;
107
+ telemetryEnabled = value;
108
+ if (value && wasInactive)
109
+ lastFrameStart = 0;
90
110
  publish();
91
111
  },
92
112
  get recording() {
93
113
  return recording;
94
114
  },
95
115
  startRecording() {
116
+ const wasInactive = !enabled && !telemetryEnabled;
96
117
  enabled = true;
118
+ if (wasInactive)
119
+ lastFrameStart = 0;
97
120
  recording = true;
98
121
  frames.length = 0;
99
122
  publish();
@@ -107,7 +130,7 @@ export function createPerformanceProfiler(initiallyEnabled = false) {
107
130
  publish();
108
131
  },
109
132
  beginFrame() {
110
- if (!enabled)
133
+ if (!enabled && !telemetryEnabled)
111
134
  return;
112
135
  currentPhases.clear();
113
136
  currentSystems.clear();
@@ -201,7 +224,7 @@ export function createPerformanceProfiler(initiallyEnabled = false) {
201
224
  };
202
225
  },
203
226
  endFrame() {
204
- if (!enabled)
227
+ if (!enabled && !telemetryEnabled)
205
228
  return;
206
229
  const timestamp = now();
207
230
  const intervalMs = lastFrameStart === 0 ? 0 : frameStart - lastFrameStart;
@@ -76,20 +76,50 @@
76
76
  * implementation parts without adding wrappers.
77
77
  * - `authoringLabel` — authored literal name (or component tag fallback)
78
78
  * for that source-backed component instance.
79
+ * - `authoringComponent` — exact source component identity for portable-CSF
80
+ * association; unlike the label, never user-facing copy.
81
+ * - `authoringDocument` — generic reference to the project-tool document
82
+ * that owns this scene instance's authored asset.
79
83
  * - `editorHelper` — `true` for editor-only helper objects (gizmos, wireframes).
84
+ *
85
+ * Hierarchy-presentation convention (written by GAME code, read by the editor —
86
+ * see `../adapter/hierarchy-marks.ts`, which is the ONLY place these two are
87
+ * read/written from; the `vgai` prefix marks them as the HOST's namespace on a
88
+ * node a game owns, unlike every other key above, which the engine/editor also
89
+ * write):
90
+ * - `vgaiComponentRoot` — display name of the component instance this subtree
91
+ * IS. The node renders as one collapsed, expandable
92
+ * row named for it.
93
+ * - `vgaiBuiltInternal` — `true` on the ROOT of a subtree runtime code
94
+ * CONSTRUCTED rather than authored (skeleton bones,
95
+ * particle renderers). Subtree-scoped: everything
96
+ * below a marked node is built-internal too.
97
+ * - `vgaiBodyOwner` — the rigid body that OWNS this node's pose, written
98
+ * by the code that attaches the body (see
99
+ * `../adapter/body-marks.ts`, the only reader/writer).
100
+ * A transform edit on such a node must be applied to
101
+ * the BODY, or the next physics step writes the node
102
+ * straight back.
80
103
  * - `editorHelperType` — which kind of helper (lights/particles/pivot/navmesh/...).
81
104
  * - `editorIcon` — `true` for editor billboard icon sprites.
82
105
  * - `skeletonVisible` — per-entity editor preference for its bone overlay.
83
106
  * - `skeletonEnabled` — resolved visibility preference on a skeleton helper.
84
107
  * - `envObject` — `true` for environment objects (ambient light, etc.).
108
+ * - `reflectionProbe` — live project-owned reflection probe projected from
109
+ * JSX props for renderer/editor integration.
110
+ * - `constraints` — live project-owned spatial constraints projected
111
+ * into the shared Inspector and viewport.
85
112
  * - `splineControlPoint` — index of a spline control-point drag handle.
86
113
  * - `vcDirIdx` — view-cube face direction index (0=+X,1=-X,2=+Y,...).
87
114
  */
88
115
  import type * as THREE from 'three';
89
116
  import type { ParticleSystem } from 'three.quarks';
117
+ import type { ConstraintMark } from '../adapter/constraint';
118
+ import type { RapierEditableBody } from '../adapter/rapier-physics-adapter';
119
+ import type { ReflectionProbeMark } from '../adapter/reflection-probe';
90
120
  import type { XStateAnimationBinding } from '../animation/xstate-animation-binding';
91
121
  /** The kinds of editor helper objects tagged via `editorHelperType`. */
92
- export type EditorHelperType = 'lights' | 'cameras' | 'audio' | 'colliders' | 'joints' | 'lod' | 'splines' | 'particles' | 'particle-shape' | 'pivot' | 'navmesh' | 'skeletons';
122
+ export type EditorHelperType = 'lights' | 'cameras' | 'audio' | 'colliders' | 'joints' | 'lod' | 'splines' | 'particles' | 'particle-shape' | 'pivot' | 'navmesh' | 'constraints' | 'reflection-probes' | 'skeletons';
93
123
  /**
94
124
  * Maps each canonical accessor name to its value type. This is the single
95
125
  * source of truth for what every known `userData` key holds.
@@ -122,12 +152,23 @@ export interface UserDataSchema {
122
152
  authoringRoot: boolean;
123
153
  authoringInstance: string;
124
154
  authoringLabel: string;
155
+ vgaiComponentRoot: string;
156
+ vgaiBuiltInternal: boolean;
157
+ vgaiBodyOwner: RapierEditableBody;
158
+ authoringComponent: string;
159
+ authoringDocument: {
160
+ readonly kind: 'project-tool';
161
+ readonly name: string;
162
+ readonly title: string;
163
+ };
125
164
  editorHelper: boolean;
126
165
  editorHelperType: EditorHelperType;
127
166
  editorIcon: boolean;
128
167
  skeletonVisible: boolean;
129
168
  skeletonEnabled: boolean;
130
169
  envObject: boolean;
170
+ constraints: readonly ConstraintMark[];
171
+ reflectionProbe: ReflectionProbeMark;
131
172
  vcDirIdx: number;
132
173
  /** W1a navmesh path-probe preview polyline: the routed waypoints, mirrored
133
174
  * onto the preview line Object3D so e2e can read the path back from the
@@ -170,12 +211,19 @@ export declare const UserDataKeys: {
170
211
  readonly authoringRoot: "authoringRoot";
171
212
  readonly authoringInstance: "authoringInstance";
172
213
  readonly authoringLabel: "authoringLabel";
214
+ readonly vgaiComponentRoot: "vgaiComponentRoot";
215
+ readonly vgaiBuiltInternal: "vgaiBuiltInternal";
216
+ readonly vgaiBodyOwner: "vgaiBodyOwner";
217
+ readonly authoringComponent: "authoringComponent";
218
+ readonly authoringDocument: "authoringDocument";
173
219
  readonly editorHelper: "editorHelper";
174
220
  readonly editorHelperType: "editorHelperType";
175
221
  readonly editorIcon: "editorIcon";
176
222
  readonly skeletonVisible: "skeletonVisible";
177
223
  readonly skeletonEnabled: "skeletonEnabled";
178
224
  readonly envObject: "envObject";
225
+ readonly constraints: "constraints";
226
+ readonly reflectionProbe: "reflectionProbe";
179
227
  readonly vcDirIdx: "vcDirIdx";
180
228
  readonly navPathPoints: "navPathPoints";
181
229
  };
@@ -1 +1 @@
1
- {"version":3,"file":"user-data.d.ts","sourceRoot":"","sources":["../../src/ecs/user-data.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"user-data.d.ts","sourceRoot":"","sources":["../../src/ecs/user-data.ts"],"names":[],"mappings":"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"}
@@ -76,12 +76,39 @@
76
76
  * implementation parts without adding wrappers.
77
77
  * - `authoringLabel` — authored literal name (or component tag fallback)
78
78
  * for that source-backed component instance.
79
+ * - `authoringComponent` — exact source component identity for portable-CSF
80
+ * association; unlike the label, never user-facing copy.
81
+ * - `authoringDocument` — generic reference to the project-tool document
82
+ * that owns this scene instance's authored asset.
79
83
  * - `editorHelper` — `true` for editor-only helper objects (gizmos, wireframes).
84
+ *
85
+ * Hierarchy-presentation convention (written by GAME code, read by the editor —
86
+ * see `../adapter/hierarchy-marks.ts`, which is the ONLY place these two are
87
+ * read/written from; the `vgai` prefix marks them as the HOST's namespace on a
88
+ * node a game owns, unlike every other key above, which the engine/editor also
89
+ * write):
90
+ * - `vgaiComponentRoot` — display name of the component instance this subtree
91
+ * IS. The node renders as one collapsed, expandable
92
+ * row named for it.
93
+ * - `vgaiBuiltInternal` — `true` on the ROOT of a subtree runtime code
94
+ * CONSTRUCTED rather than authored (skeleton bones,
95
+ * particle renderers). Subtree-scoped: everything
96
+ * below a marked node is built-internal too.
97
+ * - `vgaiBodyOwner` — the rigid body that OWNS this node's pose, written
98
+ * by the code that attaches the body (see
99
+ * `../adapter/body-marks.ts`, the only reader/writer).
100
+ * A transform edit on such a node must be applied to
101
+ * the BODY, or the next physics step writes the node
102
+ * straight back.
80
103
  * - `editorHelperType` — which kind of helper (lights/particles/pivot/navmesh/...).
81
104
  * - `editorIcon` — `true` for editor billboard icon sprites.
82
105
  * - `skeletonVisible` — per-entity editor preference for its bone overlay.
83
106
  * - `skeletonEnabled` — resolved visibility preference on a skeleton helper.
84
107
  * - `envObject` — `true` for environment objects (ambient light, etc.).
108
+ * - `reflectionProbe` — live project-owned reflection probe projected from
109
+ * JSX props for renderer/editor integration.
110
+ * - `constraints` — live project-owned spatial constraints projected
111
+ * into the shared Inspector and viewport.
85
112
  * - `splineControlPoint` — index of a spline control-point drag handle.
86
113
  * - `vcDirIdx` — view-cube face direction index (0=+X,1=-X,2=+Y,...).
87
114
  */
@@ -115,12 +142,19 @@ export const UserDataKeys = {
115
142
  authoringRoot: 'authoringRoot',
116
143
  authoringInstance: 'authoringInstance',
117
144
  authoringLabel: 'authoringLabel',
145
+ vgaiComponentRoot: 'vgaiComponentRoot',
146
+ vgaiBuiltInternal: 'vgaiBuiltInternal',
147
+ vgaiBodyOwner: 'vgaiBodyOwner',
148
+ authoringComponent: 'authoringComponent',
149
+ authoringDocument: 'authoringDocument',
118
150
  editorHelper: 'editorHelper',
119
151
  editorHelperType: 'editorHelperType',
120
152
  editorIcon: 'editorIcon',
121
153
  skeletonVisible: 'skeletonVisible',
122
154
  skeletonEnabled: 'skeletonEnabled',
123
155
  envObject: 'envObject',
156
+ constraints: 'constraints',
157
+ reflectionProbe: 'reflectionProbe',
124
158
  vcDirIdx: 'vcDirIdx',
125
159
  navPathPoints: 'navPathPoints',
126
160
  };
package/dist/index.d.ts CHANGED
@@ -20,14 +20,13 @@
20
20
  * - game setup contract: `GameContext`/`GameCleanup`/`GameSetupFn`, `fromSetup`
21
21
  * - surface vocabulary: `AdapterSurface`
22
22
  * - manifest-driven mount: `mountManifestRoots` + its option/result types
23
- * - asset-format entry points: `parseMaterialFile` (.mat.json), `parseInstancesFile`
24
23
  * - game manifest (vgai.project.json) entry point: `loadGameManifest`
25
24
  */
26
25
  export type { AdapterSurface } from './adapter/adapter-surface';
27
26
  export { fromSetup } from './adapter/setup-three-root-adapter';
28
- export { AssetParseError, parseInstancesFile, parseMaterialFile } from './asset-formats/parse';
27
+ export { AssetParseError } from './asset-parse-error';
29
28
  export type { AdapterRoot, GameManifest, ResolvedAdapter, ResolvedAdapterRoot, ResolvedGameManifest, RootAdapter, } from './manifest';
30
- export { CAPABILITY_CEILINGS, DEFAULT_SERVER_MODULE, loadGameManifest } from './manifest';
29
+ export { DEFAULT_SERVER_MODULE, loadGameManifest } from './manifest';
31
30
  export type { GameSession } from './runtime/create-runtime';
32
31
  export type { MountEntry, MountedManifestSession, MountManifestOptions, } from './runtime/mount-manifest';
33
32
  export { mountManifestRoots } from './runtime/mount-manifest';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/F,YAAY,EACV,WAAW,EACX,YAAY,EACZ,eAAe,EACf,mBAAmB,EACnB,oBAAoB,EACpB,WAAW,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC1F,YAAY,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,YAAY,EACV,UAAU,EACV,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,YAAY,EACV,WAAW,EACX,YAAY,EACZ,eAAe,EACf,mBAAmB,EACnB,oBAAoB,EACpB,WAAW,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACrE,YAAY,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,YAAY,EACV,UAAU,EACV,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -20,10 +20,9 @@
20
20
  * - game setup contract: `GameContext`/`GameCleanup`/`GameSetupFn`, `fromSetup`
21
21
  * - surface vocabulary: `AdapterSurface`
22
22
  * - manifest-driven mount: `mountManifestRoots` + its option/result types
23
- * - asset-format entry points: `parseMaterialFile` (.mat.json), `parseInstancesFile`
24
23
  * - game manifest (vgai.project.json) entry point: `loadGameManifest`
25
24
  */
26
25
  export { fromSetup } from './adapter/setup-three-root-adapter';
27
- export { AssetParseError, parseInstancesFile, parseMaterialFile } from './asset-formats/parse';
28
- export { CAPABILITY_CEILINGS, DEFAULT_SERVER_MODULE, loadGameManifest } from './manifest';
26
+ export { AssetParseError } from './asset-parse-error';
27
+ export { DEFAULT_SERVER_MODULE, loadGameManifest } from './manifest';
29
28
  export { mountManifestRoots } from './runtime/mount-manifest';
@@ -1,6 +1,6 @@
1
1
  export { isManifestFilename, MANIFEST_FILENAME, REMOVED_MANIFEST_FILENAME, removedManifestFilenameMessage, } from './filename';
2
2
  export type { ResolvedAdapter, ResolvedAdapterRoot, ResolvedGameManifest } from './load';
3
- export { CAPABILITY_CEILINGS, DEFAULT_SERVER_MODULE, loadGameManifest } from './load';
4
- export type { AdapterRoot, GameManifest, IngestStrategy, RootAdapter, Tier, } from './schema';
5
- export { AdapterRootSchema, GameManifestSchema, IngestStrategySchema, RootAdapterSchema, TierSchema, } from './schema';
3
+ export { DEFAULT_SERVER_MODULE, loadGameManifest } from './load';
4
+ export type { AdapterRoot, GameManifest, RootAdapter } from './schema';
5
+ export { AdapterRootSchema, GameManifestSchema, RootAdapterSchema } from './schema';
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/manifest/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,yBAAyB,EACzB,8BAA8B,GAC/B,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AACzF,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AACtF,YAAY,EACV,WAAW,EACX,YAAY,EACZ,cAAc,EACd,WAAW,EACX,IAAI,GACL,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,UAAU,GACX,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/manifest/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,yBAAyB,EACzB,8BAA8B,GAC/B,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AACzF,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AACjE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC"}