@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.
- package/README.md +6 -5
- package/dist/adapter/authoring.d.ts +51 -28
- package/dist/adapter/authoring.d.ts.map +1 -1
- package/dist/adapter/body-marks.d.ts +59 -0
- package/dist/adapter/body-marks.d.ts.map +1 -0
- package/dist/adapter/body-marks.js +62 -0
- package/dist/adapter/constraint.d.ts +41 -0
- package/dist/adapter/constraint.d.ts.map +1 -0
- package/dist/adapter/constraint.js +27 -0
- package/dist/adapter/hierarchy-marks.d.ts +138 -0
- package/dist/adapter/hierarchy-marks.d.ts.map +1 -0
- package/dist/adapter/hierarchy-marks.js +148 -0
- package/dist/adapter/index.d.ts +1 -1
- package/dist/adapter/index.d.ts.map +1 -1
- package/dist/adapter/ingest/contract-system-adapters.d.ts +64 -0
- package/dist/adapter/ingest/contract-system-adapters.d.ts.map +1 -0
- package/dist/adapter/ingest/contract-system-adapters.js +134 -0
- package/dist/adapter/ingest/game-contract.d.ts +87 -9
- package/dist/adapter/ingest/game-contract.d.ts.map +1 -1
- package/dist/adapter/ingest/game-contract.js +7 -6
- package/dist/adapter/ingest/scene-capture.d.ts +31 -4
- package/dist/adapter/ingest/scene-capture.d.ts.map +1 -1
- package/dist/adapter/ingest/scene-capture.js +29 -7
- package/dist/adapter/ingest/structural-ids.d.ts +1 -1
- package/dist/adapter/ingest/structural-ids.js +2 -2
- package/dist/adapter/reflection-probe.d.ts +53 -0
- package/dist/adapter/reflection-probe.d.ts.map +1 -0
- package/dist/adapter/reflection-probe.js +18 -0
- package/dist/asset-formats/index.d.ts +4 -10
- package/dist/asset-formats/index.d.ts.map +1 -1
- package/dist/asset-formats/index.js +3 -8
- package/dist/asset-formats/material.d.ts +0 -66
- package/dist/asset-formats/material.d.ts.map +1 -1
- package/dist/asset-formats/material.js +0 -8
- package/dist/asset-formats/mesh.d.ts +1 -2
- package/dist/asset-formats/mesh.d.ts.map +1 -1
- package/dist/asset-formats/mesh.js +3 -13
- package/dist/asset-formats/render-env.d.ts +2 -2
- package/dist/asset-parse-error.d.ts +4 -5
- package/dist/asset-parse-error.d.ts.map +1 -1
- package/dist/asset-parse-error.js +4 -5
- package/dist/config.d.ts +7 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +7 -0
- package/dist/data/curve.d.ts +116 -0
- package/dist/data/curve.d.ts.map +1 -0
- package/dist/data/curve.js +230 -0
- package/dist/data/vite-plugin-data.d.ts +2 -2
- package/dist/data/vite-plugin-data.d.ts.map +1 -1
- package/dist/data/vite-plugin-data.js +24 -15
- package/dist/dev/performance-profiler.d.ts +1 -0
- package/dist/dev/performance-profiler.d.ts.map +1 -1
- package/dist/dev/performance-profiler.js +25 -2
- package/dist/ecs/user-data.d.ts +49 -1
- package/dist/ecs/user-data.d.ts.map +1 -1
- package/dist/ecs/user-data.js +34 -0
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -3
- package/dist/manifest/index.d.ts +3 -3
- package/dist/manifest/index.d.ts.map +1 -1
- package/dist/manifest/index.js +2 -2
- package/dist/manifest/load.d.ts +15 -67
- package/dist/manifest/load.d.ts.map +1 -1
- package/dist/manifest/load.js +11 -103
- package/dist/manifest/schema.d.ts +18 -103
- package/dist/manifest/schema.d.ts.map +1 -1
- package/dist/manifest/schema.js +59 -179
- package/dist/pixi/index.d.ts +2 -3
- package/dist/pixi/index.d.ts.map +1 -1
- package/dist/pixi/index.js +2 -3
- package/dist/pixi/ingest.d.ts +7 -75
- package/dist/pixi/ingest.d.ts.map +1 -1
- package/dist/pixi/ingest.js +6 -14
- package/dist/pixi/scene-capture.d.ts +2 -2
- package/dist/pixi/scene-capture.js +2 -2
- package/dist/react/use-data.d.ts +10 -5
- package/dist/react/use-data.d.ts.map +1 -1
- package/dist/react/use-data.js +15 -15
- package/dist/render/viewport-shading.d.ts +1 -1
- package/dist/render/viewport-shading.d.ts.map +1 -1
- package/dist/render/viewport-shading.js +14 -0
- package/dist/runtime/create-runtime.d.ts +12 -0
- package/dist/runtime/create-runtime.d.ts.map +1 -1
- package/dist/runtime/create-runtime.js +7 -2
- package/dist/runtime/mount-game.d.ts +1 -1
- package/dist/runtime/mount-game.d.ts.map +1 -1
- package/dist/runtime/mount-manifest.d.ts.map +1 -1
- package/dist/runtime/mount-manifest.js +5 -1
- package/dist/world3d-react/r3f-adapter.d.ts.map +1 -1
- package/dist/world3d-react/r3f-adapter.js +69 -39
- package/dist/world3d-react/renderer-config.d.ts +15 -0
- package/dist/world3d-react/renderer-config.d.ts.map +1 -1
- package/dist/world3d-react/renderer-config.js +15 -0
- package/dist/world3d-react/world-context.d.ts +2 -1
- package/dist/world3d-react/world-context.d.ts.map +1 -1
- package/dist-config/config.js +140 -20
- package/dist-config/config.js.map +4 -4
- package/package.json +1 -1
- package/schemas/engine-capabilities.json +10 -10
- package/schemas/vgai-project.schema.json +21 -76
- package/src/adapter/authoring.ts +54 -31
- package/src/adapter/body-marks.ts +69 -0
- package/src/adapter/constraint.ts +71 -0
- package/src/adapter/hierarchy-marks.ts +155 -0
- package/src/adapter/index.ts +2 -3
- package/src/adapter/ingest/contract-system-adapters.ts +174 -0
- package/src/adapter/ingest/game-contract.ts +98 -9
- package/src/adapter/ingest/scene-capture.ts +61 -11
- package/src/adapter/ingest/structural-ids.ts +2 -2
- package/src/adapter/reflection-probe.ts +75 -0
- package/src/asset-formats/index.ts +4 -10
- package/src/asset-formats/material.ts +0 -11
- package/src/asset-formats/mesh.ts +3 -16
- package/src/asset-parse-error.ts +4 -5
- package/src/config.ts +13 -0
- package/src/data/curve.ts +263 -0
- package/src/data/vite-plugin-data.ts +48 -14
- package/src/dev/performance-profiler.ts +21 -2
- package/src/ecs/user-data.ts +50 -0
- package/src/index.ts +2 -3
- package/src/manifest/index.ts +3 -15
- package/src/manifest/load.ts +27 -143
- package/src/manifest/schema.ts +65 -223
- package/src/pixi/index.ts +2 -15
- package/src/pixi/ingest.ts +13 -87
- package/src/pixi/scene-capture.ts +2 -2
- package/src/react/use-data.ts +15 -20
- package/src/render/viewport-shading.ts +16 -1
- package/src/runtime/create-runtime.ts +30 -5
- package/src/runtime/mount-game.ts +1 -1
- package/src/runtime/mount-manifest.ts +5 -1
- package/src/world3d-react/r3f-adapter.tsx +73 -39
- package/src/world3d-react/renderer-config.ts +31 -0
- package/src/world3d-react/world-context.ts +2 -1
- package/dist/asset-formats/instances.d.ts +0 -17
- package/dist/asset-formats/instances.d.ts.map +0 -1
- package/dist/asset-formats/instances.js +0 -31
- package/dist/asset-formats/parse.d.ts +0 -20
- package/dist/asset-formats/parse.d.ts.map +0 -1
- package/dist/asset-formats/parse.js +0 -34
- package/dist/pixi/ingest-iframe.d.ts +0 -82
- package/dist/pixi/ingest-iframe.d.ts.map +0 -1
- package/dist/pixi/ingest-iframe.js +0 -166
- package/dist/render/instance-mesh.d.ts +0 -5
- package/dist/render/instance-mesh.d.ts.map +0 -1
- package/dist/render/instance-mesh.js +0 -19
- package/schemas/mat.schema.json +0 -255
- package/src/asset-formats/instances.ts +0 -38
- package/src/asset-formats/parse.ts +0 -39
- package/src/pixi/ingest-iframe.ts +0 -255
- 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;
|
|
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;
|
|
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;
|
package/dist/ecs/user-data.d.ts
CHANGED
|
@@ -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":"AAAA
|
|
1
|
+
{"version":3,"file":"user-data.d.ts","sourceRoot":"","sources":["../../src/ecs/user-data.ts"],"names":[],"mappings":"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"}
|
package/dist/ecs/user-data.js
CHANGED
|
@@ -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
|
|
27
|
+
export { AssetParseError } from './asset-parse-error';
|
|
29
28
|
export type { AdapterRoot, GameManifest, ResolvedAdapter, ResolvedAdapterRoot, ResolvedGameManifest, RootAdapter, } from './manifest';
|
|
30
|
-
export {
|
|
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';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
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
|
|
28
|
-
export {
|
|
26
|
+
export { AssetParseError } from './asset-parse-error';
|
|
27
|
+
export { DEFAULT_SERVER_MODULE, loadGameManifest } from './manifest';
|
|
29
28
|
export { mountManifestRoots } from './runtime/mount-manifest';
|
package/dist/manifest/index.d.ts
CHANGED
|
@@ -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 {
|
|
4
|
-
export type { AdapterRoot, GameManifest,
|
|
5
|
-
export { AdapterRootSchema, GameManifestSchema,
|
|
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,
|
|
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"}
|