@forgeax/engine-scene 0.1.7 → 0.1.20
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/dist/.tsbuildinfo +1 -1
- package/dist/index.mjs +64 -229
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -4
package/dist/index.mjs
CHANGED
|
@@ -1,182 +1,8 @@
|
|
|
1
|
-
// ../types/dist/index.mjs
|
|
2
|
-
var OK_PROTO = {
|
|
3
|
-
unwrap() {
|
|
4
|
-
return this.value;
|
|
5
|
-
},
|
|
6
|
-
unwrapOr(_defaultValue) {
|
|
7
|
-
return this.value;
|
|
8
|
-
}
|
|
9
|
-
};
|
|
10
|
-
var ERR_PROTO = {
|
|
11
|
-
unwrap() {
|
|
12
|
-
throw this.error;
|
|
13
|
-
},
|
|
14
|
-
unwrapOr(defaultValue) {
|
|
15
|
-
return defaultValue;
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
function ok(value) {
|
|
19
|
-
const r = Object.create(OK_PROTO);
|
|
20
|
-
r.ok = true;
|
|
21
|
-
r.value = value;
|
|
22
|
-
return r;
|
|
23
|
-
}
|
|
24
|
-
function err(error) {
|
|
25
|
-
const r = Object.create(ERR_PROTO);
|
|
26
|
-
r.ok = false;
|
|
27
|
-
r.error = error;
|
|
28
|
-
return r;
|
|
29
|
-
}
|
|
30
|
-
function toUnique(raw) {
|
|
31
|
-
return raw;
|
|
32
|
-
}
|
|
33
|
-
function unwrapHandle(h) {
|
|
34
|
-
return h;
|
|
35
|
-
}
|
|
36
|
-
var MAX_SLOT = (1 << 24) - 1;
|
|
37
|
-
var MATERIAL_ERROR_CODES = [
|
|
38
|
-
"material-parent-not-found",
|
|
39
|
-
"material-circular-inheritance",
|
|
40
|
-
"material-no-effective-pass",
|
|
41
|
-
"material-value-unknown",
|
|
42
|
-
"material-value-type-mismatch",
|
|
43
|
-
"material-contract-program-mismatch",
|
|
44
|
-
"shader-module-id-missing",
|
|
45
|
-
"shader-module-id-duplicate",
|
|
46
|
-
"shader-module-not-found",
|
|
47
|
-
"shader-module-namespace-reserved",
|
|
48
|
-
"material-reflection-binding-mismatch",
|
|
49
|
-
"material-specialization-not-cooked",
|
|
50
|
-
"material-specialization-stale-generation",
|
|
51
|
-
"gltf-material-uv-set-missing",
|
|
52
|
-
"material-derived-interface-mismatch",
|
|
53
|
-
"material-texture-coordinate-invalid",
|
|
54
|
-
"material-payload-bounds"
|
|
55
|
-
];
|
|
56
|
-
var MATERIAL_ERROR_POLICY = {
|
|
57
|
-
"material-parent-not-found": {
|
|
58
|
-
expected: "every parent GUID resolves to a MaterialAsset",
|
|
59
|
-
hint: "fix the parent GUID and resolve the material again"
|
|
60
|
-
},
|
|
61
|
-
"material-circular-inheritance": {
|
|
62
|
-
expected: "the parent chain is acyclic",
|
|
63
|
-
hint: "remove the repeated GUID from the parent chain"
|
|
64
|
-
},
|
|
65
|
-
"material-no-effective-pass": {
|
|
66
|
-
expected: "the resolved material has at least one pass",
|
|
67
|
-
hint: "add a pass to the root material or an inherited parent"
|
|
68
|
-
},
|
|
69
|
-
"material-value-unknown": {
|
|
70
|
-
expected: "every value name is declared by the effective contract",
|
|
71
|
-
hint: "remove the value or declare the parameter in the root contract"
|
|
72
|
-
},
|
|
73
|
-
"material-value-type-mismatch": {
|
|
74
|
-
expected: "each value matches its declared parameter type",
|
|
75
|
-
hint: "change the value to the declared parameter type"
|
|
76
|
-
},
|
|
77
|
-
"material-contract-program-mismatch": {
|
|
78
|
-
expected: "the program satisfies the material contract",
|
|
79
|
-
hint: "align the program entries with the root contract"
|
|
80
|
-
},
|
|
81
|
-
"shader-module-id-missing": {
|
|
82
|
-
expected: "each WGSL source declares a module ID",
|
|
83
|
-
hint: "add a compiler-native module ID declaration to the WGSL source"
|
|
84
|
-
},
|
|
85
|
-
"shader-module-id-duplicate": {
|
|
86
|
-
expected: "each module ID has one source provenance",
|
|
87
|
-
hint: "rename one module or remove the duplicate source"
|
|
88
|
-
},
|
|
89
|
-
"shader-module-not-found": {
|
|
90
|
-
expected: "every referenced module exists in the source catalog",
|
|
91
|
-
hint: "add the module to the source catalog or fix the reference"
|
|
92
|
-
},
|
|
93
|
-
"shader-module-namespace-reserved": {
|
|
94
|
-
expected: "user modules use a non-reserved namespace",
|
|
95
|
-
hint: "choose a module ID outside the reserved namespace"
|
|
96
|
-
},
|
|
97
|
-
"material-reflection-binding-mismatch": {
|
|
98
|
-
expected: "reflection matches the material contract bindings",
|
|
99
|
-
hint: "update the contract or WGSL binding and cook again"
|
|
100
|
-
},
|
|
101
|
-
"material-specialization-not-cooked": {
|
|
102
|
-
expected: "the requested specialization has a cooked artifact",
|
|
103
|
-
hint: "run the build or development cook path for this selection"
|
|
104
|
-
},
|
|
105
|
-
"material-specialization-stale-generation": {
|
|
106
|
-
expected: "all specialization dependencies share one generation",
|
|
107
|
-
hint: "retry after dependent assets and sources settle"
|
|
108
|
-
},
|
|
109
|
-
"gltf-material-uv-set-missing": {
|
|
110
|
-
expected: "each texture slot references an available primitive UV set",
|
|
111
|
-
hint: "add the requested UV set to the primitive and re-import it"
|
|
112
|
-
},
|
|
113
|
-
"material-derived-interface-mismatch": {
|
|
114
|
-
expected: "the generated material interface matches the derived schema interface",
|
|
115
|
-
hint: "repair the schema or WGSL producer and recook the material"
|
|
116
|
-
},
|
|
117
|
-
"material-texture-coordinate-invalid": {
|
|
118
|
-
expected: "every texture coordinate record is finite and complete",
|
|
119
|
-
hint: "repair the texture metadata or coordinates and recook the material"
|
|
120
|
-
},
|
|
121
|
-
"material-payload-bounds": {
|
|
122
|
-
expected: "every material payload write stays within the derived payload",
|
|
123
|
-
hint: "repair the derived payload owner before submitting the draw"
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
var MATERIAL_ERROR_EXPECTED = Object.fromEntries(
|
|
127
|
-
MATERIAL_ERROR_CODES.map((code) => [code, MATERIAL_ERROR_POLICY[code].expected])
|
|
128
|
-
);
|
|
129
|
-
var MATERIAL_ERROR_HINTS = Object.fromEntries(
|
|
130
|
-
MATERIAL_ERROR_CODES.map((code) => [code, MATERIAL_ERROR_POLICY[code].hint])
|
|
131
|
-
);
|
|
132
|
-
var NUMERIC_TYPES = /* @__PURE__ */ new Set([
|
|
133
|
-
"f32",
|
|
134
|
-
"i32",
|
|
135
|
-
"u32",
|
|
136
|
-
"vec2",
|
|
137
|
-
"vec3",
|
|
138
|
-
"vec4",
|
|
139
|
-
"color"
|
|
140
|
-
]);
|
|
141
|
-
var TEXTURE_VIEW_TYPES = /* @__PURE__ */ new Set([
|
|
142
|
-
"texture2d",
|
|
143
|
-
"texture_cube",
|
|
144
|
-
"texture_depth_2d",
|
|
145
|
-
"texture_cube_array"
|
|
146
|
-
]);
|
|
147
|
-
var SAMPLER_TYPES = /* @__PURE__ */ new Set([
|
|
148
|
-
"sampler",
|
|
149
|
-
"sampler_comparison"
|
|
150
|
-
]);
|
|
151
|
-
var ALL_TYPES = /* @__PURE__ */ new Set([
|
|
152
|
-
...NUMERIC_TYPES,
|
|
153
|
-
...TEXTURE_VIEW_TYPES,
|
|
154
|
-
...SAMPLER_TYPES,
|
|
155
|
-
"storage_buffer"
|
|
156
|
-
]);
|
|
157
|
-
var PACK_ERROR_HINTS = {
|
|
158
|
-
"pack-malformed-meta": "check guid is a valid RFC 4122 UUID; validate with: ajv validate -s schema/meta.schema.json -d <file>",
|
|
159
|
-
"pack-malformed-pack": "check all asset guid and refs[] fields are 36-char dash-form UUIDs; validate with pack.schema.json",
|
|
160
|
-
"pack-guid-malformed": "use AssetGuid.random() or a UUIDv7 generator; all GUID fields must be 36-char RFC 4122 dash-form",
|
|
161
|
-
"pack-orphan-meta": "remove the orphan .meta.json or add the missing source file next to it",
|
|
162
|
-
"pack-meta-missing": "run forgeax-engine-remote-asset scan --roots <dir> to list source files without .meta.json",
|
|
163
|
-
"pack-guid-collision": "run forgeax-engine-remote-asset verify to list all GUID collisions; each GUID must be globally unique",
|
|
164
|
-
"pack-cyclic-reference": "run forgeax-engine-remote-asset verify to print the cycle path; break the cycle by removing a refs[] entry",
|
|
165
|
-
"pack-subasset-index-out-of-range": "check subAssets[].sourceIndex does not exceed the actual sub-image count in the source file",
|
|
166
|
-
// === 1 new hint (feat-20260523-shader-template-instance-split M1-T02) ===
|
|
167
|
-
"payload-schema-mismatch": "material asset payload failed schema validation; check paramSchema entries all use valid types from MATERIAL_PARAM_TYPES and materialShader is a non-empty string",
|
|
168
|
-
// === 4 new hints (feat-20260608-scene-nesting-ecs-fication M1 / w8;
|
|
169
|
-
// plan-strategy D-8) ===
|
|
170
|
-
"pack-mount-localid-overlap": "check parent SceneAsset.mounts[].memberFirst windows do not overlap with each other or with entities[].localId; rebuild mount sidecar after the child SceneAsset reimport",
|
|
171
|
-
"pack-mount-count-mismatch": "mount.memberCount must equal the referenced child SceneAsset totalSlots (entities.length + sum(mounts[].memberCount) + mounts.length); rebuild mount sidecar via forgeax-engine-remote-asset verify <dir> after the child SceneAsset reimport",
|
|
172
|
-
"pack-mount-override-localid-out-of-range": "override.localId must be in [0, mount.memberCount); shrink the override or extend memberCount to match the child SceneAsset",
|
|
173
|
-
"pack-mount-override-unknown-field": "override.comp / override.field must match a defined component schema; check defineComponent registry or rebuild mount sidecar after the child SceneAsset reimport",
|
|
174
|
-
// === 2 new hints (feat-20260625-asset-meta-source-mount-prefix M1 / w1) ===
|
|
175
|
-
"pack-unknown-path": "the @name in source is not declared in package.json#forgeax.assets.paths; add it there or use a known name from the list in error.detail.knownNames",
|
|
176
|
-
"pack-malformed-path-ref": "source must be @<name>/<rest> where name is a key in package.json#forgeax.assets.paths; the resolved path must not escape the declared directory"
|
|
177
|
-
};
|
|
178
|
-
|
|
179
1
|
// src/assets/scene-decoder.ts
|
|
2
|
+
import {
|
|
3
|
+
err,
|
|
4
|
+
ok
|
|
5
|
+
} from "@forgeax/engine-types";
|
|
180
6
|
var sceneAssetKind = {
|
|
181
7
|
kind: "scene"
|
|
182
8
|
};
|
|
@@ -356,6 +182,7 @@ var SCENE_COLLECT_PROFILE = Object.freeze({
|
|
|
356
182
|
});
|
|
357
183
|
|
|
358
184
|
// src/instances/externalization.ts
|
|
185
|
+
import { err as err2, ok as ok2 } from "@forgeax/engine-types";
|
|
359
186
|
function sharedKind(type) {
|
|
360
187
|
if (type?.startsWith("shared<")) return "one";
|
|
361
188
|
if (type?.startsWith("array<shared<")) return "many";
|
|
@@ -433,10 +260,10 @@ function externalizeSceneAsset(scene, resolveSchema) {
|
|
|
433
260
|
};
|
|
434
261
|
});
|
|
435
262
|
for (const [arrayIndex, guid] of (scene.skinGuids ?? []).entries()) {
|
|
436
|
-
if (typeof guid !== "string") return
|
|
263
|
+
if (typeof guid !== "string") return err2({ field: "skinGuids", value: guid });
|
|
437
264
|
addRef(guid, { componentName: "<scene>", fieldName: "skinGuids", arrayIndex });
|
|
438
265
|
}
|
|
439
|
-
return
|
|
266
|
+
return ok2({
|
|
440
267
|
payload: {
|
|
441
268
|
entities,
|
|
442
269
|
...mounts === void 0 || mounts.length === 0 ? {} : { mounts },
|
|
@@ -453,6 +280,13 @@ import {
|
|
|
453
280
|
import { classifyEntityField, remapEntityFieldValue } from "@forgeax/engine-ecs/externalization";
|
|
454
281
|
import { componentSchema } from "@forgeax/engine-ecs/internal";
|
|
455
282
|
import { fillComponentDefaults, StaleEntityError } from "@forgeax/engine-ecs/projection";
|
|
283
|
+
import {
|
|
284
|
+
err as err3,
|
|
285
|
+
ok as ok3,
|
|
286
|
+
PACK_ERROR_HINTS,
|
|
287
|
+
toUnique,
|
|
288
|
+
unwrapHandle
|
|
289
|
+
} from "@forgeax/engine-types";
|
|
456
290
|
var entityIndex = (entity) => entity & 16777215;
|
|
457
291
|
var entityGeneration = (entity) => entity >>> 24 & 255;
|
|
458
292
|
var sceneWorldStates = /* @__PURE__ */ new WeakMap();
|
|
@@ -474,7 +308,7 @@ function worldInstantiateScene(world, handle, parent) {
|
|
|
474
308
|
const diagnostics = [];
|
|
475
309
|
const r = worldInstantiateSceneRec(world, handle, parent, stack, diagnostics);
|
|
476
310
|
if (!r.ok) return r;
|
|
477
|
-
return
|
|
311
|
+
return ok3({ root: r.value, diagnostics });
|
|
478
312
|
}
|
|
479
313
|
function worldInstantiateScenePayload(world, asset, parent) {
|
|
480
314
|
const handle = world.allocSharedRef("SceneAsset", asset);
|
|
@@ -498,7 +332,7 @@ function worldInstantiateSceneFlat(world, handle) {
|
|
|
498
332
|
stack.delete(handleKey);
|
|
499
333
|
}
|
|
500
334
|
if (!r.ok) return r;
|
|
501
|
-
return
|
|
335
|
+
return ok3({ ...r.value, diagnostics });
|
|
502
336
|
}
|
|
503
337
|
function worldInstantiateSceneRec(world, handle, parent, stack, diagnostics) {
|
|
504
338
|
const handleKey = unwrapHandle(handle);
|
|
@@ -511,7 +345,7 @@ function worldInstantiateSceneRec(world, handle, parent, stack, diagnostics) {
|
|
|
511
345
|
kind: "mount-asset",
|
|
512
346
|
cycle: cycleArr
|
|
513
347
|
};
|
|
514
|
-
return
|
|
348
|
+
return err3({
|
|
515
349
|
code: "pack-cyclic-reference",
|
|
516
350
|
expected: "acyclic SceneAsset mount graph",
|
|
517
351
|
hint: PACK_ERROR_HINTS["pack-cyclic-reference"],
|
|
@@ -531,14 +365,14 @@ function worldInstantiateSceneRec(world, handle, parent, stack, diagnostics) {
|
|
|
531
365
|
function worldResolveSceneAsset(world, handle) {
|
|
532
366
|
const r = world.sharedRefs.resolve(handle);
|
|
533
367
|
if (!r.ok) {
|
|
534
|
-
return
|
|
368
|
+
return err3(r.error);
|
|
535
369
|
}
|
|
536
|
-
return
|
|
370
|
+
return ok3(r.value);
|
|
537
371
|
}
|
|
538
372
|
function worldSpawnSceneMembers(world, handle, asset, stack, diagnostics) {
|
|
539
373
|
const sceneInstanceToken = world.components.resolve("SceneInstance");
|
|
540
374
|
if (sceneInstanceToken === void 0) {
|
|
541
|
-
return
|
|
375
|
+
return err3(new ComponentNotDefinedError("SceneInstance"));
|
|
542
376
|
}
|
|
543
377
|
const childOfToken = world.components.resolve("ChildOf");
|
|
544
378
|
const ownEntities = asset.entities;
|
|
@@ -583,7 +417,7 @@ function worldSpawnSceneMembers(world, handle, asset, stack, diagnostics) {
|
|
|
583
417
|
}
|
|
584
418
|
if (overlapLids.size > 0) {
|
|
585
419
|
const overlapping = Array.from(overlapLids).sort((a, b) => a - b);
|
|
586
|
-
return
|
|
420
|
+
return err3({
|
|
587
421
|
code: "pack-mount-localid-overlap",
|
|
588
422
|
expected: "each LocalEntityId claimed by exactly one entity or mount slot",
|
|
589
423
|
hint: PACK_ERROR_HINTS["pack-mount-localid-overlap"],
|
|
@@ -623,7 +457,7 @@ function worldSpawnSceneMembers(world, handle, asset, stack, diagnostics) {
|
|
|
623
457
|
const childMapping = childInstRes.value.mapping;
|
|
624
458
|
mountInstances.push({ mount, root: childRes.value, mapping: childMapping });
|
|
625
459
|
if (childMapping.length !== mount.memberCount) {
|
|
626
|
-
return
|
|
460
|
+
return err3({
|
|
627
461
|
code: "pack-mount-count-mismatch",
|
|
628
462
|
expected: "mount.memberCount === child SceneAsset totalSlots",
|
|
629
463
|
hint: PACK_ERROR_HINTS["pack-mount-count-mismatch"],
|
|
@@ -694,7 +528,7 @@ function worldSpawnSceneMembers(world, handle, asset, stack, diagnostics) {
|
|
|
694
528
|
}
|
|
695
529
|
}
|
|
696
530
|
}
|
|
697
|
-
return
|
|
531
|
+
return ok3({
|
|
698
532
|
mapping,
|
|
699
533
|
entityToLocalId,
|
|
700
534
|
rootEntities,
|
|
@@ -707,7 +541,7 @@ function worldSpawnSceneMembers(world, handle, asset, stack, diagnostics) {
|
|
|
707
541
|
function worldInstantiateSceneAsset(world, handle, asset, parent, stack, diagnostics) {
|
|
708
542
|
const sceneInstanceToken = world.components.resolve("SceneInstance");
|
|
709
543
|
if (sceneInstanceToken === void 0) {
|
|
710
|
-
return
|
|
544
|
+
return err3(new ComponentNotDefinedError("SceneInstance"));
|
|
711
545
|
}
|
|
712
546
|
const childOfToken = world.components.resolve("ChildOf");
|
|
713
547
|
const membersRes = worldSpawnSceneMembers(world, handle, asset, stack, diagnostics);
|
|
@@ -807,7 +641,7 @@ function worldInstantiateSceneAsset(world, handle, asset, parent, stack, diagnos
|
|
|
807
641
|
if (!r.ok) return r;
|
|
808
642
|
}
|
|
809
643
|
}
|
|
810
|
-
return
|
|
644
|
+
return ok3(rootEntity);
|
|
811
645
|
}
|
|
812
646
|
function worldInstantiateSceneAssetFlat(world, handle, asset, stack, diagnostics) {
|
|
813
647
|
const membersRes = worldSpawnSceneMembers(world, handle, asset, stack, diagnostics);
|
|
@@ -846,7 +680,7 @@ function worldInstantiateSceneAssetFlat(world, handle, asset, stack, diagnostics
|
|
|
846
680
|
}
|
|
847
681
|
}
|
|
848
682
|
}
|
|
849
|
-
return
|
|
683
|
+
return ok3({ roots: [...rootEntities, ...mountEntitiesNeedingRootParent], mountEntities });
|
|
850
684
|
}
|
|
851
685
|
function worldBuildSceneEntityComponentDatas(world, node, mapping, diagnostics) {
|
|
852
686
|
const out = [];
|
|
@@ -854,7 +688,7 @@ function worldBuildSceneEntityComponentDatas(world, node, mapping, diagnostics)
|
|
|
854
688
|
for (const compName of Object.keys(node.components)) {
|
|
855
689
|
const token = world.components.resolve(compName);
|
|
856
690
|
if (token === void 0) {
|
|
857
|
-
return
|
|
691
|
+
return err3(new ComponentNotDefinedError(compName));
|
|
858
692
|
}
|
|
859
693
|
const raw = node.components[compName] ?? {};
|
|
860
694
|
const schema = componentSchema(token);
|
|
@@ -881,11 +715,11 @@ function worldBuildSceneEntityComponentDatas(world, node, mapping, diagnostics)
|
|
|
881
715
|
const filled = fillComponentDefaults(token, remappedRaw);
|
|
882
716
|
out.push({ component: token, data: filled });
|
|
883
717
|
}
|
|
884
|
-
return
|
|
718
|
+
return ok3(out);
|
|
885
719
|
}
|
|
886
720
|
function worldApplyMountOverride(world, member, ov) {
|
|
887
721
|
const ovToken = world.components.resolve(ov.comp);
|
|
888
|
-
if (ovToken === void 0) return
|
|
722
|
+
if (ovToken === void 0) return ok3(void 0);
|
|
889
723
|
if (ov.field !== void 0) {
|
|
890
724
|
return world.set(member, ovToken, { [ov.field]: ov.value });
|
|
891
725
|
}
|
|
@@ -899,7 +733,7 @@ function worldApplyMountOverride(world, member, ov) {
|
|
|
899
733
|
}
|
|
900
734
|
function worldValidateMountOverrides(world, mount) {
|
|
901
735
|
const overrides = mount.overrides;
|
|
902
|
-
if (overrides === void 0) return
|
|
736
|
+
if (overrides === void 0) return ok3(void 0);
|
|
903
737
|
const memberFirst = mount.memberFirst;
|
|
904
738
|
const memberCount = mount.memberCount;
|
|
905
739
|
const memberLast = memberFirst + memberCount;
|
|
@@ -907,7 +741,7 @@ function worldValidateMountOverrides(world, mount) {
|
|
|
907
741
|
for (const ov of overrides) {
|
|
908
742
|
const ovLid = ov.localId;
|
|
909
743
|
if (ovLid < memberFirst || ovLid >= memberLast) {
|
|
910
|
-
return
|
|
744
|
+
return err3({
|
|
911
745
|
code: "pack-mount-override-localid-out-of-range",
|
|
912
746
|
expected: `override.localId in [${memberFirst}, ${memberLast})`,
|
|
913
747
|
hint: PACK_ERROR_HINTS["pack-mount-override-localid-out-of-range"],
|
|
@@ -924,7 +758,7 @@ function worldValidateMountOverrides(world, mount) {
|
|
|
924
758
|
if (ovToken !== void 0) {
|
|
925
759
|
const schema = componentSchema(ovToken);
|
|
926
760
|
if (!(ov.field in schema)) {
|
|
927
|
-
return
|
|
761
|
+
return err3({
|
|
928
762
|
code: "pack-mount-override-unknown-field",
|
|
929
763
|
expected: `override.field defined on component '${ov.comp}'`,
|
|
930
764
|
hint: PACK_ERROR_HINTS["pack-mount-override-unknown-field"],
|
|
@@ -939,13 +773,13 @@ function worldValidateMountOverrides(world, mount) {
|
|
|
939
773
|
}
|
|
940
774
|
} else {
|
|
941
775
|
if (ovToken === void 0) {
|
|
942
|
-
return
|
|
776
|
+
return err3(new ComponentNotDefinedError(ov.comp));
|
|
943
777
|
}
|
|
944
778
|
const schema = componentSchema(ovToken);
|
|
945
779
|
const valueMap = ov.value ?? {};
|
|
946
780
|
for (const key of Object.keys(valueMap)) {
|
|
947
781
|
if (!(key in schema)) {
|
|
948
|
-
return
|
|
782
|
+
return err3({
|
|
949
783
|
code: "pack-mount-override-unknown-field",
|
|
950
784
|
expected: `override.value keys defined on component '${ov.comp}'`,
|
|
951
785
|
hint: PACK_ERROR_HINTS["pack-mount-override-unknown-field"],
|
|
@@ -960,7 +794,7 @@ function worldValidateMountOverrides(world, mount) {
|
|
|
960
794
|
}
|
|
961
795
|
}
|
|
962
796
|
}
|
|
963
|
-
return
|
|
797
|
+
return ok3(void 0);
|
|
964
798
|
}
|
|
965
799
|
function worldSpawnMountEntity(world, mount, mapping, diagnostics) {
|
|
966
800
|
const fakeNode = {
|
|
@@ -979,7 +813,7 @@ function worldSpawnMountEntity(world, mount, mapping, diagnostics) {
|
|
|
979
813
|
if (cdRes.value.length === 0) {
|
|
980
814
|
const childOfToken = world.components.resolve("ChildOf");
|
|
981
815
|
if (childOfToken === void 0) {
|
|
982
|
-
return
|
|
816
|
+
return err3(new ComponentNotDefinedError("ChildOf"));
|
|
983
817
|
}
|
|
984
818
|
cdRes.value.push({
|
|
985
819
|
component: childOfToken,
|
|
@@ -991,7 +825,7 @@ function worldSpawnMountEntity(world, mount, mapping, diagnostics) {
|
|
|
991
825
|
function worldResolveMountSource(world, source, parentHandle) {
|
|
992
826
|
const resolver = worldGetSceneAssetResolver(world);
|
|
993
827
|
if (resolver === null) {
|
|
994
|
-
return
|
|
828
|
+
return err3({
|
|
995
829
|
code: "stale-entity",
|
|
996
830
|
expected: "wired SceneAssetResolver (auto-wired by engine.assets.instantiate)",
|
|
997
831
|
hint: "engine.assets.instantiate sugar wires this for you; call worldSetSceneAssetResolver before nested scene expansion.",
|
|
@@ -1000,9 +834,9 @@ function worldResolveMountSource(world, source, parentHandle) {
|
|
|
1000
834
|
}
|
|
1001
835
|
const r = resolver(source, parentHandle);
|
|
1002
836
|
if (!r.ok) {
|
|
1003
|
-
return
|
|
837
|
+
return err3(r.error);
|
|
1004
838
|
}
|
|
1005
|
-
return
|
|
839
|
+
return ok3(r.value);
|
|
1006
840
|
}
|
|
1007
841
|
function worldMountOverridesToStateMap(src) {
|
|
1008
842
|
const out = /* @__PURE__ */ new Map();
|
|
@@ -1025,7 +859,7 @@ function worldSetUniqueRefPayload(world, handle, payload) {
|
|
|
1025
859
|
function worldResolveSceneInstanceStatePayload(world, root) {
|
|
1026
860
|
const sceneInstanceToken = world.components.resolve("SceneInstance");
|
|
1027
861
|
if (sceneInstanceToken === void 0) {
|
|
1028
|
-
return
|
|
862
|
+
return err3(new ComponentNotDefinedError("SceneInstance"));
|
|
1029
863
|
}
|
|
1030
864
|
const r = world.get(root, sceneInstanceToken);
|
|
1031
865
|
if (!r.ok) return r;
|
|
@@ -1033,7 +867,7 @@ function worldResolveSceneInstanceStatePayload(world, root) {
|
|
|
1033
867
|
const stateRefHandle = toUnique(stateRefRaw);
|
|
1034
868
|
const payload = sceneWorldState(world).statePayloads.get(Number(stateRefHandle));
|
|
1035
869
|
if (payload === void 0) {
|
|
1036
|
-
return
|
|
870
|
+
return err3(
|
|
1037
871
|
new StaleEntityError(root, entityIndex(root), entityGeneration(root), {
|
|
1038
872
|
operation: "resolveSceneInstanceState",
|
|
1039
873
|
component: "SceneInstance",
|
|
@@ -1042,7 +876,7 @@ function worldResolveSceneInstanceStatePayload(world, root) {
|
|
|
1042
876
|
})
|
|
1043
877
|
);
|
|
1044
878
|
}
|
|
1045
|
-
return
|
|
879
|
+
return ok3(payload);
|
|
1046
880
|
}
|
|
1047
881
|
function worldGetSceneInstanceState(world, root) {
|
|
1048
882
|
return worldResolveSceneInstanceStatePayload(world, root);
|
|
@@ -1052,7 +886,7 @@ function worldDespawnScene(world, root, opts) {
|
|
|
1052
886
|
if (!dRes.ok) return dRes;
|
|
1053
887
|
const drop = world.despawn(root);
|
|
1054
888
|
if (!drop.ok) return drop;
|
|
1055
|
-
return
|
|
889
|
+
return ok3(dRes.value + 1);
|
|
1056
890
|
}
|
|
1057
891
|
function worldDespawnDescendants(world, root, opts) {
|
|
1058
892
|
let detached = null;
|
|
@@ -1129,7 +963,7 @@ function worldDespawnDescendants(world, root, opts) {
|
|
|
1129
963
|
}
|
|
1130
964
|
count += 1;
|
|
1131
965
|
}
|
|
1132
|
-
return
|
|
966
|
+
return ok3(count);
|
|
1133
967
|
}
|
|
1134
968
|
function worldSetSceneOverride(world, root, member, component, field, value) {
|
|
1135
969
|
const stateRes = worldResolveSceneInstanceStatePayload(world, root);
|
|
@@ -1137,7 +971,7 @@ function worldSetSceneOverride(world, root, member, component, field, value) {
|
|
|
1137
971
|
const state = stateRes.value;
|
|
1138
972
|
const lid = state.entityToLocalId.get(member);
|
|
1139
973
|
if (lid === void 0) {
|
|
1140
|
-
return
|
|
974
|
+
return err3(
|
|
1141
975
|
new StaleEntityError(
|
|
1142
976
|
member,
|
|
1143
977
|
entityIndex(member),
|
|
@@ -1156,7 +990,7 @@ function worldSetSceneOverride(world, root, member, component, field, value) {
|
|
|
1156
990
|
const expectJsType = primitiveJsType(schemaType);
|
|
1157
991
|
const actualJsType = typeof value;
|
|
1158
992
|
if (expectJsType !== actualJsType) {
|
|
1159
|
-
return
|
|
993
|
+
return err3({
|
|
1160
994
|
code: "scene-override-type-mismatch",
|
|
1161
995
|
expected: `value typeof === ${expectJsType}`,
|
|
1162
996
|
hint: `setSceneOverride(${component.name}.${field}) expected ${expectJsType}, got ${actualJsType}; coerce or pick a different override path.`,
|
|
@@ -1182,14 +1016,14 @@ function worldSetSceneOverride(world, root, member, component, field, value) {
|
|
|
1182
1016
|
field,
|
|
1183
1017
|
value
|
|
1184
1018
|
});
|
|
1185
|
-
return
|
|
1019
|
+
return ok3(void 0);
|
|
1186
1020
|
}
|
|
1187
1021
|
function worldRemoveSceneOverride(world, root, member, component, field) {
|
|
1188
1022
|
const stateRes = worldResolveSceneInstanceStatePayload(world, root);
|
|
1189
1023
|
if (!stateRes.ok) return stateRes;
|
|
1190
1024
|
const state = stateRes.value;
|
|
1191
1025
|
const lid = state.entityToLocalId.get(member);
|
|
1192
|
-
if (lid === void 0) return
|
|
1026
|
+
if (lid === void 0) return ok3(void 0);
|
|
1193
1027
|
const fieldMap = state.overrides.get(lid);
|
|
1194
1028
|
if (fieldMap !== void 0) {
|
|
1195
1029
|
fieldMap.delete(`${component.name}:${field}`);
|
|
@@ -1205,34 +1039,34 @@ function worldRemoveSceneOverride(world, root, member, component, field) {
|
|
|
1205
1039
|
const r = world.set(member, component, { [field]: layer1[field] });
|
|
1206
1040
|
if (!r.ok) return r;
|
|
1207
1041
|
}
|
|
1208
|
-
return
|
|
1042
|
+
return ok3(void 0);
|
|
1209
1043
|
}
|
|
1210
1044
|
function worldDetachSceneMember(world, root, member) {
|
|
1211
1045
|
const sceneInstanceToken = world.components.resolve("SceneInstance");
|
|
1212
1046
|
if (sceneInstanceToken === void 0) {
|
|
1213
|
-
return
|
|
1047
|
+
return err3(new ComponentNotDefinedError("SceneInstance"));
|
|
1214
1048
|
}
|
|
1215
1049
|
const stateRes = worldResolveSceneInstanceStatePayload(world, root);
|
|
1216
1050
|
if (!stateRes.ok) return stateRes;
|
|
1217
1051
|
const state = stateRes.value;
|
|
1218
1052
|
const lid = state.entityToLocalId.get(member);
|
|
1219
|
-
if (lid === void 0) return
|
|
1053
|
+
if (lid === void 0) return ok3(void 0);
|
|
1220
1054
|
state.detachedLocalIds.add(lid);
|
|
1221
|
-
return
|
|
1055
|
+
return ok3(void 0);
|
|
1222
1056
|
}
|
|
1223
1057
|
function worldReattachSceneMember(world, root, member) {
|
|
1224
1058
|
const stateRes = worldResolveSceneInstanceStatePayload(world, root);
|
|
1225
1059
|
if (!stateRes.ok) return stateRes;
|
|
1226
1060
|
const state = stateRes.value;
|
|
1227
1061
|
const lid = state.entityToLocalId.get(member);
|
|
1228
|
-
if (lid === void 0) return
|
|
1062
|
+
if (lid === void 0) return ok3(void 0);
|
|
1229
1063
|
state.detachedLocalIds.delete(lid);
|
|
1230
|
-
return
|
|
1064
|
+
return ok3(void 0);
|
|
1231
1065
|
}
|
|
1232
1066
|
function worldGetSceneAssetForInstance(world, root) {
|
|
1233
1067
|
const stateRes = worldResolveSceneInstanceStatePayload(world, root);
|
|
1234
1068
|
if (!stateRes.ok) return stateRes;
|
|
1235
|
-
return
|
|
1069
|
+
return ok3(stateRes.value.source);
|
|
1236
1070
|
}
|
|
1237
1071
|
function sceneTopoSort(nodes) {
|
|
1238
1072
|
const n = nodes.length;
|
|
@@ -1303,6 +1137,7 @@ import {
|
|
|
1303
1137
|
setDerivedComponent
|
|
1304
1138
|
} from "@forgeax/engine-ecs/projection";
|
|
1305
1139
|
import { mat4 } from "@forgeax/engine-math";
|
|
1140
|
+
import { err as err4, ok as ok4 } from "@forgeax/engine-types";
|
|
1306
1141
|
|
|
1307
1142
|
// src/systems/hierarchy-projection.ts
|
|
1308
1143
|
import { Entity } from "@forgeax/engine-ecs";
|
|
@@ -1450,8 +1285,8 @@ function descendants(childrenOf, roots) {
|
|
|
1450
1285
|
}
|
|
1451
1286
|
function hierarchyError(hierarchy) {
|
|
1452
1287
|
const first = hierarchy.diagnostics[0];
|
|
1453
|
-
if (first === void 0) return
|
|
1454
|
-
return
|
|
1288
|
+
if (first === void 0) return ok4(void 0);
|
|
1289
|
+
return err4(
|
|
1455
1290
|
new SceneError({
|
|
1456
1291
|
code: first.code,
|
|
1457
1292
|
expected: first.expected,
|
|
@@ -1481,17 +1316,17 @@ function buildCache(world, projection) {
|
|
|
1481
1316
|
entities,
|
|
1482
1317
|
locals,
|
|
1483
1318
|
derived: /* @__PURE__ */ new Map(),
|
|
1484
|
-
result:
|
|
1319
|
+
result: ok4(void 0)
|
|
1485
1320
|
};
|
|
1486
1321
|
}
|
|
1487
1322
|
function deriveEntity(world, entity, cache, affected, visiting, published) {
|
|
1488
|
-
if (!affected.has(entity) || cache.derived.has(entity)) return
|
|
1489
|
-
if (visiting.has(entity)) return
|
|
1323
|
+
if (!affected.has(entity) || cache.derived.has(entity)) return ok4(void 0);
|
|
1324
|
+
if (visiting.has(entity)) return ok4(void 0);
|
|
1490
1325
|
visiting.add(entity);
|
|
1491
1326
|
const local = cache.locals.get(entity);
|
|
1492
1327
|
if (local === void 0) {
|
|
1493
1328
|
visiting.delete(entity);
|
|
1494
|
-
return
|
|
1329
|
+
return ok4(void 0);
|
|
1495
1330
|
}
|
|
1496
1331
|
const parent = cache.parentOf.get(entity);
|
|
1497
1332
|
if (parent !== void 0 && cache.entities.has(parent)) {
|
|
@@ -1507,7 +1342,7 @@ function deriveEntity(world, entity, cache, affected, visiting, published) {
|
|
|
1507
1342
|
const write = setDerivedComponent(world, entity, Transform, { world: resolved });
|
|
1508
1343
|
if (!write.ok) {
|
|
1509
1344
|
visiting.delete(entity);
|
|
1510
|
-
return
|
|
1345
|
+
return err4(
|
|
1511
1346
|
new SceneError({
|
|
1512
1347
|
code: "hierarchy-broken",
|
|
1513
1348
|
expected: "the derived Transform.world write to succeed",
|
|
@@ -1519,7 +1354,7 @@ function deriveEntity(world, entity, cache, affected, visiting, published) {
|
|
|
1519
1354
|
cache.derived.set(entity, resolved);
|
|
1520
1355
|
published.add(entity);
|
|
1521
1356
|
visiting.delete(entity);
|
|
1522
|
-
return
|
|
1357
|
+
return ok4(void 0);
|
|
1523
1358
|
}
|
|
1524
1359
|
function drainPublishedChanges(cache, published) {
|
|
1525
1360
|
const drained = cache.projection.poll();
|