@forgeax/engine-runtime 0.1.28 → 0.1.29

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 (113) hide show
  1. package/README.md +98 -0
  2. package/dist/collect-scene-asset.d.ts.map +1 -1
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.mjs +480 -15
  6. package/dist/index.mjs.map +1 -1
  7. package/dist/scene-utils/mount-override-fold.d.ts +3 -1
  8. package/dist/scene-utils/mount-override-fold.d.ts.map +1 -1
  9. package/package.json +37 -32
  10. package/src/__tests__/animation-graph-collect-roundtrip.test.ts +4 -2
  11. package/src/__tests__/asset-registry-aabb.cases.unit.test.ts +5 -4
  12. package/src/__tests__/asset-registry-guid-reverse.test.ts +22 -27
  13. package/src/__tests__/asset-registry-mounts.test.ts +174 -734
  14. package/src/__tests__/asset-registry-scene.cases.unit.test.ts +9 -18
  15. package/src/__tests__/asset-registry.recursive.spec.ts +23 -29
  16. package/src/__tests__/camera-ortho.cases.unit.test.ts +12 -3
  17. package/src/__tests__/collect-scene-asset.test.ts +96 -113
  18. package/src/__tests__/collect-scene-mount-collapse.test.ts +64 -66
  19. package/src/__tests__/collect-transient-children-absent.test.ts +11 -17
  20. package/src/__tests__/collect-transient-roundtrip.test.ts +12 -13
  21. package/src/__tests__/collect-transient-skip.test.ts +20 -27
  22. package/src/__tests__/components.test-d.ts +17 -1
  23. package/src/__tests__/components.unit.test.ts +75 -27
  24. package/src/__tests__/composite-skybox-cross-world.browser.test.ts +4 -2
  25. package/src/__tests__/dawn/instances-per-instance-pbr.dawn.test.ts +8 -4
  26. package/src/__tests__/dawn/instances-shadow.dawn.test.ts +4 -1
  27. package/src/__tests__/dawn/instances-uniform-fallback.dawn.test.ts +66 -92
  28. package/src/__tests__/dawn/material-cooked-fixture.dawn.test.ts +200 -4
  29. package/src/__tests__/errors.unit.test.ts +13 -0
  30. package/src/__tests__/feature-depth-material.dawn.test.ts +23 -0
  31. package/src/__tests__/feature-depth-material.fixture.ts +473 -0
  32. package/src/__tests__/fullscreen-post-process-pass.dawn.test.ts +14 -14
  33. package/src/__tests__/geometry.unit.test.ts +42 -43
  34. package/src/__tests__/gpu-resource-release.cases.unit.test.ts +16 -9
  35. package/src/__tests__/handle-migration.test.ts +0 -1
  36. package/src/__tests__/instances-renderer-lifecycle.integration.test.ts +20 -14
  37. package/src/__tests__/instances.test-d.ts +13 -52
  38. package/src/__tests__/instantiate-mount-deferred-wiring.test.ts +42 -80
  39. package/src/__tests__/lazy-catalog.cases.unit.test.ts +17 -3
  40. package/src/__tests__/loader-registry.cases.unit.test.ts +4 -4
  41. package/src/__tests__/material-publication.browser.test.ts +29 -0
  42. package/src/__tests__/material-publication.commands.ts +23 -0
  43. package/src/__tests__/material-publication.dawn.test.ts +24 -0
  44. package/src/__tests__/material-publication.fixture.ts +349 -0
  45. package/src/__tests__/material-publication.server.ts +109 -0
  46. package/src/__tests__/parse-scene-payload-refs.cases.unit.test.ts +73 -96
  47. package/src/__tests__/pbr-pipeline.unit.test.ts +25 -11
  48. package/src/__tests__/point-light-shadow.browser.test.ts +8 -2
  49. package/src/__tests__/point-light-shadow.unit.test.ts +37 -8
  50. package/src/__tests__/record-all-topology.cases.unit.test.ts +52 -0
  51. package/src/__tests__/record-draw-branch.cases.unit.test.ts +1 -0
  52. package/src/__tests__/record-worldid-isolation.test.ts +47 -28
  53. package/src/__tests__/render-error-exhaustive.test-d.ts +24 -0
  54. package/src/__tests__/render-system-extract-dispatch-ordering.test.ts +15 -4
  55. package/src/__tests__/render-system-extract.test.ts +61 -0
  56. package/src/__tests__/render-system-extract.unit.test.ts +21 -7
  57. package/src/__tests__/render-system-fold-bucket.unit.test.ts +33 -1
  58. package/src/__tests__/render-system-fold-material.unit.test.ts +32 -6
  59. package/src/__tests__/render-system-fold-modegate.unit.test.ts +26 -4
  60. package/src/__tests__/render-system-fold.dawn.test.ts +4 -1
  61. package/src/__tests__/render-system-mega.test.ts +50 -62
  62. package/src/__tests__/renderer-device-loss-provider-feasibility.dawn.test.ts +0 -1
  63. package/src/__tests__/renderer-device-loss-recovery.dawn.test.ts +0 -3
  64. package/src/__tests__/renderer-draw-world.cases.unit.test.ts +16 -513
  65. package/src/__tests__/resolve-scene-guids.cases.unit.test.ts +48 -43
  66. package/src/__tests__/rhi-null-command-flow.unit.test.ts +9 -7
  67. package/src/__tests__/roots-to-scene-asset.test.ts +27 -28
  68. package/src/__tests__/roundtrip-primitive.test.ts +24 -23
  69. package/src/__tests__/scene-equirect-roundtrip.test.ts +5 -16
  70. package/src/__tests__/scene-instantiate-cycle-runtime.test.ts +13 -29
  71. package/src/__tests__/scene-mount-fixed-point.test.ts +104 -227
  72. package/src/__tests__/scene-mount-roundtrip.test.ts +95 -961
  73. package/src/__tests__/scene-mount-wrapper-roundtrip.test.ts +36 -182
  74. package/src/__tests__/scene-sugar-instantiate.test.ts +20 -15
  75. package/src/__tests__/serialize-mounts-roundtrip.test.ts +108 -492
  76. package/src/__tests__/serialize-scene-asset.test.ts +36 -50
  77. package/src/__tests__/shadow-caster-empty-schema.test.ts +3 -1
  78. package/src/__tests__/shadow-fields-observable.dawn.test.ts +34 -19
  79. package/src/__tests__/shadow-mesh-ssbo-order.test.ts +5 -12
  80. package/src/__tests__/skin-extract-getarrayview-count.unit.test.ts +6 -4
  81. package/src/__tests__/skin-m2-extract-happy.cases.unit.test.ts +50 -2
  82. package/src/__tests__/skin-m2-extract-joint-error.cases.unit.test.ts +50 -2
  83. package/src/__tests__/skin-m2-extract-null-assets.cases.unit.test.ts +50 -2
  84. package/src/__tests__/skin-m2-extract-skeleton-error.cases.unit.test.ts +50 -2
  85. package/src/__tests__/skin-palette-extract.cases.unit.test.ts +2 -0
  86. package/src/__tests__/skinned-shadow-mixed.dawn.test.ts +93 -48
  87. package/src/__tests__/skylight-pipeline-layout.cases.unit.test.ts +6 -2
  88. package/src/__tests__/sparse-tag-scene-roundtrip.test.ts +1 -1
  89. package/src/__tests__/sprite-lit-bgl-byte-identical.test.ts +11 -3
  90. package/src/__tests__/template-game-default-api-contract.test.ts +21 -21
  91. package/src/__tests__/tonemap-hdr-target.cases.unit.test.ts +8 -5
  92. package/src/__tests__/tonemap-pipeline-split.cases.unit.test.ts +3 -0
  93. package/src/__tests__/transient-fields-collect.test.ts +4 -4
  94. package/src/__tests__/transient-runtime-behavior.test.ts +9 -9
  95. package/src/__tests__/vfx-depth-material.dawn.test.ts +42 -0
  96. package/src/__tests__/vfx-mesh-lighting.browser.test.ts +16 -0
  97. package/src/__tests__/vfx-mesh-lighting.commands.ts +14 -0
  98. package/src/__tests__/vfx-mesh-lighting.dawn.test.ts +16 -0
  99. package/src/__tests__/vfx-mesh-lighting.fixture.ts +883 -0
  100. package/src/__tests__/wave1-rendering-materials.browser.test.ts +617 -0
  101. package/src/__tests__/wave1-rendering-p0.browser.test.ts +751 -0
  102. package/src/__tests__/wave1-rendering-recovery.browser.test.ts +666 -0
  103. package/src/__tests__/wave1-shadow-diagnostic.browser.test.ts +582 -0
  104. package/src/__tests__/world-scene-despawn.test.ts +8 -8
  105. package/src/__tests__/world-scene-instantiate.test.ts +23 -29
  106. package/src/__tests__/world-scene-nested.test.ts +90 -163
  107. package/src/__tests__/world-scene-override.test.ts +17 -16
  108. package/src/__tests__/zero-compression-zero-load.integration.test.ts +1 -0
  109. package/src/collect-scene-asset.ts +637 -19
  110. package/src/components/__tests__/sprite-animation.test-d.ts +2 -2
  111. package/src/index.ts +1 -0
  112. package/src/scene-utils/mount-override-fold.ts +5 -14
  113. package/src/__tests__/node-shims.d.ts +0 -31
@@ -1,9 +1,11 @@
1
1
  import { type EntityHandle, type World } from '@forgeax/engine-ecs';
2
- import type { Handle, LocalEntityId, MountOverride } from '@forgeax/engine-types';
2
+ import type { MountOverride } from '@forgeax/engine-scene';
3
+ import type { Handle, LocalEntityId } from '@forgeax/engine-types';
3
4
  /** Minimal structural view of a SceneInstanceState the fold reads (D-4 boundary:
4
5
  * `world.getSceneInstanceState(root).value` is structurally assignable). */
5
6
  export interface FoldSceneInstanceState {
6
7
  readonly source: Handle<'SceneAsset', 'shared'>;
8
+ readonly keyByLocalId: Map<number, string>;
7
9
  readonly entityToLocalId: Map<EntityHandle, LocalEntityId>;
8
10
  }
9
11
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"mount-override-fold.d.ts","sourceRoot":"","sources":["../../src/scene-utils/mount-override-fold.ts"],"names":[],"mappings":"AA2CA,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,KAAK,EACX,MAAM,qBAAqB,CAAC;AAG7B,OAAO,KAAK,EACV,MAAM,EACN,aAAa,EACb,aAAa,EAGd,MAAM,uBAAuB,CAAC;AAE/B;4EAC4E;AAC5E,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IAChD,QAAQ,CAAC,eAAe,EAAE,GAAG,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;CAC5D;AA4ED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,sBAAsB,GAAG,aAAa,EAAE,CAmE/F"}
1
+ {"version":3,"file":"mount-override-fold.d.ts","sourceRoot":"","sources":["../../src/scene-utils/mount-override-fold.ts"],"names":[],"mappings":"AA2CA,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,KAAK,EACX,MAAM,qBAAqB,CAAC;AAG7B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAc,MAAM,uBAAuB,CAAC;AAE/E;4EAC4E;AAC5E,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IAChD,QAAQ,CAAC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,QAAQ,CAAC,eAAe,EAAE,GAAG,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;CAC5D;AA4ED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,sBAAsB,GAAG,aAAa,EAAE,CA8D/F"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgeax/engine-runtime",
3
- "version": "0.1.28",
3
+ "version": "0.1.29",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -26,39 +26,44 @@
26
26
  "LICENSE"
27
27
  ],
28
28
  "dependencies": {
29
- "@forgeax/engine-animation": "0.1.28",
30
- "@forgeax/engine-assets-runtime": "0.1.28",
31
- "@forgeax/engine-audio-webaudio": "0.1.28",
32
- "@forgeax/engine-codec": "0.1.28",
33
- "@forgeax/engine-debug-draw": "0.1.28",
34
- "@forgeax/engine-ecs": "0.1.28",
35
- "@forgeax/engine-font": "0.1.28",
36
- "@forgeax/engine-geometry": "0.1.28",
37
- "@forgeax/engine-graphics-extras": "0.1.28",
38
- "@forgeax/engine-image": "0.1.28",
39
- "@forgeax/engine-input": "0.1.28",
40
- "@forgeax/engine-math": "0.1.28",
41
- "@forgeax/engine-pack": "0.1.28",
42
- "@forgeax/engine-profiler": "0.1.28",
43
- "@forgeax/engine-render": "0.1.28",
44
- "@forgeax/engine-render-graph": "0.1.28",
45
- "@forgeax/engine-rhi": "0.1.28",
46
- "@forgeax/engine-rhi-null": "0.1.28",
47
- "@forgeax/engine-rhi-webgpu": "0.1.28",
48
- "@forgeax/engine-rhi-wgpu": "0.1.28",
49
- "@forgeax/engine-scene": "0.1.28",
50
- "@forgeax/engine-shader": "0.1.28",
51
- "@forgeax/engine-skinning": "0.1.28",
52
- "@forgeax/engine-types": "0.1.28",
53
- "@forgeax/engine-vfx": "0.1.28"
29
+ "@forgeax/engine-animation": "0.1.29",
30
+ "@forgeax/engine-assets-runtime": "0.1.29",
31
+ "@forgeax/engine-audio-webaudio": "0.1.29",
32
+ "@forgeax/engine-codec": "0.1.29",
33
+ "@forgeax/engine-debug-draw": "0.1.29",
34
+ "@forgeax/engine-ecs": "0.1.29",
35
+ "@forgeax/engine-font": "0.1.29",
36
+ "@forgeax/engine-geometry": "0.1.29",
37
+ "@forgeax/engine-graphics-extras": "0.1.29",
38
+ "@forgeax/engine-image": "0.1.29",
39
+ "@forgeax/engine-input": "0.1.29",
40
+ "@forgeax/engine-math": "0.1.29",
41
+ "@forgeax/engine-pack": "0.1.29",
42
+ "@forgeax/engine-profiler": "0.1.29",
43
+ "@forgeax/engine-render": "0.1.29",
44
+ "@forgeax/engine-render-graph": "0.1.29",
45
+ "@forgeax/engine-rhi": "0.1.29",
46
+ "@forgeax/engine-rhi-null": "0.1.29",
47
+ "@forgeax/engine-rhi-webgpu": "0.1.29",
48
+ "@forgeax/engine-rhi-wgpu": "0.1.29",
49
+ "@forgeax/engine-scene": "0.1.29",
50
+ "@forgeax/engine-shader": "0.1.29",
51
+ "@forgeax/engine-skinning": "0.1.29",
52
+ "@forgeax/engine-types": "0.1.29",
53
+ "@forgeax/engine-vfx": "0.1.29"
54
54
  },
55
55
  "devDependencies": {
56
- "@forgeax/engine-import": "0.1.28",
57
- "@forgeax/engine-naga": "0.1.28",
58
- "@forgeax/engine-physics": "0.1.28",
59
- "@forgeax/engine-physics-rapier3d": "0.1.28",
60
- "@forgeax/engine-state": "0.1.28",
61
- "@forgeax/engine-vite-plugin-shader": "0.1.28",
56
+ "@forgeax/engine-import": "0.1.29",
57
+ "@forgeax/engine-naga": "0.1.29",
58
+ "@forgeax/engine-physics": "0.1.29",
59
+ "@forgeax/engine-physics-rapier3d": "0.1.29",
60
+ "@forgeax/engine-rhi-debug": "0.1.29",
61
+ "@forgeax/engine-shader-compiler": "0.1.29",
62
+ "@forgeax/engine-state": "0.1.29",
63
+ "@forgeax/engine-vfx-compiler": "0.1.29",
64
+ "@forgeax/engine-vfx-render": "0.1.29",
65
+ "@forgeax/engine-vite-plugin-pack": "0.1.29",
66
+ "@forgeax/engine-vite-plugin-shader": "0.1.29",
62
67
  "@types/node": "^20.14.0"
63
68
  },
64
69
  "forgeax": {
@@ -74,8 +74,10 @@ function registerGraph(
74
74
  return { handle, guid: AssetGuid.format(parsed.value) };
75
75
  }
76
76
 
77
- function apOf(scene: { entities: readonly unknown[] }): Record<string, unknown> | undefined {
78
- for (const e of scene.entities) {
77
+ function apOf(scene: {
78
+ entities: Readonly<Record<string, unknown>>;
79
+ }): Record<string, unknown> | undefined {
80
+ for (const e of Object.values(scene.entities)) {
79
81
  const comps = (e as { components: Record<string, Record<string, unknown>> }).components;
80
82
  if (comps.AnimationPlayer !== undefined) return comps.AnimationPlayer;
81
83
  }
@@ -75,6 +75,7 @@ import {
75
75
  import { audioLoader } from '@forgeax/engine-audio-webaudio';
76
76
  import { defineComponent, World } from '@forgeax/engine-ecs';
77
77
  import {
78
+ buildMeshAttributeMapForUvSets,
78
79
  createBoxGeometry,
79
80
  createPlaneGeometry,
80
81
  meshFromInterleaved,
@@ -462,7 +463,7 @@ type __MergedKeep =
462
463
  kind: 'mesh',
463
464
  vertices,
464
465
  indices: new Uint16Array([0, 1, 2, 2, 3, 0]),
465
- attributes: { position: positions },
466
+ attributes: { ...buildMeshAttributeMapForUvSets(1), position: positions },
466
467
  aabb: new Float32Array(6),
467
468
  materialSlots: [{ slotName: 'Default' }],
468
469
  submeshes: [
@@ -502,7 +503,7 @@ type __MergedKeep =
502
503
  kind: 'mesh',
503
504
  vertices,
504
505
  indices: new Uint16Array([0, 1, 2]),
505
- attributes: { position: positionBuf },
506
+ attributes: { ...buildMeshAttributeMapForUvSets(1), position: positionBuf },
506
507
  aabb: new Float32Array(6),
507
508
  materialSlots: [{ slotName: 'Default' }],
508
509
  submeshes: [
@@ -600,7 +601,7 @@ type __MergedKeep =
600
601
  kind: 'mesh',
601
602
  vertices,
602
603
  indices: new Uint16Array([0]),
603
- attributes: { position: positions },
604
+ attributes: { ...buildMeshAttributeMapForUvSets(1), position: positions },
604
605
  aabb: new Float32Array(6),
605
606
  materialSlots: [{ slotName: 'Default' }],
606
607
  submeshes: [
@@ -638,7 +639,7 @@ type __MergedKeep =
638
639
  kind: 'mesh',
639
640
  vertices,
640
641
  indices: new Uint16Array([0, 1]),
641
- attributes: { position: positions },
642
+ attributes: { ...buildMeshAttributeMapForUvSets(1), position: positions },
642
643
  aabb: new Float32Array(6),
643
644
  materialSlots: [{ slotName: 'Default' }],
644
645
  submeshes: [
@@ -80,7 +80,7 @@ function firstLiveMaterialHandle(world: World, root: Handle<string, 'shared'>):
80
80
  function makeScene(entities?: SceneAsset['entities']): SceneAsset {
81
81
  return {
82
82
  kind: 'scene',
83
- entities: entities ?? [{ localId: 0 as never, components: { Transform: {} } }],
83
+ entities: entities ?? { 'entity-0': { components: { Transform: {} } } },
84
84
  };
85
85
  }
86
86
 
@@ -167,15 +167,14 @@ describe('m1-t2 — uncatalogued scene MISS path', () => {
167
167
  const meshHandle = world.allocSharedRef('MeshAsset', mesh);
168
168
  const asset: SceneAsset = {
169
169
  kind: 'scene',
170
- entities: [
171
- {
172
- localId: 0 as never,
170
+ entities: {
171
+ 'entity-0': {
173
172
  components: {
174
173
  MeshFilter: { assetHandle: meshHandle as never },
175
174
  Transform: {},
176
175
  },
177
176
  },
178
- ],
177
+ },
179
178
  };
180
179
 
181
180
  // Allocate shared ref for the scene and instantiate.
@@ -213,15 +212,14 @@ describe('builtin reverse lookup ownership', () => {
213
212
  prepareWorld(world);
214
213
  const scene: SceneAsset = {
215
214
  kind: 'scene',
216
- entities: [
217
- {
218
- localId: 0 as never,
215
+ entities: {
216
+ 'entity-0': {
219
217
  components: {
220
218
  Transform: {},
221
219
  MeshFilter: { assetHandle: HANDLE_CUBE as never },
222
220
  },
223
221
  },
224
- ],
222
+ },
225
223
  };
226
224
  const sceneHandle = world.allocSharedRef<'SceneAsset', SceneAsset>('SceneAsset', scene);
227
225
  const instantiated = SceneOwner.worldInstantiateScene(world, sceneHandle);
@@ -231,7 +229,7 @@ describe('builtin reverse lookup ownership', () => {
231
229
  const collected = rootsToSceneAsset(registry, world, [instantiated.value.root]);
232
230
  expect(collected.ok).toBe(true);
233
231
  if (!collected.ok) return;
234
- const meshEntity = collected.value.entities.find(
232
+ const meshEntity = Object.values(collected.value.entities).find(
235
233
  (entity) => entity.components.MeshFilter !== undefined,
236
234
  );
237
235
  expect(meshEntity?.components.MeshFilter?.assetHandle).toBe(GUID_A);
@@ -316,16 +314,15 @@ describe('w14 M4 probe — owned payload identity anchor', () => {
316
314
  const newHandle = world.allocSharedRef<'MeshAsset', MeshAsset>('MeshAsset', repeated.value);
317
315
  const scene: SceneAsset = {
318
316
  kind: 'scene',
319
- entities: [
320
- {
321
- localId: 0 as never,
317
+ entities: {
318
+ 'entity-0': {
322
319
  components: {
323
320
  Transform: {},
324
321
  MeshFilter: { assetHandle: newHandle as never },
325
322
  MeshRenderer: { materials: [] },
326
323
  },
327
324
  },
328
- ],
325
+ },
329
326
  };
330
327
  const sceneHandle = world.allocSharedRef<'SceneAsset', SceneAsset>('SceneAsset', scene);
331
328
  const instantiated = SceneOwner.worldInstantiateScene(world, sceneHandle);
@@ -334,7 +331,7 @@ describe('w14 M4 probe — owned payload identity anchor', () => {
334
331
  const collected = rootsToSceneAsset(reg, world, [instantiated.value.root]);
335
332
  expect(collected.ok).toBe(true);
336
333
  if (!collected.ok) return;
337
- expect(collected.value.entities).toContainEqual(
334
+ expect(Object.values(collected.value.entities)).toContainEqual(
338
335
  expect.objectContaining({
339
336
  components: expect.objectContaining({
340
337
  MeshFilter: expect.objectContaining({ assetHandle: MESH_GUID }),
@@ -357,25 +354,24 @@ describe('w14 M4 probe — owned payload identity anchor', () => {
357
354
  // GUID string (post-parse intermediate shape), catalogued with refs edges.
358
355
  const child: SceneAsset = {
359
356
  kind: 'scene',
360
- entities: [
361
- {
362
- localId: 0 as never,
357
+ entities: {
358
+ 'entity-0': {
363
359
  components: {
364
360
  Transform: {},
365
361
  MeshFilter: { assetHandle: MESH_GUID as never },
366
362
  MeshRenderer: { materials: [MAT_GUID] as never },
367
363
  },
368
364
  },
369
- ],
365
+ },
370
366
  };
371
367
  reg.catalog(parseGuid(CHILD_GUID), child as Asset, [{ guid: MESH_GUID }, { guid: MAT_GUID }]);
372
368
 
373
369
  const parent: SceneAsset = {
374
370
  kind: 'scene',
375
- entities: [{ localId: 0 as never, components: { Transform: {} } }],
376
- mounts: [
377
- { localId: 1 as never, source: CHILD_GUID, memberFirst: 2 as never, memberCount: 1 },
378
- ],
371
+ entities: {
372
+ 'entity-0': { components: { Transform: {} } },
373
+ child: { components: {}, instance: { source: CHILD_GUID } },
374
+ },
379
375
  };
380
376
  reg.catalog(parseGuid(PARENT_GUID), parent as Asset);
381
377
 
@@ -583,16 +579,15 @@ describe('w16 M4 — AC-08 reverse-lookup hit across kinds', () => {
583
579
  );
584
580
  const scene: SceneAsset = {
585
581
  kind: 'scene',
586
- entities: [
587
- {
588
- localId: 0 as never,
582
+ entities: {
583
+ 'entity-0': {
589
584
  components: {
590
585
  Transform: {},
591
586
  MeshFilter: { assetHandle: meshHandle as never },
592
587
  MeshRenderer: { materials: [matHandle] as never },
593
588
  },
594
589
  },
595
- ],
590
+ },
596
591
  };
597
592
  const sceneHandle = world.allocSharedRef<'SceneAsset', SceneAsset>('SceneAsset', scene);
598
593
  const instRes = SceneOwner.worldInstantiateScene(world, sceneHandle);