@forgeax/engine-render 0.1.4 → 0.1.7
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 +268 -640
- package/dist/.tsbuildinfo +1 -1
- package/dist/__tests__/device-scope-lifecycle.unit.test.d.ts +2 -0
- package/dist/__tests__/device-scope-lifecycle.unit.test.d.ts.map +1 -0
- package/dist/__tests__/device-scope-stale-matrix.unit.test.d.ts +2 -0
- package/dist/__tests__/device-scope-stale-matrix.unit.test.d.ts.map +1 -0
- package/dist/__tests__/fullscreen-feature-plan.unit.test.d.ts +2 -0
- package/dist/__tests__/fullscreen-feature-plan.unit.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-indirect-raster-evidence.d.ts.map +1 -1
- package/dist/__tests__/gpu-driven-view-gpu-evidence.d.ts +6 -0
- package/dist/__tests__/gpu-driven-view-gpu-evidence.d.ts.map +1 -1
- package/dist/{gpu-driven/view-reference.d.ts → __tests__/gpu-driven-view-reference.d.ts} +4 -4
- package/dist/__tests__/gpu-driven-view-reference.d.ts.map +1 -0
- package/dist/__tests__/gpu-scene-render-graph-gpu.d.ts.map +1 -1
- package/dist/__tests__/ibl/face-uniforms.unit.test.d.ts +2 -0
- package/dist/__tests__/ibl/face-uniforms.unit.test.d.ts.map +1 -0
- package/dist/__tests__/morph-feature-plan.unit.test.d.ts +2 -0
- package/dist/__tests__/morph-feature-plan.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-plan.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-plan.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-plan.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-plan.unit.test.d.ts.map +1 -0
- package/dist/__tests__/ssao-config.unit.test.d.ts +2 -0
- package/dist/__tests__/ssao-config.unit.test.d.ts.map +1 -0
- package/dist/__tests__/standard-clustered-pipeline.unit.test.d.ts +2 -0
- package/dist/__tests__/standard-clustered-pipeline.unit.test.d.ts.map +1 -0
- package/dist/__tests__/standard-descriptors.test-d.d.ts +2 -0
- package/dist/__tests__/standard-descriptors.test-d.d.ts.map +1 -0
- package/dist/__tests__/standard-pipeline.dawn.test.d.ts +2 -0
- package/dist/__tests__/standard-pipeline.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/standard-pipeline.integration.test.d.ts +2 -0
- package/dist/__tests__/standard-pipeline.integration.test.d.ts.map +1 -0
- package/dist/__tests__/standard-profile-oracle.unit.test.d.ts +2 -0
- package/dist/__tests__/standard-profile-oracle.unit.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-resource-short-circuit.unit.test.d.ts +2 -0
- package/dist/__tests__/visibility-resource-short-circuit.unit.test.d.ts.map +1 -0
- package/dist/{renderer/backend-selection.d.ts → assembly/backend-contract.d.ts} +15 -4
- package/dist/assembly/backend-contract.d.ts.map +1 -0
- package/dist/assembly/factory.d.ts +214 -0
- package/dist/assembly/factory.d.ts.map +1 -0
- package/dist/assembly/host-contract.d.ts +84 -0
- package/dist/assembly/host-contract.d.ts.map +1 -0
- package/dist/{renderer → assembly}/material/assembly.d.ts +0 -1
- package/dist/{renderer → assembly}/material/assembly.d.ts.map +1 -1
- package/dist/assembly/material/pipeline-projection.d.ts +30 -0
- package/dist/assembly/material/pipeline-projection.d.ts.map +1 -0
- package/dist/authoring.d.ts +11 -11
- package/dist/authoring.d.ts.map +1 -1
- package/dist/authoring.mjs +25 -3
- package/dist/authoring.mjs.map +1 -1
- package/dist/chunk-CQXZC5XI.mjs +182 -0
- package/dist/chunk-CQXZC5XI.mjs.map +1 -0
- package/dist/chunk-HCOGPHKS.mjs +93 -0
- package/dist/chunk-HCOGPHKS.mjs.map +1 -0
- package/dist/chunk-YEJIUW7D.mjs +1152 -0
- package/dist/chunk-YEJIUW7D.mjs.map +1 -0
- package/dist/components/__tests__/points-lines-admission.unit.test.d.ts +2 -0
- package/dist/components/__tests__/points-lines-admission.unit.test.d.ts.map +1 -0
- package/dist/components/__tests__/points-lines-schema.unit.test.d.ts +2 -0
- package/dist/components/__tests__/points-lines-schema.unit.test.d.ts.map +1 -0
- package/dist/components/__tests__/schema-contract.unit.test.d.ts +2 -0
- package/dist/components/__tests__/schema-contract.unit.test.d.ts.map +1 -0
- package/dist/components/glyph-text.d.ts +1 -1
- package/dist/components/glyph-text.d.ts.map +1 -1
- package/dist/components/index.d.ts +4 -2
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/instances.d.ts +1 -1
- package/dist/components/instances.d.ts.map +1 -1
- package/dist/components/light-helpers.d.ts +1 -1
- package/dist/components/light-helpers.d.ts.map +1 -1
- package/dist/components/lines.d.ts +5 -0
- package/dist/components/lines.d.ts.map +1 -0
- package/dist/components/mesh-filter.d.ts +7 -7
- package/dist/components/mesh-filter.d.ts.map +1 -1
- package/dist/components/points.d.ts +15 -0
- package/dist/components/points.d.ts.map +1 -0
- package/dist/components/scene-instance.d.ts +11 -11
- package/dist/components/skybox-background.d.ts +56 -0
- package/dist/components/skybox-background.d.ts.map +1 -0
- package/dist/components/skylight.d.ts +55 -0
- package/dist/components/skylight.d.ts.map +1 -0
- package/dist/components/sprite-animation.d.ts +2 -3
- package/dist/components/sprite-animation.d.ts.map +1 -1
- package/dist/components/sprite-instances.d.ts +1 -1
- package/dist/components/sprite-playback-mode.d.ts +6 -1
- package/dist/components/sprite-playback-mode.d.ts.map +1 -1
- package/dist/components/sprite-region-override.d.ts +2 -3
- package/dist/components/sprite-region-override.d.ts.map +1 -1
- package/dist/components/tile-layer.d.ts +5 -0
- package/dist/components/tile-layer.d.ts.map +1 -1
- package/dist/construct-renderer.d.ts +18 -1
- package/dist/construct-renderer.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +27463 -4
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/debug-draw-glue.d.ts +2 -53
- package/dist/debug-draw-glue.d.ts.map +1 -1
- package/dist/device/device-scope.d.ts +83 -0
- package/dist/device/device-scope.d.ts.map +1 -0
- package/dist/{gpu-resource-store.d.ts → device/gpu-residency.d.ts} +91 -48
- package/dist/device/gpu-residency.d.ts.map +1 -0
- package/dist/device/resource-types.d.ts +8 -0
- package/dist/device/resource-types.d.ts.map +1 -0
- package/dist/engine-metrics.d.ts +2 -2
- package/dist/engine-metrics.d.ts.map +1 -1
- package/dist/errors/recover.d.ts +28 -1
- package/dist/errors/recover.d.ts.map +1 -1
- package/dist/errors/render.d.ts +320 -248
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/features/fullscreen.d.ts +19 -0
- package/dist/features/fullscreen.d.ts.map +1 -0
- package/dist/features/host.d.ts +32 -26
- package/dist/features/host.d.ts.map +1 -1
- package/dist/features/morph/morph-feature.d.ts +39 -5
- package/dist/features/morph/morph-feature.d.ts.map +1 -1
- package/dist/features/plan.d.ts +182 -0
- package/dist/features/plan.d.ts.map +1 -0
- package/dist/features/prepared-gpu-work.d.ts +21 -17
- package/dist/features/prepared-gpu-work.d.ts.map +1 -1
- package/dist/features/prepared-graphics-store.d.ts +2 -1
- package/dist/features/prepared-graphics-store.d.ts.map +1 -1
- package/dist/features/prepared-graphics.d.ts +11 -21
- package/dist/features/prepared-graphics.d.ts.map +1 -1
- package/dist/features/render-graph-compute.d.ts +2 -2
- package/dist/features/render-graph-compute.d.ts.map +1 -1
- package/dist/features/render-graph-contribution.d.ts +4 -7
- package/dist/features/render-graph-contribution.d.ts.map +1 -1
- package/dist/features/render-graph-raster.d.ts +7 -3
- package/dist/features/render-graph-raster.d.ts.map +1 -1
- package/dist/features/render-graph-resources.d.ts +6 -6
- package/dist/features/render-graph-resources.d.ts.map +1 -1
- package/dist/features/targets.d.ts +5 -5
- package/dist/features/targets.d.ts.map +1 -1
- package/dist/features/types.d.ts +11 -190
- package/dist/features/types.d.ts.map +1 -1
- package/dist/features/vocabulary.d.ts +14 -0
- package/dist/features/vocabulary.d.ts.map +1 -0
- package/dist/fullscreen-post-process-pass.d.ts +4 -25
- package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
- package/dist/glyph-text-layout-system.d.ts +3 -2
- package/dist/glyph-text-layout-system.d.ts.map +1 -1
- package/dist/gpu-driven/batch-topology.d.ts +6 -75
- package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
- package/dist/gpu-driven/production-raster.d.ts +13 -112
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/gpu-driven/view-gpu.d.ts +10 -66
- package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
- package/dist/gpu-resource.d.ts +3 -3
- package/dist/gpu-scene-schema.d.ts +1 -94
- package/dist/gpu-scene-schema.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts +7 -33
- package/dist/gpu-scene.d.ts.map +1 -1
- package/dist/hdrp-buffers.d.ts +3 -53
- package/dist/hdrp-buffers.d.ts.map +1 -1
- package/dist/ibl/IblPipelineCache.d.ts +74 -180
- package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
- package/dist/ibl/skylight-bind-group.d.ts +1 -1
- package/dist/index.d.ts +17 -43
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +167 -3
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +72 -0
- package/dist/inspection-types.d.ts.map +1 -0
- package/dist/instance-buffer-cache.d.ts +1 -4
- package/dist/instance-buffer-cache.d.ts.map +1 -1
- package/dist/internal.d.ts +1 -73
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.mjs +1 -43
- package/dist/internal.mjs.map +1 -1
- package/dist/lifecycle.d.ts +36 -2
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/materials.d.ts +0 -3
- package/dist/materials.d.ts.map +1 -1
- package/dist/mesh-material-bindings.d.ts +0 -1
- package/dist/mesh-material-bindings.d.ts.map +1 -1
- package/dist/pbr-pipeline.d.ts +77 -29
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-forward-lane.d.ts +5 -0
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -0
- package/dist/pipeline/standard-pipeline.d.ts +31 -0
- package/dist/pipeline/standard-pipeline.d.ts.map +1 -0
- package/dist/pipeline/standard-profile.d.ts +40 -0
- package/dist/pipeline/standard-profile.d.ts.map +1 -0
- package/dist/pipeline-builder.d.ts +3 -3
- package/dist/pipeline-builder.d.ts.map +1 -1
- package/dist/pipeline-spec-types.d.ts +24 -0
- package/dist/pipeline-spec-types.d.ts.map +1 -0
- package/dist/pipeline-spec.d.ts +16 -155
- package/dist/pipeline-spec.d.ts.map +1 -1
- package/dist/plugin.d.ts +1 -14
- package/dist/plugin.d.ts.map +1 -1
- package/dist/points-lines/__tests__/bounds.unit.test.d.ts +2 -0
- package/dist/points-lines/__tests__/bounds.unit.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/cache-recovery.unit.test.d.ts +2 -0
- package/dist/points-lines/__tests__/cache-recovery.unit.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/inspection-lanes.integration.test.d.ts +2 -0
- package/dist/points-lines/__tests__/inspection-lanes.integration.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/inspection.unit.test.d.ts +2 -0
- package/dist/points-lines/__tests__/inspection.unit.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/lane-structural.integration.test.d.ts +2 -0
- package/dist/points-lines/__tests__/lane-structural.integration.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/points-lines.bench.d.ts +2 -0
- package/dist/points-lines/__tests__/points-lines.bench.d.ts.map +1 -0
- package/dist/points-lines/__tests__/raster-lane.integration.test.d.ts +2 -0
- package/dist/points-lines/__tests__/raster-lane.integration.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/snapshot.unit.test.d.ts +2 -0
- package/dist/points-lines/__tests__/snapshot.unit.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/view-ubo.unit.test.d.ts +2 -0
- package/dist/points-lines/__tests__/view-ubo.unit.test.d.ts.map +1 -0
- package/dist/points-lines/admission.d.ts +36 -0
- package/dist/points-lines/admission.d.ts.map +1 -0
- package/dist/points-lines/bounds.d.ts +8 -0
- package/dist/points-lines/bounds.d.ts.map +1 -0
- package/dist/points-lines/expansion-cache.d.ts +28 -0
- package/dist/points-lines/expansion-cache.d.ts.map +1 -0
- package/dist/points-lines/inspection.d.ts +53 -0
- package/dist/points-lines/inspection.d.ts.map +1 -0
- package/dist/points-lines/prepare.d.ts +67 -0
- package/dist/points-lines/prepare.d.ts.map +1 -0
- package/dist/points-lines/record.d.ts +60 -0
- package/dist/points-lines/record.d.ts.map +1 -0
- package/dist/points-lines/snapshot.d.ts +49 -0
- package/dist/points-lines/snapshot.d.ts.map +1 -0
- package/dist/post-process-errors.d.ts +18 -18
- package/dist/post-process-errors.d.ts.map +1 -1
- package/dist/prepare/prepared-graphics-resolver.d.ts +2 -5
- package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
- package/dist/record/__tests__/typed-frame-graph-plan.unit.test.d.ts +2 -0
- package/dist/record/__tests__/typed-frame-graph-plan.unit.test.d.ts.map +1 -0
- package/dist/record/frame-lighting.d.ts +7 -73
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +44 -44
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame-targets.d.ts +5 -38
- package/dist/record/frame-targets.d.ts.map +1 -1
- package/dist/record/frame.d.ts +64 -52
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/helpers.d.ts +3 -2
- package/dist/record/helpers.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +12 -4
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +90 -59
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass-sprite-draws.d.ts +28 -3
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts +1 -1
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/mesh-ssbo.d.ts +276 -3
- package/dist/record/mesh-ssbo.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +252 -0
- package/dist/record/render-context.d.ts.map +1 -0
- package/dist/record/shadow-pass.d.ts +15 -88
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/skybox-post-pass.d.ts +1 -1
- package/dist/record/skybox-post-pass.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts +29 -7
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts +9 -3
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/render-contract.d.ts +424 -0
- package/dist/render-contract.d.ts.map +1 -0
- package/dist/render-data.d.ts.map +1 -1
- package/dist/render-graph-primitives.d.ts +14 -362
- package/dist/render-graph-primitives.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +25 -64
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +110 -338
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system.d.ts +24 -713
- package/dist/render-system.d.ts.map +1 -1
- package/dist/scene/render-scene-types.d.ts +61 -0
- package/dist/scene/render-scene-types.d.ts.map +1 -0
- package/dist/scene/render-scene.d.ts +112 -0
- package/dist/scene/render-scene.d.ts.map +1 -0
- package/dist/scene-instances/post-spawn-resolve-joints.d.ts +2 -5
- package/dist/scene-instances/post-spawn-resolve-joints.d.ts.map +1 -1
- package/dist/ssao-buffers.d.ts +22 -3
- package/dist/ssao-buffers.d.ts.map +1 -1
- package/dist/systems/skin-palette-allocator.d.ts +2 -4
- package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
- package/dist/systems/skin-palette-types.d.ts +14 -0
- package/dist/systems/skin-palette-types.d.ts.map +1 -0
- package/dist/systems/transparent-sort-config.d.ts +23 -2
- package/dist/systems/transparent-sort-config.d.ts.map +1 -1
- package/dist/tilemap-chunk-extract-system.d.ts +4 -3
- package/dist/tilemap-chunk-extract-system.d.ts.map +1 -1
- package/dist/typed-render-graph-primitives.d.ts +2 -4
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/typed-shadow-passes.d.ts +3 -3
- package/dist/typed-shadow-passes.d.ts.map +1 -1
- package/package.json +23 -23
- package/src/__tests__/authoring-path.unit.test.ts +9 -0
- package/src/__tests__/backend-selection-rhi-capture.test-d.ts +1 -1
- package/src/__tests__/callback-inference.test-d.ts +6 -3
- package/src/__tests__/cluster-grid-default-surface.unit.test.ts +7 -4
- package/src/__tests__/construct-renderer-identity.unit.test.ts +15 -2
- package/src/__tests__/device-scope-lifecycle.unit.test.ts +151 -0
- package/src/__tests__/device-scope-stale-matrix.unit.test.ts +42 -0
- package/src/__tests__/direct-extract-consumer-contract.test-d.ts +8 -19
- package/src/__tests__/direct-light-snapshot.unit.test.ts +3 -13
- package/src/__tests__/factory-contract.integration.test.ts +158 -209
- package/src/__tests__/fallback-row-stride-surface.unit.test.ts +1 -4
- package/src/__tests__/frame-observation.contract.test.ts +17 -8
- package/src/__tests__/fullscreen-feature-plan.unit.test.ts +32 -0
- package/src/__tests__/glyph-text-layout-recovery.unit.test.ts +6 -11
- package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +21 -18
- package/src/__tests__/gpu-driven-production.integration.test.ts +32 -205
- package/src/__tests__/gpu-driven-scaling.unit.test.ts +4 -7
- package/src/__tests__/gpu-driven-view-gpu-evidence.ts +87 -8
- package/src/__tests__/gpu-driven-view-graph.integration.test.ts +170 -8
- package/src/{gpu-driven/view-reference.ts → __tests__/gpu-driven-view-reference.ts} +4 -3
- package/src/__tests__/gpu-driven-view.browser.test.ts +12 -1
- package/src/__tests__/gpu-driven-view.dawn.test.ts +12 -1
- package/src/__tests__/gpu-driven-view.unit.test.ts +11 -267
- package/src/__tests__/gpu-resource-store-stride.unit.test.ts +3 -3
- package/src/__tests__/gpu-scene-render-graph-gpu.ts +2 -3
- package/src/__tests__/gpu-scene.dawn.test.ts +2 -6
- package/src/__tests__/gpu-scene.unit.test.ts +10 -24
- package/src/__tests__/ibl/face-uniforms.unit.test.ts +46 -0
- package/src/__tests__/infinite-grid-no-vertex-probe.unit.test.ts +34 -66
- package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +14 -5
- package/src/__tests__/light-buffer-layout.unit.test.ts +4 -49
- package/src/__tests__/material-cooked-projection.unit.test.ts +31 -58
- package/src/__tests__/material-snapshot-mutation.integration.test.ts +10 -15
- package/src/__tests__/material-static-dynamic-route.unit.test.ts +31 -50
- package/src/__tests__/material-stride-surface.unit.test.ts +2 -2
- package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +7 -8
- package/src/__tests__/morph-culling-reentry.dawn.test.ts +29 -38
- package/src/__tests__/morph-feature-gpu-work.integration.test.ts +45 -43
- package/src/__tests__/morph-feature-plan.unit.test.ts +53 -0
- package/src/__tests__/morph-visual-evidence.integration.test.ts +47 -33
- package/src/__tests__/nineslice-handle-surface.unit.test.ts +11 -6
- package/src/__tests__/post-process-error-policy-owner.unit.test.ts +6 -13
- package/src/__tests__/prepared-graphics-capability.unit.test.ts +6 -81
- package/src/__tests__/prepared-graphics-generation.unit.test.ts +3 -17
- package/src/__tests__/prepared-graphics-lifecycle.unit.test.ts +6 -74
- package/src/__tests__/prepared-graphics-resolver.unit.test.ts +1 -3
- package/src/__tests__/prepared-graphics-snapshot.unit.test.ts +2 -2
- package/src/__tests__/profiler-default-off.test.ts +1 -1
- package/src/__tests__/profiler-phase-catalog.test.ts +2 -2
- package/src/__tests__/profiler-phase-integration.test.ts +5 -13
- package/src/__tests__/profiler-phase-token.test.ts +3 -8
- package/src/__tests__/public-surface.test-d.ts +65 -3
- package/src/__tests__/recover-error-policy-owner.unit.test.ts +1 -21
- package/src/__tests__/render-error-code-owner.test-d.ts +24 -23
- package/src/__tests__/render-error-detail-ssot.test-d.ts +0 -95
- package/src/__tests__/render-error-exhaustive.test-d.ts +27 -1
- package/src/__tests__/render-feature-assembly.test-d.ts +8 -16
- package/src/__tests__/render-feature-context.test-d.ts +16 -40
- package/src/__tests__/render-feature-contract.test-d.ts +9 -18
- package/src/__tests__/render-feature-diagnostics.unit.test.ts +6 -8
- package/src/__tests__/render-feature-docs.unit.test.ts +8 -7
- package/src/__tests__/render-feature-gpu-work.integration.test.ts +14 -75
- package/src/__tests__/render-feature-plan.test-d.ts +161 -0
- package/src/__tests__/render-feature-plan.unit.test.ts +170 -0
- package/src/__tests__/render-feature-prepared-diagnostics.unit.test.ts +8 -19
- package/src/__tests__/render-feature-prepared-errors.test-d.ts +3 -6
- package/src/__tests__/render-feature-prepared-graphics-docs.unit.test.ts +10 -71
- package/src/__tests__/render-feature-prepared-graphics-isolation.unit.test.ts +11 -61
- package/src/__tests__/render-feature-prepared-graphics-negative.test-d.ts +20 -43
- package/src/__tests__/render-feature-prepared-graphics.test-d.ts +56 -78
- package/src/__tests__/render-feature-public-surface.test-d.ts +6 -24
- package/src/__tests__/render-feature-retry.unit.test.ts +7 -48
- package/src/__tests__/render-feature-scheduling.unit.test.ts +15 -27
- package/src/__tests__/render-feature-stage-failed-policy-owner.unit.test.ts +0 -9
- package/src/__tests__/render-feature-stage-fault-recovery.unit.test.ts +19 -109
- package/src/__tests__/render-feature-visibility-context.test-d.ts +1 -6
- package/src/__tests__/render-feature-visibility-context.unit.test.ts +1 -2
- package/src/__tests__/render-feature-zero-work.unit.test.ts +14 -20
- package/src/__tests__/render-scene-projection.unit.test.ts +73 -111
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +82 -95
- package/src/__tests__/renderer-lifecycle.integration.test.ts +49 -1
- package/src/__tests__/shader-stage-surface.unit.test.ts +14 -9
- package/src/__tests__/ssao-config.unit.test.ts +36 -0
- package/src/__tests__/ssao-kernel-surface.unit.test.ts +4 -5
- package/src/__tests__/standard-clustered-pipeline.unit.test.ts +28 -0
- package/src/__tests__/standard-descriptors.test-d.ts +22 -0
- package/src/__tests__/standard-pipeline.dawn.test.ts +61 -0
- package/src/__tests__/standard-pipeline.integration.test.ts +124 -0
- package/src/__tests__/standard-profile-oracle.unit.test.ts +62 -0
- package/src/__tests__/surface-configuration.unit.test.ts +1 -2
- package/src/__tests__/texture-usage-surface.unit.test.ts +3 -6
- package/src/__tests__/typed-pipeline-topology.unit.test.ts +40 -206
- package/src/__tests__/urp-pipeline-targets.unit.test.ts +1 -11
- package/src/__tests__/urp-pipeline.unit.test.ts +2 -2
- package/src/__tests__/vertex-color-pipeline.unit.test.ts +10 -2
- package/src/__tests__/vertex-layout-consumer.unit.test.ts +1 -1
- package/src/__tests__/visibility-diagnostics.integration.test.ts +7 -11
- package/src/__tests__/visibility-extract.integration.test.ts +20 -11
- package/src/__tests__/visibility-extract.perf.test.ts +66 -32
- package/src/__tests__/visibility-feature-dedup.integration.test.ts +2 -4
- package/src/__tests__/visibility-hidden-report.unit.test.ts +1 -2
- package/src/__tests__/visibility-instances.integration.test.ts +7 -11
- package/src/__tests__/visibility-multi-world.integration.test.ts +38 -6
- package/src/__tests__/visibility-producer-matrix.integration.test.ts +18 -41
- package/src/__tests__/visibility-public-surface.test-d.ts +10 -9
- package/src/__tests__/visibility-resolver.unit.test.ts +2 -1
- package/src/__tests__/visibility-resource-short-circuit.unit.test.ts +80 -0
- package/src/__tests__/visibility-snapshot-contract.unit.test.ts +2 -1
- package/src/__tests__/vocabulary.unit.test.ts +1 -1
- package/src/assembly/backend-contract.ts +57 -0
- package/src/{renderer/renderer-factory.ts → assembly/factory.ts} +1741 -2699
- package/src/assembly/host-contract.ts +101 -0
- package/src/{renderer → assembly}/material/assembly.ts +2 -7
- package/src/assembly/material/pipeline-projection.ts +63 -0
- package/src/authoring.ts +15 -22
- package/src/components/__tests__/points-lines-admission.unit.test.ts +219 -0
- package/src/components/__tests__/points-lines-schema.unit.test.ts +56 -0
- package/src/components/__tests__/schema-contract.unit.test.ts +10 -0
- package/src/components/glyph-text.ts +3 -2
- package/src/components/index.ts +14 -9
- package/src/components/instances.ts +4 -5
- package/src/components/light-helpers.ts +1 -1
- package/src/components/lines.ts +18 -0
- package/src/components/mesh-filter.ts +11 -10
- package/src/components/points.ts +40 -0
- package/src/components/post-process-params.ts +3 -3
- package/src/components/scene-instance.ts +12 -12
- package/src/components/skybox-background.ts +103 -0
- package/src/components/{environment.ts → skylight.ts} +2 -110
- package/src/components/sprite-animation.ts +3 -4
- package/src/components/sprite-instances.ts +2 -2
- package/src/components/sprite-playback-mode.ts +7 -1
- package/src/components/sprite-region-override.ts +2 -3
- package/src/components/tile-layer.ts +8 -2
- package/src/construct-renderer.ts +67 -4
- package/src/debug-draw-glue.ts +8 -129
- package/src/device/device-scope.ts +306 -0
- package/src/{gpu-resource-store.ts → device/gpu-residency.ts} +540 -639
- package/src/device/resource-types.ts +20 -0
- package/src/engine-metrics.ts +12 -19
- package/src/errors/recover.ts +45 -3
- package/src/errors/render.ts +469 -429
- package/src/features/fullscreen.ts +46 -0
- package/src/features/host.ts +575 -309
- package/src/features/morph/morph-feature.ts +195 -105
- package/src/features/plan.ts +447 -0
- package/src/features/prepared-gpu-work.ts +72 -15
- package/src/features/prepared-graphics-store.ts +20 -6
- package/src/features/prepared-graphics.ts +12 -71
- package/src/features/render-graph-compute.ts +14 -5
- package/src/features/render-graph-contribution.ts +43 -63
- package/src/features/render-graph-raster.ts +32 -8
- package/src/features/render-graph-resources.ts +25 -23
- package/src/features/targets.ts +8 -21
- package/src/features/types.ts +39 -227
- package/src/features/vocabulary.ts +24 -0
- package/src/fullscreen-post-process-pass.ts +14 -57
- package/src/glyph-text-layout-system.ts +70 -96
- package/src/gpu-driven/batch-topology.ts +24 -202
- package/src/gpu-driven/production-raster.ts +99 -1109
- package/src/gpu-driven/view-gpu.ts +46 -192
- package/src/gpu-resource.ts +4 -4
- package/src/gpu-scene-schema.ts +11 -99
- package/src/gpu-scene.ts +231 -364
- package/src/hdrp-buffers.ts +12 -221
- package/src/ibl/IblPipelineCache.ts +471 -711
- package/src/ibl/skylight-bind-group.ts +4 -4
- package/src/index.ts +75 -217
- package/src/inspection-types.ts +80 -0
- package/src/instance-buffer-cache.ts +1 -29
- package/src/internal.ts +6 -85
- package/src/lifecycle.ts +64 -19
- package/src/materials.ts +7 -29
- package/src/mesh-material-bindings.ts +0 -1
- package/src/pbr-pipeline.ts +441 -53
- package/src/{urp-pipeline.ts → pipeline/standard-forward-lane.ts} +38 -149
- package/src/{hdrp-pipeline.ts → pipeline/standard-pipeline.ts} +221 -191
- package/src/pipeline/standard-profile.ts +65 -0
- package/src/pipeline-builder.ts +60 -64
- package/src/pipeline-spec-types.ts +28 -0
- package/src/pipeline-spec.ts +72 -609
- package/src/plugin.ts +7 -75
- package/src/points-lines/__tests__/bounds.unit.test.ts +21 -0
- package/src/points-lines/__tests__/cache-recovery.unit.test.ts +157 -0
- package/src/points-lines/__tests__/inspection-lanes.integration.test.ts +146 -0
- package/src/points-lines/__tests__/inspection.unit.test.ts +173 -0
- package/src/points-lines/__tests__/lane-structural.integration.test.ts +122 -0
- package/src/points-lines/__tests__/points-lines.bench.ts +400 -0
- package/src/points-lines/__tests__/raster-lane.integration.test.ts +44 -0
- package/src/points-lines/__tests__/snapshot.unit.test.ts +101 -0
- package/src/points-lines/__tests__/view-ubo.unit.test.ts +73 -0
- package/src/points-lines/admission.ts +238 -0
- package/src/points-lines/bounds.ts +23 -0
- package/src/points-lines/expansion-cache.ts +215 -0
- package/src/points-lines/inspection.ts +97 -0
- package/src/points-lines/prepare.ts +177 -0
- package/src/points-lines/record.ts +125 -0
- package/src/points-lines/snapshot.ts +130 -0
- package/src/post-process-errors.ts +31 -33
- package/src/prepare/prepared-graphics-resolver.ts +5 -4
- package/src/record/__tests__/material-slot-plan.unit.test.ts +1 -33
- package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +41 -0
- package/src/record/__tests__/video-texture-view.unit.test.ts +1 -1
- package/src/record/frame-lighting.ts +88 -197
- package/src/record/frame-snapshot.ts +45 -60
- package/src/record/frame-targets.ts +8 -243
- package/src/record/frame.ts +521 -797
- package/src/record/helpers.ts +6 -11
- package/src/record/main-pass-geometry.ts +198 -147
- package/src/record/main-pass-material.ts +517 -190
- package/src/record/main-pass-sprite-draws.ts +199 -118
- package/src/record/main-pass.ts +166 -144
- package/src/record/mesh-ssbo.ts +517 -38
- package/src/record/render-context.ts +384 -0
- package/src/record/shadow-pass.ts +154 -1843
- package/src/record/skybox-post-pass.ts +14 -15
- package/src/record/typed-frame-graph.ts +224 -262
- package/src/record/view-ubo.ts +53 -37
- package/src/render-contract.ts +582 -0
- package/src/render-data.ts +3 -3
- package/src/render-graph-primitives.ts +76 -851
- package/src/render-pipeline.ts +104 -188
- package/src/render-system-extract.ts +1114 -1732
- package/src/render-system.ts +614 -1939
- package/src/scene/render-scene-types.ts +67 -0
- package/src/scene/render-scene.ts +1087 -0
- package/src/scene-instances/post-spawn-resolve-joints.ts +4 -7
- package/src/ssao-buffers.ts +167 -8
- package/src/systems/skin-palette-allocator.ts +21 -64
- package/src/systems/skin-palette-types.ts +14 -0
- package/src/systems/transparent-sort-config.ts +25 -3
- package/src/tilemap-chunk-extract-system.ts +53 -70
- package/src/typed-render-graph-primitives.ts +35 -24
- package/src/typed-shadow-passes.ts +26 -56
- package/dist/__tests__/analytic-sky-contract.test.d.ts +0 -2
- package/dist/__tests__/analytic-sky-contract.test.d.ts.map +0 -1
- package/dist/__tests__/analytic-sky-falsify.test.d.ts +0 -2
- package/dist/__tests__/analytic-sky-falsify.test.d.ts.map +0 -1
- package/dist/__tests__/assets-runtime-handoff.integration.test.d.ts +0 -2
- package/dist/__tests__/assets-runtime-handoff.integration.test.d.ts.map +0 -1
- package/dist/__tests__/backend-selection.integration.test.d.ts +0 -2
- package/dist/__tests__/backend-selection.integration.test.d.ts.map +0 -1
- package/dist/__tests__/camera-temporal.test-d.d.ts +0 -2
- package/dist/__tests__/camera-temporal.test-d.d.ts.map +0 -1
- package/dist/__tests__/camera-temporal.test.d.ts +0 -2
- package/dist/__tests__/camera-temporal.test.d.ts.map +0 -1
- package/dist/__tests__/directional-shadow-probe-atlas-layout.unit.test.d.ts +0 -2
- package/dist/__tests__/directional-shadow-probe-atlas-layout.unit.test.d.ts.map +0 -1
- package/dist/__tests__/environment-inspection.test.d.ts +0 -2
- package/dist/__tests__/environment-inspection.test.d.ts.map +0 -1
- package/dist/__tests__/fog-ai-user.fixture.d.ts +0 -2
- package/dist/__tests__/fog-ai-user.fixture.d.ts.map +0 -1
- package/dist/__tests__/fog-custom-render-feature.fixture.d.ts +0 -16
- package/dist/__tests__/fog-custom-render-feature.fixture.d.ts.map +0 -1
- package/dist/__tests__/fog-custom-render-feature.integration.test.d.ts +0 -2
- package/dist/__tests__/fog-custom-render-feature.integration.test.d.ts.map +0 -1
- package/dist/__tests__/fog-inspection.integration.test.d.ts +0 -2
- package/dist/__tests__/fog-inspection.integration.test.d.ts.map +0 -1
- package/dist/__tests__/fog-owner-state.integration.test.d.ts +0 -2
- package/dist/__tests__/fog-owner-state.integration.test.d.ts.map +0 -1
- package/dist/__tests__/fog-pipeline-topology.integration.test.d.ts +0 -2
- package/dist/__tests__/fog-pipeline-topology.integration.test.d.ts.map +0 -1
- package/dist/__tests__/fog-public-surface.integration.test.d.ts +0 -2
- package/dist/__tests__/fog-public-surface.integration.test.d.ts.map +0 -1
- package/dist/__tests__/fog-ray-contract.integration.test.d.ts +0 -2
- package/dist/__tests__/fog-ray-contract.integration.test.d.ts.map +0 -1
- package/dist/__tests__/fog-source-absence.integration.test.d.ts +0 -2
- package/dist/__tests__/fog-source-absence.integration.test.d.ts.map +0 -1
- package/dist/__tests__/fog-temporal.integration.test.d.ts +0 -2
- package/dist/__tests__/fog-temporal.integration.test.d.ts.map +0 -1
- package/dist/__tests__/frame-chain.unit.test.d.ts +0 -2
- package/dist/__tests__/frame-chain.unit.test.d.ts.map +0 -1
- package/dist/__tests__/gpu-scene-field-type-owner.test-d.d.ts +0 -2
- package/dist/__tests__/gpu-scene-field-type-owner.test-d.d.ts.map +0 -1
- package/dist/__tests__/hdrp-pipeline.unit.test.d.ts +0 -2
- package/dist/__tests__/hdrp-pipeline.unit.test.d.ts.map +0 -1
- package/dist/__tests__/ibl/ibl-fallback.unit.test.d.ts +0 -2
- package/dist/__tests__/ibl/ibl-fallback.unit.test.d.ts.map +0 -1
- package/dist/__tests__/material-derived-error-stop-draw.integration.test.d.ts +0 -2
- package/dist/__tests__/material-derived-error-stop-draw.integration.test.d.ts.map +0 -1
- package/dist/__tests__/material-derived-payload.integration.test.d.ts +0 -2
- package/dist/__tests__/material-derived-payload.integration.test.d.ts.map +0 -1
- package/dist/__tests__/materials.unit.test.d.ts +0 -2
- package/dist/__tests__/materials.unit.test.d.ts.map +0 -1
- package/dist/__tests__/param-schema-projection-census.unit.test.d.ts +0 -2
- package/dist/__tests__/param-schema-projection-census.unit.test.d.ts.map +0 -1
- package/dist/__tests__/persistent-render-scene.unit.test.d.ts +0 -2
- package/dist/__tests__/persistent-render-scene.unit.test.d.ts.map +0 -1
- package/dist/__tests__/pipeline-error-policy-owner.unit.test.d.ts +0 -2
- package/dist/__tests__/pipeline-error-policy-owner.unit.test.d.ts.map +0 -1
- package/dist/__tests__/pipeline-pass-trace.test.d.ts +0 -2
- package/dist/__tests__/pipeline-pass-trace.test.d.ts.map +0 -1
- package/dist/__tests__/pipeline-stage-owner.test-d.d.ts +0 -2
- package/dist/__tests__/pipeline-stage-owner.test-d.d.ts.map +0 -1
- package/dist/__tests__/plugin.test.d.ts +0 -2
- package/dist/__tests__/plugin.test.d.ts.map +0 -1
- package/dist/__tests__/prepared-graphics-backend-matrix.unit.test.d.ts +0 -2
- package/dist/__tests__/prepared-graphics-backend-matrix.unit.test.d.ts.map +0 -1
- package/dist/__tests__/prepared-graphics-resolver-recording.unit.test.d.ts +0 -2
- package/dist/__tests__/prepared-graphics-resolver-recording.unit.test.d.ts.map +0 -1
- package/dist/__tests__/public-pipeline-id.test-d.d.ts +0 -2
- package/dist/__tests__/public-pipeline-id.test-d.d.ts.map +0 -1
- package/dist/__tests__/render-dispatch-membership.unit.test.d.ts +0 -2
- package/dist/__tests__/render-dispatch-membership.unit.test.d.ts.map +0 -1
- package/dist/__tests__/render-feature-construction.unit.test.d.ts +0 -2
- package/dist/__tests__/render-feature-construction.unit.test.d.ts.map +0 -1
- package/dist/__tests__/render-feature-error-code-owner.test-d.d.ts +0 -2
- package/dist/__tests__/render-feature-error-code-owner.test-d.d.ts.map +0 -1
- package/dist/__tests__/render-feature-gpu-buffer-usage-owner.test-d.d.ts +0 -2
- package/dist/__tests__/render-feature-gpu-buffer-usage-owner.test-d.d.ts.map +0 -1
- package/dist/__tests__/render-feature-graph.integration.test.d.ts +0 -2
- package/dist/__tests__/render-feature-graph.integration.test.d.ts.map +0 -1
- package/dist/__tests__/render-feature-graphics-staging.unit.test.d.ts +0 -2
- package/dist/__tests__/render-feature-graphics-staging.unit.test.d.ts.map +0 -1
- package/dist/__tests__/render-feature-order.unit.test.d.ts +0 -2
- package/dist/__tests__/render-feature-order.unit.test.d.ts.map +0 -1
- package/dist/__tests__/render-feature-prepared-graphics-recording.unit.test.d.ts +0 -2
- package/dist/__tests__/render-feature-prepared-graphics-recording.unit.test.d.ts.map +0 -1
- package/dist/__tests__/render-feature-staging.unit.test.d.ts +0 -2
- package/dist/__tests__/render-feature-staging.unit.test.d.ts.map +0 -1
- package/dist/__tests__/renderer-render-scene-public.test-d.d.ts +0 -2
- package/dist/__tests__/renderer-render-scene-public.test-d.d.ts.map +0 -1
- package/dist/__tests__/scene-temporal-coverage.unit.test.d.ts +0 -2
- package/dist/__tests__/scene-temporal-coverage.unit.test.d.ts.map +0 -1
- package/dist/__tests__/sun-snapshot-consumers.test.d.ts +0 -2
- package/dist/__tests__/sun-snapshot-consumers.test.d.ts.map +0 -1
- package/dist/__tests__/surface-backend-kind-owner.test-d.d.ts +0 -2
- package/dist/__tests__/surface-backend-kind-owner.test-d.d.ts.map +0 -1
- package/dist/__tests__/taa-history-store.unit.test.d.ts +0 -2
- package/dist/__tests__/taa-history-store.unit.test.d.ts.map +0 -1
- package/dist/__tests__/temporal-frame-transaction.integration.test.d.ts +0 -2
- package/dist/__tests__/temporal-frame-transaction.integration.test.d.ts.map +0 -1
- package/dist/__tests__/temporal-inspection.unit.test.d.ts +0 -2
- package/dist/__tests__/temporal-inspection.unit.test.d.ts.map +0 -1
- package/dist/assets/__tests__/asset-decoders.unit.test.d.ts +0 -2
- package/dist/assets/__tests__/asset-decoders.unit.test.d.ts.map +0 -1
- package/dist/assets/__tests__/mipmap-generator.unit.test.d.ts +0 -2
- package/dist/assets/__tests__/mipmap-generator.unit.test.d.ts.map +0 -1
- package/dist/assets/__tests__/render-asset-port.unit.test.d.ts +0 -2
- package/dist/assets/__tests__/render-asset-port.unit.test.d.ts.map +0 -1
- package/dist/assets/__tests__/resolve-render-asset.unit.test.d.ts +0 -2
- package/dist/assets/__tests__/resolve-render-asset.unit.test.d.ts.map +0 -1
- package/dist/chunk-DJIMFYX6.mjs +0 -1439
- package/dist/chunk-DJIMFYX6.mjs.map +0 -1
- package/dist/chunk-F2SIOCRM.mjs +0 -7423
- package/dist/chunk-F2SIOCRM.mjs.map +0 -1
- package/dist/chunk-JMSB7AR4.mjs +0 -3
- package/dist/chunk-JMSB7AR4.mjs.map +0 -1
- package/dist/chunk-KHI6K4C6.mjs +0 -659
- package/dist/chunk-KHI6K4C6.mjs.map +0 -1
- package/dist/chunk-PORZOL2V.mjs +0 -569
- package/dist/chunk-PORZOL2V.mjs.map +0 -1
- package/dist/chunk-UOJGMDGP.mjs +0 -29913
- package/dist/chunk-UOJGMDGP.mjs.map +0 -1
- package/dist/components/__tests__/atmosphere-red.test.d.ts +0 -2
- package/dist/components/__tests__/atmosphere-red.test.d.ts.map +0 -1
- package/dist/components/__tests__/atmosphere.test.d.ts +0 -2
- package/dist/components/__tests__/atmosphere.test.d.ts.map +0 -1
- package/dist/components/__tests__/fog.test-d.d.ts +0 -2
- package/dist/components/__tests__/fog.test-d.d.ts.map +0 -1
- package/dist/components/__tests__/fog.test.d.ts +0 -2
- package/dist/components/__tests__/fog.test.d.ts.map +0 -1
- package/dist/components/atmosphere.d.ts +0 -18
- package/dist/components/atmosphere.d.ts.map +0 -1
- package/dist/components/environment.d.ts +0 -115
- package/dist/components/environment.d.ts.map +0 -1
- package/dist/deferred-lighting.d.ts +0 -13
- package/dist/deferred-lighting.d.ts.map +0 -1
- package/dist/dynamic-texture-store.d.ts +0 -42
- package/dist/dynamic-texture-store.d.ts.map +0 -1
- package/dist/environment/__tests__/failure-injection.test.d.ts +0 -2
- package/dist/environment/__tests__/failure-injection.test.d.ts.map +0 -1
- package/dist/environment/__tests__/generation-red.test.d.ts +0 -2
- package/dist/environment/__tests__/generation-red.test.d.ts.map +0 -1
- package/dist/environment/__tests__/generation.test.d.ts +0 -2
- package/dist/environment/__tests__/generation.test.d.ts.map +0 -1
- package/dist/environment/__tests__/graph-transaction.test.d.ts +0 -2
- package/dist/environment/__tests__/graph-transaction.test.d.ts.map +0 -1
- package/dist/environment/__tests__/inspection-red.test.d.ts +0 -2
- package/dist/environment/__tests__/inspection-red.test.d.ts.map +0 -1
- package/dist/environment/__tests__/lifecycle-evidence.test.d.ts +0 -2
- package/dist/environment/__tests__/lifecycle-evidence.test.d.ts.map +0 -1
- package/dist/environment/__tests__/pipeline-topology.test.d.ts +0 -2
- package/dist/environment/__tests__/pipeline-topology.test.d.ts.map +0 -1
- package/dist/environment/__tests__/readiness.test.d.ts +0 -2
- package/dist/environment/__tests__/readiness.test.d.ts.map +0 -1
- package/dist/environment/__tests__/recovery.test.d.ts +0 -2
- package/dist/environment/__tests__/recovery.test.d.ts.map +0 -1
- package/dist/environment/__tests__/resize-dispose.test.d.ts +0 -2
- package/dist/environment/__tests__/resize-dispose.test.d.ts.map +0 -1
- package/dist/environment/__tests__/signature-red.test.d.ts +0 -2
- package/dist/environment/__tests__/signature-red.test.d.ts.map +0 -1
- package/dist/environment/__tests__/signature.test.d.ts +0 -2
- package/dist/environment/__tests__/signature.test.d.ts.map +0 -1
- package/dist/environment/descriptors.d.ts +0 -2
- package/dist/environment/descriptors.d.ts.map +0 -1
- package/dist/environment/extracted-environment.d.ts +0 -53
- package/dist/environment/extracted-environment.d.ts.map +0 -1
- package/dist/environment/generation.d.ts +0 -62
- package/dist/environment/generation.d.ts.map +0 -1
- package/dist/environment/gpu-bundle.d.ts +0 -23
- package/dist/environment/gpu-bundle.d.ts.map +0 -1
- package/dist/environment/graph.d.ts +0 -108
- package/dist/environment/graph.d.ts.map +0 -1
- package/dist/environment/inspection.d.ts +0 -48
- package/dist/environment/inspection.d.ts.map +0 -1
- package/dist/environment/lifecycle.d.ts +0 -22
- package/dist/environment/lifecycle.d.ts.map +0 -1
- package/dist/environment/readiness.d.ts +0 -29
- package/dist/environment/readiness.d.ts.map +0 -1
- package/dist/environment/signature.d.ts +0 -70
- package/dist/environment/signature.d.ts.map +0 -1
- package/dist/extract/__tests__/directional-csm-domain.unit.test.d.ts +0 -2
- package/dist/extract/__tests__/directional-csm-domain.unit.test.d.ts.map +0 -1
- package/dist/extract/__tests__/environment-source.test.d.ts +0 -2
- package/dist/extract/__tests__/environment-source.test.d.ts.map +0 -1
- package/dist/extract/__tests__/schema-readers.unit.test.d.ts +0 -2
- package/dist/extract/__tests__/schema-readers.unit.test.d.ts.map +0 -1
- package/dist/extract/directional-csm.d.ts +0 -129
- package/dist/extract/directional-csm.d.ts.map +0 -1
- package/dist/extract/index.d.ts +0 -5
- package/dist/extract/index.d.ts.map +0 -1
- package/dist/extract/material-interface.d.ts +0 -56
- package/dist/extract/material-interface.d.ts.map +0 -1
- package/dist/extract/schema-readers.d.ts +0 -20
- package/dist/extract/schema-readers.d.ts.map +0 -1
- package/dist/features/graph-contribution.d.ts +0 -64
- package/dist/features/graph-contribution.d.ts.map +0 -1
- package/dist/features/index.d.ts +0 -21
- package/dist/features/index.d.ts.map +0 -1
- package/dist/features/morph/index.d.ts +0 -3
- package/dist/features/morph/index.d.ts.map +0 -1
- package/dist/features/morph/morph-bounds.d.ts +0 -42
- package/dist/features/morph/morph-bounds.d.ts.map +0 -1
- package/dist/features/scene-temporal.d.ts +0 -45
- package/dist/features/scene-temporal.d.ts.map +0 -1
- package/dist/features/taa-resolve.d.ts +0 -21
- package/dist/features/taa-resolve.d.ts.map +0 -1
- package/dist/frame-chain.d.ts +0 -14
- package/dist/frame-chain.d.ts.map +0 -1
- package/dist/gpu-driven/view-reference.d.ts.map +0 -1
- package/dist/gpu-resource-store.d.ts.map +0 -1
- package/dist/hdrp-cluster-membership.d.ts +0 -2
- package/dist/hdrp-cluster-membership.d.ts.map +0 -1
- package/dist/hdrp-pipeline.d.ts +0 -36
- package/dist/hdrp-pipeline.d.ts.map +0 -1
- package/dist/ibl/cubemap-projection.d.ts +0 -23
- package/dist/ibl/cubemap-projection.d.ts.map +0 -1
- package/dist/ibl/face-uniforms.d.ts +0 -65
- package/dist/ibl/face-uniforms.d.ts.map +0 -1
- package/dist/mesh-update-errors.d.ts +0 -71
- package/dist/mesh-update-errors.d.ts.map +0 -1
- package/dist/mipmap-generator.d.ts +0 -39
- package/dist/mipmap-generator.d.ts.map +0 -1
- package/dist/param-schema-projection-census.d.ts +0 -18
- package/dist/param-schema-projection-census.d.ts.map +0 -1
- package/dist/persistent-render-scene.d.ts +0 -158
- package/dist/persistent-render-scene.d.ts.map +0 -1
- package/dist/pipeline/index.d.ts +0 -11
- package/dist/pipeline/index.d.ts.map +0 -1
- package/dist/pipeline-errors.d.ts +0 -110
- package/dist/pipeline-errors.d.ts.map +0 -1
- package/dist/prepare/__tests__/schema-readers.unit.test.d.ts +0 -2
- package/dist/prepare/__tests__/schema-readers.unit.test.d.ts.map +0 -1
- package/dist/prepare/index.d.ts +0 -4
- package/dist/prepare/index.d.ts.map +0 -1
- package/dist/prepare/schema-readers.d.ts +0 -11
- package/dist/prepare/schema-readers.d.ts.map +0 -1
- package/dist/record/__tests__/environment-record.test.d.ts +0 -2
- package/dist/record/__tests__/environment-record.test.d.ts.map +0 -1
- package/dist/record/__tests__/frame-targets.unit.test.d.ts +0 -2
- package/dist/record/__tests__/frame-targets.unit.test.d.ts.map +0 -1
- package/dist/record/__tests__/membership-timing.unit.test.d.ts +0 -2
- package/dist/record/__tests__/membership-timing.unit.test.d.ts.map +0 -1
- package/dist/record/__tests__/render-submission.integration.test.d.ts +0 -2
- package/dist/record/__tests__/render-submission.integration.test.d.ts.map +0 -1
- package/dist/record/__tests__/render-submission.perf.test.d.ts +0 -2
- package/dist/record/__tests__/render-submission.perf.test.d.ts.map +0 -1
- package/dist/record/__tests__/shadow-submit-mode.unit.test.d.ts +0 -2
- package/dist/record/__tests__/shadow-submit-mode.unit.test.d.ts.map +0 -1
- package/dist/record/__tests__/view-ubo-layout.unit.test.d.ts +0 -2
- package/dist/record/__tests__/view-ubo-layout.unit.test.d.ts.map +0 -1
- package/dist/record/frame-observation.d.ts +0 -38
- package/dist/record/frame-observation.d.ts.map +0 -1
- package/dist/record/index.d.ts +0 -15
- package/dist/record/index.d.ts.map +0 -1
- package/dist/record/main-pass-skin.d.ts +0 -46
- package/dist/record/main-pass-skin.d.ts.map +0 -1
- package/dist/record/main-pass-sprite.d.ts +0 -69
- package/dist/record/main-pass-sprite.d.ts.map +0 -1
- package/dist/record/material-payload.d.ts +0 -43
- package/dist/record/material-payload.d.ts.map +0 -1
- package/dist/record/material-slot-plan.d.ts +0 -26
- package/dist/record/material-slot-plan.d.ts.map +0 -1
- package/dist/record/membership-timing.d.ts +0 -232
- package/dist/record/membership-timing.d.ts.map +0 -1
- package/dist/record/shadow-caster-uniform.d.ts +0 -8
- package/dist/record/shadow-caster-uniform.d.ts.map +0 -1
- package/dist/record/shadow-submit-mode.d.ts +0 -66
- package/dist/record/shadow-submit-mode.d.ts.map +0 -1
- package/dist/render-dispatch-membership.d.ts +0 -47
- package/dist/render-dispatch-membership.d.ts.map +0 -1
- package/dist/render-pipeline-context.d.ts +0 -289
- package/dist/render-pipeline-context.d.ts.map +0 -1
- package/dist/render-pipeline-target.d.ts +0 -16
- package/dist/render-pipeline-target.d.ts.map +0 -1
- package/dist/render-scene-projection.d.ts +0 -174
- package/dist/render-scene-projection.d.ts.map +0 -1
- package/dist/render-system-fold.d.ts +0 -266
- package/dist/render-system-fold.d.ts.map +0 -1
- package/dist/renderer/asset-service.d.ts +0 -10
- package/dist/renderer/asset-service.d.ts.map +0 -1
- package/dist/renderer/backend-selection.d.ts.map +0 -1
- package/dist/renderer/environment-classify.d.ts +0 -6
- package/dist/renderer/environment-classify.d.ts.map +0 -1
- package/dist/renderer/environment-error.d.ts +0 -13
- package/dist/renderer/environment-error.d.ts.map +0 -1
- package/dist/renderer/material/pipeline-projection.d.ts +0 -91
- package/dist/renderer/material/pipeline-projection.d.ts.map +0 -1
- package/dist/renderer/renderer-factory.d.ts +0 -289
- package/dist/renderer/renderer-factory.d.ts.map +0 -1
- package/dist/renderer.d.ts +0 -771
- package/dist/renderer.d.ts.map +0 -1
- package/dist/scene-utils/collect-subtree.d.ts +0 -11
- package/dist/scene-utils/collect-subtree.d.ts.map +0 -1
- package/dist/ssao-data.d.ts +0 -34
- package/dist/ssao-data.d.ts.map +0 -1
- package/dist/surface-format.d.ts +0 -10
- package/dist/surface-format.d.ts.map +0 -1
- package/dist/taa-history-store.d.ts +0 -88
- package/dist/taa-history-store.d.ts.map +0 -1
- package/dist/temporal-coverage.d.ts +0 -35
- package/dist/temporal-coverage.d.ts.map +0 -1
- package/dist/temporal-frame-transaction.d.ts +0 -92
- package/dist/temporal-frame-transaction.d.ts.map +0 -1
- package/dist/temporal-inspection.d.ts +0 -57
- package/dist/temporal-inspection.d.ts.map +0 -1
- package/dist/temporal-view.d.ts +0 -43
- package/dist/temporal-view.d.ts.map +0 -1
- package/dist/tilemap/resolve-tileset-runtime.d.ts +0 -23
- package/dist/tilemap/resolve-tileset-runtime.d.ts.map +0 -1
- package/dist/urp-pipeline.d.ts +0 -4
- package/dist/urp-pipeline.d.ts.map +0 -1
- package/src/__tests__/analytic-sky-contract.test.ts +0 -27
- package/src/__tests__/analytic-sky-falsify-carriers.mjs +0 -43
- package/src/__tests__/analytic-sky-falsify.test.ts +0 -94
- package/src/__tests__/assets-runtime-handoff.integration.test.ts +0 -36
- package/src/__tests__/backend-selection.integration.test.ts +0 -11
- package/src/__tests__/camera-temporal.test-d.ts +0 -8
- package/src/__tests__/camera-temporal.test.ts +0 -188
- package/src/__tests__/directional-shadow-probe-atlas-layout.unit.test.ts +0 -18
- package/src/__tests__/environment-inspection.test.ts +0 -45
- package/src/__tests__/fog-ai-user.fixture.ts +0 -350
- package/src/__tests__/fog-custom-render-feature.fixture.ts +0 -33
- package/src/__tests__/fog-custom-render-feature.integration.test.ts +0 -76
- package/src/__tests__/fog-inspection.integration.test.ts +0 -127
- package/src/__tests__/fog-owner-state.integration.test.ts +0 -112
- package/src/__tests__/fog-pipeline-topology.integration.test.ts +0 -93
- package/src/__tests__/fog-public-surface.integration.test.ts +0 -60
- package/src/__tests__/fog-ray-contract.integration.test.ts +0 -73
- package/src/__tests__/fog-source-absence.integration.test.ts +0 -51
- package/src/__tests__/fog-temporal.integration.test.ts +0 -115
- package/src/__tests__/frame-chain.unit.test.ts +0 -26
- package/src/__tests__/gpu-scene-field-type-owner.test-d.ts +0 -27
- package/src/__tests__/hdrp-pipeline.unit.test.ts +0 -100
- package/src/__tests__/ibl/ibl-fallback.unit.test.ts +0 -23
- package/src/__tests__/material-derived-error-stop-draw.integration.test.ts +0 -69
- package/src/__tests__/material-derived-payload.integration.test.ts +0 -164
- package/src/__tests__/materials.unit.test.ts +0 -25
- package/src/__tests__/param-schema-projection-census.unit.test.ts +0 -40
- package/src/__tests__/persistent-render-scene.unit.test.ts +0 -1311
- package/src/__tests__/pipeline-error-policy-owner.unit.test.ts +0 -167
- package/src/__tests__/pipeline-pass-trace.test.ts +0 -92
- package/src/__tests__/pipeline-stage-owner.test-d.ts +0 -13
- package/src/__tests__/plugin.test.ts +0 -25
- package/src/__tests__/prepared-graphics-backend-matrix.unit.test.ts +0 -129
- package/src/__tests__/prepared-graphics-resolver-recording.unit.test.ts +0 -180
- package/src/__tests__/public-pipeline-id.test-d.ts +0 -6
- package/src/__tests__/render-dispatch-membership.unit.test.ts +0 -117
- package/src/__tests__/render-feature-construction.unit.test.ts +0 -124
- package/src/__tests__/render-feature-error-code-owner.test-d.ts +0 -27
- package/src/__tests__/render-feature-gpu-buffer-usage-owner.test-d.ts +0 -46
- package/src/__tests__/render-feature-graph.integration.test.ts +0 -205
- package/src/__tests__/render-feature-graphics-staging.unit.test.ts +0 -200
- package/src/__tests__/render-feature-order.unit.test.ts +0 -66
- package/src/__tests__/render-feature-prepared-graphics-recording.unit.test.ts +0 -107
- package/src/__tests__/render-feature-staging.unit.test.ts +0 -94
- package/src/__tests__/renderer-render-scene-public.test-d.ts +0 -27
- package/src/__tests__/scene-temporal-coverage.unit.test.ts +0 -259
- package/src/__tests__/sun-snapshot-consumers.test.ts +0 -35
- package/src/__tests__/surface-backend-kind-owner.test-d.ts +0 -42
- package/src/__tests__/taa-history-store.unit.test.ts +0 -196
- package/src/__tests__/temporal-frame-transaction.integration.test.ts +0 -537
- package/src/__tests__/temporal-inspection.unit.test.ts +0 -138
- package/src/assets/__tests__/asset-decoders.unit.test.ts +0 -92
- package/src/assets/__tests__/mipmap-generator.unit.test.ts +0 -52
- package/src/assets/__tests__/render-asset-port.unit.test.ts +0 -54
- package/src/assets/__tests__/resolve-render-asset.unit.test.ts +0 -47
- package/src/components/__tests__/atmosphere-red.test.ts +0 -51
- package/src/components/__tests__/atmosphere.test.ts +0 -79
- package/src/components/__tests__/fog.test-d.ts +0 -49
- package/src/components/__tests__/fog.test.ts +0 -60
- package/src/components/atmosphere.ts +0 -64
- package/src/deferred-lighting.ts +0 -92
- package/src/dynamic-texture-store.ts +0 -111
- package/src/environment/README.md +0 -76
- package/src/environment/__tests__/failure-injection.test.ts +0 -50
- package/src/environment/__tests__/generation-red.test.ts +0 -64
- package/src/environment/__tests__/generation.test.ts +0 -37
- package/src/environment/__tests__/graph-transaction.test.ts +0 -85
- package/src/environment/__tests__/inspection-red.test.ts +0 -53
- package/src/environment/__tests__/lifecycle-evidence.test.ts +0 -40
- package/src/environment/__tests__/pipeline-topology.test.ts +0 -33
- package/src/environment/__tests__/readiness.test.ts +0 -42
- package/src/environment/__tests__/recovery.test.ts +0 -62
- package/src/environment/__tests__/resize-dispose.test.ts +0 -30
- package/src/environment/__tests__/signature-red.test.ts +0 -45
- package/src/environment/__tests__/signature.test.ts +0 -60
- package/src/environment/descriptors.ts +0 -7
- package/src/environment/extracted-environment.ts +0 -239
- package/src/environment/generation.ts +0 -158
- package/src/environment/gpu-bundle.ts +0 -144
- package/src/environment/graph.ts +0 -588
- package/src/environment/inspection.ts +0 -107
- package/src/environment/lifecycle.ts +0 -124
- package/src/environment/readiness.ts +0 -76
- package/src/environment/signature.ts +0 -185
- package/src/extract/__tests__/directional-csm-domain.unit.test.ts +0 -391
- package/src/extract/__tests__/environment-source.test.ts +0 -105
- package/src/extract/__tests__/schema-readers.unit.test.ts +0 -16
- package/src/extract/directional-csm.ts +0 -959
- package/src/extract/index.ts +0 -10
- package/src/extract/material-interface.ts +0 -604
- package/src/extract/schema-readers.ts +0 -27
- package/src/features/graph-contribution.ts +0 -577
- package/src/features/index.ts +0 -100
- package/src/features/morph/index.ts +0 -24
- package/src/features/morph/morph-bounds.ts +0 -123
- package/src/features/scene-temporal.ts +0 -274
- package/src/features/taa-resolve.ts +0 -244
- package/src/frame-chain.ts +0 -21
- package/src/hdrp-cluster-membership.ts +0 -70
- package/src/ibl/cubemap-projection.ts +0 -60
- package/src/ibl/face-uniforms.ts +0 -150
- package/src/mesh-update-errors.ts +0 -113
- package/src/mipmap-generator.ts +0 -244
- package/src/param-schema-projection-census.ts +0 -73
- package/src/persistent-render-scene.ts +0 -1752
- package/src/pipeline/index.ts +0 -40
- package/src/pipeline-errors.ts +0 -172
- package/src/prepare/__tests__/schema-readers.unit.test.ts +0 -16
- package/src/prepare/index.ts +0 -8
- package/src/prepare/schema-readers.ts +0 -20
- package/src/record/__tests__/environment-record.test.ts +0 -35
- package/src/record/__tests__/frame-targets.unit.test.ts +0 -54
- package/src/record/__tests__/membership-timing.unit.test.ts +0 -524
- package/src/record/__tests__/render-submission.integration.test.ts +0 -76
- package/src/record/__tests__/render-submission.perf.test.ts +0 -141
- package/src/record/__tests__/shadow-submit-mode.unit.test.ts +0 -88
- package/src/record/__tests__/view-ubo-layout.unit.test.ts +0 -101
- package/src/record/frame-observation.ts +0 -122
- package/src/record/index.ts +0 -15
- package/src/record/main-pass-skin.ts +0 -51
- package/src/record/main-pass-sprite.ts +0 -166
- package/src/record/material-payload.ts +0 -292
- package/src/record/material-slot-plan.ts +0 -68
- package/src/record/membership-timing.ts +0 -1012
- package/src/record/shadow-caster-uniform.ts +0 -37
- package/src/record/shadow-submit-mode.ts +0 -277
- package/src/render-dispatch-membership.ts +0 -155
- package/src/render-pipeline-context.ts +0 -332
- package/src/render-pipeline-target.ts +0 -96
- package/src/render-scene-projection.ts +0 -1738
- package/src/render-system-fold.ts +0 -531
- package/src/renderer/asset-service.ts +0 -32
- package/src/renderer/backend-selection.ts +0 -121
- package/src/renderer/environment-classify.ts +0 -30
- package/src/renderer/environment-error.ts +0 -19
- package/src/renderer/material/pipeline-projection.ts +0 -140
- package/src/renderer.ts +0 -940
- package/src/scene-utils/collect-subtree.ts +0 -40
- package/src/ssao-data.ts +0 -106
- package/src/surface-format.ts +0 -37
- package/src/taa-history-store.ts +0 -429
- package/src/temporal-coverage.ts +0 -106
- package/src/temporal-frame-transaction.ts +0 -301
- package/src/temporal-inspection.ts +0 -194
- package/src/temporal-view.ts +0 -174
- package/src/tilemap/resolve-tileset-runtime.ts +0 -72
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/glyph-text.ts","../src/components/sprite-animation.ts","../src/components/sprite-instances.ts","../src/components/sprite-playback-mode.ts","../src/components/sprite-region-override.ts","../src/components/tile-layer.ts","../src/components/tilemap.ts","../src/errors/render.ts","../src/components/atmosphere.ts","../src/components/camera.ts","../src/components/directional-light.ts","../src/components/environment.ts","../src/components/instances.ts","../src/components/layer.ts","../src/components/mesh-filter.ts","../src/components/mesh-renderer.ts","../src/components/point-light.ts","../src/components/point-light-shadow.ts","../src/components/post-process-params.ts","../src/components/scene-instance.ts","../src/components/sort-key.ts","../src/components/spot-light.ts","../src/components/visibility.ts","../src/materials.ts","../src/assets/resolve-render-asset.ts","../src/glyph-text-layout-system.ts","../src/systems/transparent-sort-config.ts"],"names":["defineComponent","err","ok","layout","materialId"],"mappings":"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","file":"chunk-DJIMFYX6.mjs","sourcesContent":["// @forgeax/engine-runtime - GlyphText component (feat-20260531-world-space-msdf-text-rendering M4 / w14).\n//\n// `GlyphText` is the authoring source component for world-space MSDF text\n// (requirements AC-06 / §domain model). It carries ONLY authoring data; the\n// glyph quad baking + MeshFilter / MeshRenderer attachment is the job of the\n// `glyphTextLayoutSystem` (plan-strategy D-2: GlyphText is pure authoring\n// data, baking is a system responsibility). There is NO `TextLayoutAsset`\n// intermediate (OOS-5) -- layout output lives directly in a baked MeshAsset.\n//\n// Naming: single-semantic component drops the `Component` suffix\n// (AGENTS.md §Component naming rule #1 -- Transform / Camera / GlyphText).\n//\n// Schema vocab:\n// - `fontHandle: 'shared<FontAsset>'` -> `Handle<'FontAsset', 'shared'>`\n// (u32-stored; AssetRegistry owns the FontAsset lifecycle). AI users\n// obtain the handle via `assets.load(guid, fontAssetKind)`.\n// - `text: 'string'` -> native JS string (UniqueRefStore-backed, same\n// dispatch as `Name.value`).\n// - `fontSize: 'f32'` -> layout scale applied to the FontAsset metrics.\n// - `color: 'array<f32, 4>'` -> linear-space rgba tint (feat-20260709 M3:\n// collapsed from four `colorR/G/B/A` scalar columns into one inline\n// stride-4 SoA column, mirroring the DirectionalLight direction/color\n// idiom). Explicit layer-2 default [1,1,1,1] (opaque white).\n//\n// charter mapping: P1 (single import surface from `@forgeax/engine-render`,\n// co-located with `glyphTextLayoutSystem` that consumes it) + P3\n// (machine-readable schema literal) + P5 (consistent abstraction: same\n// `'shared<T>'` idiom as MeshFilter.assetHandle / MeshRenderer.materials).\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Glyph text authoring component (world-space MSDF text).\n *\n * Spawn an entity with a `GlyphText` and the `glyphTextLayoutSystem`\n * (auto-wired by `createRenderer` / `createApp`) lays out the glyph quads,\n * bakes a `MeshAsset`, and attaches `MeshFilter` + `MeshRenderer` on the\n * next frame (Commands-deferred). Mutating `text` / `fontSize` / `color`\n * re-bakes the mesh in place (plan-strategy D-1 updateMesh; registry size\n * unchanged, AC-08).\n *\n * @example Spawn a world-space label:\n * import { GlyphText } from '@forgeax/engine-render/authoring';\n * const font = (await assets.load(fontGuid, fontAssetKind)).unwrap();\n * world.spawn({\n * component: GlyphText,\n * data: { fontHandle: font, text: 'Hello', fontSize: 32,\n * color: [1, 1, 1, 1] },\n * });\n */\nexport const GlyphText = defineComponent('GlyphText', {\n // The layout/render owner re-resolves the font asset on the target world;\n // authoring text and style remain portable simulation state.\n fontHandle: {\n type: 'shared<FontAsset>',\n default: 0 as never,\n },\n text: { type: 'string', default: '' },\n fontSize: { type: 'f32', default: 16 },\n // color carries an explicit layer-2 default [1,1,1,1] (opaque white); the\n // array layer-3 fallback is all-zero, so the default MUST be explicit (D-5).\n color: { type: 'array<f32, 4>', default: new Float32Array([1, 1, 1, 1]) },\n});\n","// @forgeax/engine-runtime - SpriteAnimation (per-entity frame-tick clock).\n//\n// 6-field schema (1:1 with requirements section 2.3 table; D-5 + D-6\n// vocab keywords locked):\n//\n// frameCount : 'u32' total frames in the cycle (>= 1).\n// frameDuration : 'f32' per-frame seconds (> 0).\n// currentFrame : 'u32' live frame index, in [0, frameCount).\n// accumDt : 'f32' dt accumulator (research F-3 carries\n// fractional residue across ticks).\n// regions : 'array<f32>' flat per-frame UV rectangles\n// [uMin, vMin, uW, vH]; the M4 tick\n// system enforces\n// `regions.length === frameCount * 4`\n// on first observation (AC-09 fail-fast,\n// D-1 path).\n// playbackMode : 'u32' numeric encoding of `SpritePlaybackMode`\n// (0 = SPRITE_PLAYBACK_MODE_LOOP,\n// 1 = SPRITE_PLAYBACK_MODE_CLAMP).\n//\n// Why u32 for playbackMode? research F-2 + F-5: the ECS schema whitelist\n// rejects string-literal unions. The M1 SSOT\n// `packages/runtime/src/components/sprite-playback-mode.ts` carries the\n// numeric constants + the `spritePlaybackModeFromU32` mapper that turns\n// the column value back into a string-literal union at the M4 tick-system\n// seam — same shape as the M1 Tonemap encoding (`tonemap: 'f32'` +\n// TONEMAP_NONE / TONEMAP_REINHARD_EXTENDED + tonemapFromF32). One mental\n// model across all closed-union schema columns; charter P4 consistent\n// abstraction.\n//\n// Why array<f32> (variable) and not array<f32, N> (fixed) for regions?\n// The length `frameCount * 4` is data-dependent: `frameCount` is itself a\n// per-entity column read at runtime, not a schema-time literal. Same\n// shape as M1 `Instances.transforms: 'array<f32>'` whose length depends\n// on the live instance count; D-6 codifies the precedent.\n//\n// dt accumulator clock model (requirements section 2.5 q6 + plan-strategy\n// section 2 D-5):\n// accumDt += Time.delta\n// while (accumDt >= frameDuration) { advance currentFrame; accumDt -= frameDuration }\n// The carry-over `accumDt` survives across ticks so frame timing stays\n// stable under jittery dt; M4 T-23 implements the loop. Per-frame UV\n// is materialised by writing the slice\n// `regions[currentFrame*4 .. currentFrame*4 + 4]` into the entity's\n// `SpriteRegionOverride.region` column (T-11 + M4 T-23).\n//\n// Sprite-only consumption (requirements section 5 constraint #2): the\n// M4 tick system + the M3 extract branch read this component only when\n// the entity routes through the sprite bucket. Opaque buckets ignore\n// the component even when present. Naming keeps the `Sprite` prefix per\n// OOS-01 (no premature 3D generalisation); 3D UV animation lands in a\n// separate component in a future feat.\n//\n// 4-step recipe (charter F1 progressive disclosure — minimum walk-cycle\n// host code; full demo lands in M6 hello-sprite-atlas):\n// 1. Build atlas via `forgeax-engine-remote-asset atlas --input <glob> --name <prefix> --output <dir>`\n// (M5 build-time hook); load the emitted `<name>.atlas.png` plus\n// `<name>.atlas.meta.json` sidecar.\n// 2. Register the sprite material referencing the atlas\n// `TextureAsset` with the initial frame's `region` rectangle (the\n// runtime tick system overrides this region per entity per frame).\n// 3. `world.spawn` an entity with a quad mesh reference +\n// `MeshRenderer(spriteMaterial)` + `Instances(...)` plus this\n// `SpriteAnimation` (frameCount / frameDuration / regions /\n// playbackMode) and `SpriteRegionOverride { region }` (the tick\n// system writes per-frame UV).\n// 4. Add `spriteAnimationTickSystem` (M4 T-23) to the schedule between\n// input/time and `RenderSystem.extract`.\n//\n// @derives `defineComponent` factory (packages/ecs/src/component.ts) —\n// `'u32'` / `'f32'` are scalar tier-1 keywords; `'array<f32>'` is a\n// tier-2 schema-vocab keyword (variable-capacity; M1 feat-20260515\n// buffer-array vocab). Layer-3 default fallback fills missing\n// `currentFrame` / `accumDt` / `playbackMode` with 0\n// (component-default-fallback typeDefault table).\n// @consumes M4 T-23 (`spriteAnimationTickSystem` reads all 6 fields and\n// writes per-frame slice into SpriteRegionOverride).\n//\n// charter mapping: F1 (single-import barrel discovery + 4-step recipe\n// at the JSDoc head); P3 (4 explicit error fields surface via the M4\n// tick-system fail-fast — `regions.length` mismatch / `frameDuration`\n// non-positive routes through SpriteAnimationInvalidError, M1 T-05);\n// P4 (consistent abstraction — same numeric closed-union encoding as\n// Tonemap / TransparentSortConfig.mode); P5 (producer / consumer\n// separation — atlas regions are produced build-time by\n// vite-plugin-image and consumed runtime as a flat Float32Array; AI\n// users never call a packer at runtime).\n//\n// Anchors: plan-strategy section 2 D-5 + D-6 + section 3.1 SAC + section\n// 4 risks R-SCHEMA-1 + R-SCHEMA-2 + R-TIME-1 reaction; plan-tasks.json\n// T-12; research F-2 + F-3 + F-5; requirements section AC-02 + section\n// 2.3 + section 2.5 + section 7 boundary table.\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Per-entity sprite frame-tick clock.\n *\n * Schema (6 fields, 1:1 with requirements section 2.3):\n * - `frameCount: u32` — total frames (>= 1).\n * - `frameDuration: f32` — seconds per frame (> 0).\n * - `currentFrame: u32` — live frame index (0..frameCount). Layer-3\n * default `0` when omitted at spawn.\n * - `accumDt: f32` — dt residue carried across ticks. Layer-3 default\n * `0` when omitted; lives on the component (not on a system-side\n * resource) so the system stays stateless and AI-user setFrame paths\n * can reset both `currentFrame` and `accumDt` atomically.\n * - `regions: array<f32>` — flat per-frame UV rectangles\n * `[uMin, vMin, uW, vH]`; runtime invariant\n * `regions.length === frameCount * 4` (enforced by the M4 tick system).\n * - `playbackMode: u32` — numeric encoding of `SpritePlaybackMode`;\n * `SPRITE_PLAYBACK_MODE_LOOP = 0` (default) /\n * `SPRITE_PLAYBACK_MODE_CLAMP = 1`.\n *\n * Pair with `SpriteRegionOverride` (T-11) — the tick system writes the\n * per-frame UV slice into the override column, which `render-system-\n * extract` then reads in the sprite bucket branch.\n *\n * @example Spawn a 4-frame walk cycle that loops:\n * import { MeshFilter, MeshRenderer } from '@forgeax/engine-render';\n * import {\n * SpriteAnimation, SpriteRegionOverride, SPRITE_PLAYBACK_MODE_LOOP,\n * } from '@forgeax/engine-render/authoring';\n * import { Transform } from '@forgeax/engine-scene';\n * import { createPrimitiveMesh } from '@forgeax/engine-geometry';\n * const quadMesh = world.internSharedRef(createPrimitiveMesh('quad').unwrap());\n *\n * // 4 frames packed in an atlas, each 64x64 inside a 256x64 row:\n * const regions = new Float32Array([\n * 0.00, 0, 0.25, 1, // walk-0\n * 0.25, 0, 0.25, 1, // walk-1\n * 0.50, 0, 0.25, 1, // walk-2\n * 0.75, 0, 0.25, 1, // walk-3\n * ]);\n * world.spawn(\n * { component: Transform, data: { pos: [0, 0, 0],\n * quat: [0, 0, 0, 1], scale: [1, 1, 1] } },\n * { component: MeshFilter, data: { assetHandle: quadMesh } },\n * { component: MeshRenderer, data: { materials: [spriteMaterial] } },\n * { component: SpriteAnimation,\n * data: {\n * frameCount: 4,\n * frameDuration: 0.1,\n * regions,\n * playbackMode: SPRITE_PLAYBACK_MODE_LOOP,\n * } },\n * { component: SpriteRegionOverride,\n * data: { region: new Float32Array([0, 0, 0.25, 1]) } },\n * );\n *\n * @example Manual setFrame — jump to frame 2 atomically:\n * world.set(entity, SpriteAnimation,\n * { currentFrame: 2, accumDt: 0 }).unwrap();\n *\n * Error path (M4 T-23 routes through `SpriteAnimationInvalidError`,\n * `EcsErrorCode === 'sprite-animation-invalid'`; charter P3):\n * - `regions.length !== frameCount * 4` -> detail.field = 'regions-length',\n * detail carries `regionsLength` + `frameCount`.\n * - `frameDuration <= 0` -> detail.field = 'frame-duration', detail carries\n * `frameDuration`.\n */\nexport const SpriteAnimation = defineComponent('SpriteAnimation', {\n frameCount: { type: 'u32' },\n frameDuration: { type: 'f32' },\n currentFrame: { type: 'u32', transient: true },\n accumDt: { type: 'f32', transient: true },\n regions: { type: 'array<f32>' },\n playbackMode: { type: 'u32' },\n});\n","// @forgeax/engine-runtime - SpriteInstances component (per-entity 2D\n// instanced-draw transforms + per-instance UV region).\n//\n// Schema: 2 array<f32> fields. `transforms` carries packed column-major mat4\n// instance transforms (16 f32 per instance, stride = 16). `regions` carries\n// packed per-instance UV vec4 (4 f32 per instance, stride = 4; layout\n// [uMin, vMin, uW, vH] mirroring SpriteAnimation.regions). The pair share\n// the same instance count; the SSOT invariant is\n// transforms.length / 16 === regions.length / 4\n// enforced through a TWO-LAYER contract:\n//\n// 1. AI user set-site: spawn / `world.set` / `world.push` callers pass two\n// Float32Arrays whose lengths satisfy the stride pair. The set site is\n// the AI user's responsibility — the engine cannot prove column-major\n// mat4 packing or per-instance UV intent without caller declaration.\n// 2. RenderSystem extract entry: `render-system-extract.ts` performs a\n// defensive `transforms.length / 16 === regions.length / 4` check on\n// every `world.get(e, SpriteInstances)` snapshot at frame extract time;\n// violations route a structured `SpriteInstancesCountMismatchError`\n// (`code: 'sprite-instances-count-mismatch'`,\n// `detail: { transformsLength, regionsLength, expectedStride: { transforms: 16, regions: 4 } }`)\n// through the World Layer-3 ErrorHandler and the renderable is skipped.\n// Two further extract-entry checks fire:\n// - `'sprite-instances-requires-sprite-shader'` — MaterialAsset's\n// first pass `shader` must be `'forgeax::sprite'`.\n// - `'sprite-instances-mutually-exclusive-with-instances'` — same\n// entity must not carry both Instances + SpriteInstances.\n// (Error class declarations live in `@forgeax/engine-ecs` errors.ts; the\n// extract-entry fire path is owned by feat M3 w12 / w13.)\n//\n// Peer relation to Instances (charter P4 consistent abstraction):\n// - Instances : 3D scene primitive — per-instance mat4 only (stride 16).\n// - SpriteInstances : 2D scene primitive — per-instance mat4 + per-instance\n// UV region (interleaved 80B per instance: 64B mat4 + 16B region).\n// AI users pick by data shape (does the per-instance carry UV?). Both ride\n// the array-vocab path and route through the same Layer-3 error envelope.\n//\n// Group transform chained semantics (charter proposition 5 mental migration):\n// When the same entity carries both `Transform` (entity_world) and\n// `SpriteInstances` (per-instance local transforms), the vertex shader\n// composes per instance:\n// world_position[i] = entity_world * instances_local[i] * vertex_position\n// `SpriteInstances.transforms[i*16..i*16+15]` is interpreted as a local-\n// space transform under the entity, exactly like `Instances.transforms`.\n// Set the entity's `Transform` to identity to make `instances_local[i]`\n// directly world-space.\n//\n// Uniform / storage buffer cap (research D-R-4 + AC-04): 80B per instance\n// * 128-cap fallback = 10240 B < 16384 B uniform max; the storage-buffer\n// path is uncapped and used by capable backends (RenderSystem record-stage\n// cap-gate).\n//\n// 4-segment minimum contract (read this header before reaching for the\n// source body):\n//\n// ===== (a) single-component import + spawn example =====\n//\n// import {\n// createRenderer,\n// MeshFilter, MeshRenderer, Transform,\n// SpriteInstances, type SpriteInstancesData,\n// } from '@forgeax/engine-render';\n//\n// // 1 entity rendering N instanced sprites (16N transforms f32 + 4N regions f32):\n// const transforms = new Float32Array(N * 16);\n// const regions = new Float32Array(N * 4);\n// // ... fill column-major mat4 columns + [uMin, vMin, uW, vH] per instance ...\n// world.spawn(\n// { component: MeshFilter, data: { assetHandle: quadMesh } },\n// { component: MeshRenderer, data: { /* sprite-shaded MaterialAsset */ } },\n// { component: SpriteInstances, data: { transforms, regions } },\n// );\n//\n// ===== (b) packed mat4 + region layout =====\n//\n// const transforms = new Float32Array(N * 16); // column-major mat4 per instance\n// const regions = new Float32Array(N * 4); // [uMin, vMin, uW, vH] per instance\n// // instance i occupies floats:\n// // transforms[i*16 .. i*16+15] — column-major mat4 (translation in m03/m13/m23)\n// // regions [i* 4 .. i* 4+ 3] — uMin, vMin, uW, vH (atlas-normalized UV rect)\n//\n// `transforms.length` MUST be a non-zero multiple of 16; `regions.length`\n// MUST be a non-zero multiple of 4; the per-instance count derived from\n// both MUST agree. AI users gate at the set / push site; the RenderSystem\n// extract entry holds the second defensive (see error path 1 below).\n//\n// ===== (c) error code consumption (typed property access, no message regex) =====\n//\n// // Stride / mutual-exclusion / sprite-shader violations surface through\n// // the engine-ecs Layer-3 ErrorHandler when extract reads a malformed\n// // snapshot:\n// // on('error', (err) => {\n// // switch (err.code) {\n// // case 'sprite-instances-count-mismatch':\n// // // err.detail.transformsLength / regionsLength / expectedStride\n// // break;\n// // case 'sprite-instances-requires-sprite-shader':\n// // // err.detail.entityId / observedMaterialShaderId\n// // break;\n// // case 'sprite-instances-mutually-exclusive-with-instances':\n// // // err.detail.entityId\n// // break;\n// // }\n// // });\n//\n// charter mapping (charter v2 numbering, with round-1 v1 aliases retained\n// in parentheses so reviewers tracking the v1 spec can cross-reference;\n// SSOT for the v2 -> v1 alias map is the AI User Charter — see\n// .claude/skills/forgeax-closed-loop/agents/ai-user-charter.md):\n// F1 (alias: proposition 1) — single import surface\n// `import { SpriteInstances, type SpriteInstancesData } from\n// '@forgeax/engine-render'`;\n// P2 (alias: proposition 3) — machine-readable schema > prose:\n// `{ transforms: 'array<f32>', regions: 'array<f32>' }` is the SSOT,\n// stride pair documented here + enforced at the RenderSystem entry;\n// P3 (alias: proposition 4) — explicit failure: 3 structured EcsError\n// codes route per failure shape, not silent half-row;\n// P4 (alias: proposition 5) — consistent abstraction: SpriteInstances\n// mirrors Instances — both ride the array-vocab path; pick by data\n// shape, not by API.\n//\n// Anchors: requirements AC-01 (component schema), AC-03 (3 error codes),\n// AC-09 (IDE autocomplete + type inference); plan-strategy D-1 (interleaved\n// single binding slot), D-6 (3 codes declared in M1 ecs, fired in M3 render),\n// D-7 (type export location), D-8 (barrel re-export at runtime, not ecs).\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Per-entity 2D instanced-draw primitive (ECS component).\n *\n * Carries two variable-length `array<f32>` fields:\n * - `transforms` — column-major mat4 per instance (16 f32, stride 16);\n * - `regions` — UV vec4 per instance ([uMin, vMin, uW, vH], 4 f32,\n * stride 4).\n *\n * The pair share the same instance count; the invariant\n * `transforms.length / 16 === regions.length / 4` is enforced at the\n * RenderSystem extract entry (NOT at ECS write paths). The runtime\n * RenderSystem consumer materialises a fresh `Float32Array` snapshot on\n * every `world.get(e, SpriteInstances)` access and uploads an interleaved\n * 80B-per-instance buffer to the GPU in the record stage.\n *\n * @example Spawn an entity rendering 10000 instanced sprites:\n * const transforms = new Float32Array(10000 * 16);\n * const regions = new Float32Array(10000 * 4);\n * // ... fill mat4 columns + [uMin, vMin, uW, vH] ...\n * world.spawn(\n * { component: MeshFilter, data: { assetHandle: quadMesh } },\n * { component: MeshRenderer, data: { ... } },\n * { component: SpriteInstances, data: { transforms, regions } },\n * );\n */\nexport const SpriteInstances = defineComponent('SpriteInstances', {\n transforms: { type: 'array<f32>' },\n regions: { type: 'array<f32>' },\n});\n\n/**\n * Type-level hint for `data` at the `SpriteInstances` spawn site.\n *\n * The runtime ECS column shape for `array<f32>` accepts a `Float32Array`\n * payload at spawn / set time (the bytes are copied into the BufferPool\n * slot). Both fields are typed as `Float32Array` so AI-user IDE\n * autocomplete picks up the typed-array shape and the AC-09 inference\n * surfaces without `as` casts inside `world.get(e, SpriteInstances)` and\n * QueryRow access paths.\n *\n * @example\n * import type { SpriteInstancesData } from '@forgeax/engine-render/authoring';\n * const data: SpriteInstancesData = {\n * transforms: new Float32Array(N * 16),\n * regions: new Float32Array(N * 4),\n * };\n */\nexport type SpriteInstancesData = {\n readonly transforms: Float32Array;\n readonly regions: Float32Array;\n};\n","// @forgeax/engine-runtime - SpritePlaybackMode (u32 column encoding + mapper).\n//\n// SSOT for the SpriteAnimation.playbackMode ECS column (M2 T-12) and the\n// runtime tick-system branch selector (M4 T-23). The shape mirrors the M1\n// `Tonemap` block in `./camera.ts:72-90` (TONEMAP_NONE = 0 /\n// TONEMAP_REINHARD_EXTENDED = 1 + `type Tonemap = 'none' |\n// 'reinhard-extended'` + `tonemapFromF32`) for charter P4 consistent\n// abstraction — AI users keep one mental model across all u32-encoded\n// closed-union schema columns.\n//\n// Why `'u32'` + constant + mapper instead of a string-literal column?\n// ECS schema whitelist `SchemaFieldType` (packages/ecs/src/component.ts\n// section schema-field-type) does not accept string-literal unions\n// (research F-2 + F-5). Storing a u32 + translating to a closed\n// `'loop' | 'clamp'` literal union at the tick-system seam preserves\n// AI-user-facing narrowing (`switch (mode) { case 'loop': ... }`)\n// without forcing the ECS column to learn a new field-type vocabulary.\n//\n// Naming convention (plan-strategy section 8.command naming):\n// SPRITE_PLAYBACK_MODE_LOOP / SPRITE_PLAYBACK_MODE_CLAMP mirror M1\n// TONEMAP_* / TRANSPARENT_SORT_MODE_*. `spritePlaybackModeFromU32`\n// mirrors `tonemapFromF32` / `cameraProjectionFromF32`. AI users\n// discover the trio via single-import barrel re-export from\n// `@forgeax/engine-runtime` (wired in by M2 T-13).\n//\n// Anchors: plan-strategy section 2 D-5 + section 3.1 PR block SPM +\n// section 4 risk R-SCHEMA-1 reaction; research F-2 + F-5;\n// requirements section AC-02 + section 2.3 playbackMode row;\n// plan-tasks.json T-07 acceptanceCheck (rg\n// \"SPRITE_PLAYBACK_MODE_LOOP|SPRITE_PLAYBACK_MODE_CLAMP|\n// spritePlaybackModeFromU32\" >= 3 hits in this file).\n\n/**\n * Playback mode discriminator literal union (requirements section AC-02 +\n * section 2.3). Two members for the MVP:\n *\n * `'loop'` — `currentFrame = (currentFrame + 1) % frameCount`; the\n * sprite-animation-tick system wraps the index when\n * `accumDt >= frameDuration` (default for hello-sprite-\n * atlas demo \"100 sprites synchronised walk cycle\").\n * `'clamp'` — `currentFrame = min(currentFrame + 1, frameCount - 1)`;\n * holds the last frame for death / terminator-animation\n * style sequences (requirements section 2.5 q8 lock).\n *\n * Future modes (`'pingpong'`, reverse playback, arbitrary frame index\n * jumps) are deferred per requirements OOS-03. The closed union shape\n * leaves room for additive growth without breaking the u32 enum encoding\n * (plan-strategy section 2 D-5).\n */\nexport type SpritePlaybackMode = 'loop' | 'clamp';\n\n/** Numeric encoding of the loop playback mode (schema value for `playbackMode`). */\nexport const SPRITE_PLAYBACK_MODE_LOOP = 0 as const;\n\n/** Numeric encoding of the clamp playback mode (schema value for `playbackMode`). */\nexport const SPRITE_PLAYBACK_MODE_CLAMP = 1 as const;\n\n/**\n * Map a `SpriteAnimation.playbackMode` numeric column value to the closed\n * `SpritePlaybackMode` string-literal union. The defensive fallback mirrors\n * `cameraProjectionFromF32` / `tonemapFromF32` precedent — any value other\n * than `SPRITE_PLAYBACK_MODE_CLAMP` (1) maps to `'loop'`, so stale or\n * uninitialised entities surface a predictable playback shape through the\n * tick-system query (rather than throwing or returning `undefined`).\n * Validation of `playbackMode` happens at schema-write time, not here.\n *\n * The tick-system in M4 T-23 (`spriteAnimationTickSystem`) consumes the\n * return value via `switch (mode) { case 'loop': ...; case 'clamp': ... }`\n * to pick the per-branch frame-advance arithmetic.\n */\nexport function spritePlaybackModeFromU32(value: number): SpritePlaybackMode {\n return value === SPRITE_PLAYBACK_MODE_CLAMP ? 'clamp' : 'loop';\n}\n","// @forgeax/engine-runtime - SpriteRegionOverride (per-entity UV region\n// override, sprite-only).\n//\n// Schema: 1 fixed-length array column `region: 'array<f32, 4>'` carrying a\n// packed UV sub-rectangle `[uMin, vMin, uW, vH]`. The fixed `4` length is\n// enforced at compile time by the ECS schema-vocab keyword\n// `'array<T, N>'` (D-6: prefer compile-time enforcement over runtime\n// fail-fast for length-bound contracts).\n//\n// Why an entity-side override component instead of a render parameter on\n// MaterialRenderer? Plan-strategy section 1 / requirements section 5\n// constraint #1 (Pipeline Isolation R1, M1 ssot): `AssetRegistry` stays\n// append-only / read-only and `MaterialRenderer` schema is frozen.\n// Per-entity render-parameter overrides ride the same rail as Layer /\n// SortKey — one ECS column per entity, read at extract time, never\n// flowing back to the asset.\n//\n// Sprite-only consumption (requirements section 5 constraint #2 + section\n// 7 boundary line 1): `render-system-extract` reads this component ONLY\n// inside the sprite bucket branch (`pipelineTag === 'sprite'` plus the\n// asset-side sprite discriminant). Opaque (`unlit` / `standard`) buckets\n// ignore the column even when the entity happens to carry it; the M3\n// T-15 grep gate\n// (`packages/runtime/src/__tests__/sprite-only-isolation-grep-gate.test.ts`)\n// asserts this file contains zero substring matches against the asset\n// discriminant identifier as a structural lock (charter P5 producer /\n// consumer separation: the component owner never names the asset\n// discriminant directly).\n//\n// Naming: bare `SpriteRegionOverride` (no `Component` suffix per\n// AGENTS.md section Component naming \"Single-semantic components drop\n// the Component suffix\"). The `Sprite` prefix is intentional — 3D UV\n// region animation lands in a separate component (e.g. future\n// `MaterialRegionOverride`) per OOS-01 to avoid premature 3D\n// generalisation. Plan-strategy section 8 naming convention pins the\n// prefix to make the AC-11 grep gate trivially decidable.\n//\n// @derives `defineComponent` factory (packages/ecs/src/component.ts) —\n// `'array<f32, 4>'` is on the `SchemaVocabKeyword` whitelist (line ~94\n// `array<${ManagedArrayElementType}, ${number}>`).\n// @consumes M3 T-16 (`render-system-extract.ts` sprite bucket branch\n// reads override into `paramSnapshot.region`, post-M3 feat-20260625\n// ablation -- the pre-ablation per-entity hop through the snapshot\n// POD layer collapsed into the generic paramSchema-driven path).\n// @produces M4 T-23 (`spriteAnimationTickSystem` writes per-frame UV\n// slice into `region`).\n//\n// charter mapping: F1 (single-import barrel discovery — joins Layer /\n// SortKey / Transform / SpriteAnimation under a single\n// `from '@forgeax/engine-render'`); P3 (compile-time length=4 lock\n// surfaces mismatched payloads at the TS edge before the column write\n// path observes them); P4 (consistent abstraction — same per-entity\n// override shape AI users already learned for Layer / SortKey).\n//\n// Anchors: plan-strategy section 2 D-6 + section 3.1 SRO + section 4\n// risk R-SCHEMA-2 reaction; plan-tasks.json T-11; research F-5;\n// requirements section AC-01 + section 2.4 + section 5 constraint #2.\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Per-entity sprite UV region override (sprite-only).\n *\n * Carries a fixed-length `Float32Array(4)` of `[uMin, vMin, uW, vH]` that\n * `render-system-extract` reads in the sprite bucket branch and writes\n * into `paramSnapshot.region`, replacing the asset-side region for\n * this entity only (feat-20260625 M3 ablation: the prior per-entity POD\n * indirection collapsed into the generic paramSchema-driven snapshot).\n * Opaque buckets ignore this component; the AC-11 grep gate keeps the\n * producer / consumer separation structural (this file never names the\n * asset-side sprite discriminant identifier).\n *\n * Pair with `SpriteAnimation` to drive the override per frame\n * (sprite-animation-tick system, M4 T-23). Standalone use (manual region\n * override without animation) is also supported — set the column once and\n * the next extract picks up the new value.\n *\n * Schema-vocab keyword `'array<f32, 4>'` (D-6) — fixed-length 4 is the\n * compile-time enforcement axis. `Float32Array` payloads with length !== 4\n * round-trip fewer / more bytes per the underlying BufferPool slot, but\n * the slot is sized at schema registration time; AI users keep the\n * payload exactly four-floats wide.\n *\n * @example Spawn a sprite entity that displays the right half of an atlas:\n * import { MeshFilter, MeshRenderer } from '@forgeax/engine-render';\n * import { SpriteRegionOverride } from '@forgeax/engine-render/authoring';\n * import { Transform } from '@forgeax/engine-scene';\n * import { createPrimitiveMesh } from '@forgeax/engine-geometry';\n * const quadMesh = world.internSharedRef(createPrimitiveMesh('quad').unwrap());\n *\n * world.spawn(\n * { component: Transform, data: { pos: [0, 0, 0],\n * quat: [0, 0, 0, 1], scale: [1, 1, 1] } },\n * { component: MeshFilter, data: { assetHandle: quadMesh } },\n * { component: MeshRenderer, data: { materials: [spriteMaterial] } },\n * { component: SpriteRegionOverride,\n * data: { region: new Float32Array([0.5, 0, 0.5, 1]) } },\n * );\n *\n * @example Update the override at runtime (e.g. flip-frame test):\n * world.set(entity, SpriteRegionOverride,\n * { region: new Float32Array([0, 0, 1, 1]) }).unwrap();\n */\nexport const SpriteRegionOverride = defineComponent('SpriteRegionOverride', {\n region: { type: 'array<f32, 4>' },\n});\n","// @forgeax/engine-runtime - TileLayer (one render layer of a Tilemap).\n//\n// Schema (4 fields):\n// tiles array<u32> per-cell tile id (packed Tiled .tmj wire form);\n// length == parent.Tilemap.cols * rows.\n// layerOrder i32 render-order key (higher = drawn on top).\n// dirty u8 0 means clean, non-zero means dirty - the next\n// tilemap-chunk-extract-system pass rebuilds derived\n// per-cell entities for this layer.\n// sortScope u8 (TS: 0 = 'layer' (default) - terrain semantics:\n// closed every derived entity in this\n// 'layer' | layer shares one Layer.value\n// 'per-cell' (layerOrder << 20), so the\n// union) whole layer Y-sorts as a single\n// bucket. AI users grep\n// `sortScope: 'layer'` to confirm.\n// 1 = 'per-cell' - object semantics: each derived\n// entity carries its own foot-Y\n// key; preserves per-cell entity\n// derivation for Y-interleave\n// with sprite entities sharing\n// the same Layer.value.\n//\n// Storage rationale (D-V-3 R-NEW-1 fallback / round-2): ECS schema does not\n// yet support `values: ['layer', 'per-cell']` literal-union constraints\n// on a `'string'` column, so the on-disk shape is `u8` (0/1) but every\n// AI-facing TS surface (`TileLayerData.sortScope`) is the closed\n// `'layer' | 'per-cell'` string union. The bridge functions\n// `encodeSortScope` / `decodeSortScope` are the SSOT for the two-way\n// mapping (charter F1 — single grep target).\n//\n// Each TileLayer entity attaches to a Tilemap entity via ChildOf (the parent\n// field carries the Tilemap entity). M0 supports multiple TileLayer entities\n// per Tilemap (each rendered as an independent z-ordered layer).\n//\n// charter mapping: F1 (single-import barrel + single grep target for\n// `sortScope`), P1 (progressive disclosure — `'layer'` / `'per-cell'`\n// reads directly without a magic-number table), P3 (dirty flag is\n// explicit - silent re-extraction is forbidden), P4 (handle-free row\n// schema mirrors MeshFilter / MeshRenderer conventions).\n\nimport { defineComponent, type EcsError, type EntityHandle, type World } from '@forgeax/engine-ecs';\nimport type { Result } from '@forgeax/engine-types';\n\n/**\n * Closed string-literal union for the TileLayer.sortScope field. AI users\n * grep `sortScope` and land on this single SSOT type alias; switch\n * statements over this type are exhaustive without a default arm.\n *\n * - 'layer' - terrain semantics; whole layer shares one Layer.value\n * bucket and Y-sorts together (chunkIndex is folded into 0).\n * - 'per-cell' - object semantics; each derived entity gets its own\n * chunkIndex tiebreak so it can Y-interleave with\n * sprite entities carrying the same Layer.value (e.g. a\n * player sprite riding the same SPRITE_LAYER_VALUE).\n */\nexport type SortScope = 'layer' | 'per-cell';\n\n/**\n * Bridge: `SortScope` -> on-disk u8. SSOT for the encoding (`'layer'` -> 0,\n * `'per-cell'` -> 1). The compile-time exhaustive switch guards against\n * silent drift if the union ever grows; adding a new literal here without\n * adding its arm fails typecheck (charter P3 — closed unions never default).\n */\nexport function encodeSortScope(scope: SortScope): 0 | 1 {\n switch (scope) {\n case 'layer':\n return 0;\n case 'per-cell':\n return 1;\n }\n}\n\n/**\n * Bridge: on-disk u8 -> `SortScope`. Defaults to `'layer'` for any value\n * outside `{0, 1}` (defensive — the column is typed `u8` so out-of-range\n * values can only appear if a future schema migration loosens the bound;\n * the default preserves terrain semantics which is the safer of the two).\n */\nexport function decodeSortScope(raw: number | undefined): SortScope {\n return raw === 1 ? 'per-cell' : 'layer';\n}\n\n/**\n * Public TileLayer field shape (`world.spawn({ component: TileLayer, data:\n * { ... } })` payload). `sortScope` is the closed string union surfaced to\n * AI users; the runtime row encodes it as `u8` via `encodeSortScope` at\n * spawn time so on-disk storage stays compact.\n *\n * Treat as the `TileLayer` data SSOT — `defineComponent` schema below\n * mirrors it field-for-field with the bridge `sortScope: u8` in place of\n * the union literal.\n */\nexport interface TileLayerData {\n readonly tiles: Uint32Array;\n readonly layerOrder?: number;\n readonly dirty?: number;\n readonly sortScope?: SortScope;\n}\n\n/**\n * TileLayer component (M0 baseline rebuild + round-2 sortScope rename).\n *\n * AI users typically spawn a TileLayer + ChildOf pair pointing at an\n * existing Tilemap entity:\n *\n * @example\n * const tilesArray = new Uint32Array(cols * rows);\n * tilesArray[5 * cols + 7] = 1; // tile id 1 at cell (7, 5)\n * world.spawn(\n * { component: TileLayer, data: { tiles: tilesArray, layerOrder: 0 } },\n * { component: ChildOf, data: { parent: tilemapEntity } },\n * );\n *\n * Object-layer variant (Y-interleave with sprite entities):\n *\n * > NOTE: schema storage is `u8` (ECS schema does not support\n * > string-literal-union column constraints; see R-NEW-2). The\n * > AI-user surface is the closed `SortScope` string union, but\n * > `world.spawn` requires the numeric encoding — pass through\n * > `encodeSortScope('per-cell')` rather than the literal string.\n *\n * @example\n * world.spawn(\n * { component: TileLayer, data: {\n * tiles: objectTiles,\n * layerOrder: 1000,\n * sortScope: encodeSortScope('per-cell'),\n * } },\n * { component: ChildOf, data: { parent: tilemapEntity } },\n * );\n *\n * Defaults: `layerOrder = 0`, `dirty = 0`, `sortScope = 'layer'` (stored\n * as `u8 = 0`, i.e. `encodeSortScope('layer')`). `tiles` has no default -\n * AI users supply the per-cell array at spawn time. To trigger a re-build\n * after mutating tiles in place, call `markTileLayerDirty(world, layer)`.\n */\nexport const TileLayer = defineComponent('TileLayer', {\n tiles: { type: 'array<u32>' },\n layerOrder: { type: 'i32', default: 0 },\n dirty: { type: 'u8', default: 0 },\n sortScope: { type: 'u8', default: 0 },\n});\n\n/**\n * Mark a TileLayer entity dirty so the next `tilemapChunkExtractSystem`\n * pass purges and re-spawns its derived per-cell entities. Use this after\n * mutating `TileLayer.tiles` (e.g. an in-place patch via a column view).\n *\n * Returns the underlying ECS write result - on `err` branch the caller\n * can read `.code` to recover (`'stale-entity'` if the layer was\n * despawned, `'component-not-present'` if the entity is missing the\n * TileLayer column; both kebab-case literals are members of the closed\n * `EcsErrorCode` union).\n */\nexport function markTileLayerDirty(\n world: World,\n layerEntity: EntityHandle,\n): Result<void, EcsError> {\n return world.set(layerEntity, TileLayer, { dirty: 1 });\n}\n","// @forgeax/engine-runtime - Tilemap (grid + tileset reference).\n//\n// Schema (5 fields):\n// cols u32 total grid columns\n// rows u32 total grid rows\n// tileSize array<f32, 2> per-cell world [width, height] (default [1, 1];\n// feat-20260709 M3: collapsed from the tileSizeX\n// / tileSizeY scalar pair into one inline column)\n// chunkSize u32 per-chunk axis-length in cells (default 16)\n// tileset string durable TilesetAsset GUID\n//\n// Naming: single-semantic Tilemap (AGENTS.md §Component naming drops\n// `Component` suffix). One Tilemap entity per grid; TileLayer entities\n// attach via ChildOf relationship and supply the per-cell tile id array\n// for a single render-layer.\n//\n// charter mapping: F1 (single-import barrel from `@forgeax/engine-runtime`),\n// P1 (progressive disclosure - defaults cover the common case), P4 (durable\n// asset identity stays separate from World-local handles).\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Tilemap component (M0 baseline rebuild).\n *\n * A Tilemap entity carries grid metadata + a single durable `tileset` GUID. The\n * actual per-cell tile id array lives on attached `TileLayer` entities\n * (one per render layer; ChildOf points back to the Tilemap entity).\n *\n * Defaults:\n * - `tileSize = [1, 1]` (unit-cell world coordinates).\n * - `chunkSize = 16` (tilemap-chunk-extract-system chunks 16x16 cells).\n *\n * @example Spawn a 32x32 unit-cell Tilemap referencing a TilesetAsset:\n * const tilemap = world.spawn(\n * { component: Tilemap, data: { cols: 32, rows: 32, tileset } },\n * { component: Transform, data: {} },\n * ).unwrap();\n */\nexport const Tilemap = defineComponent('Tilemap', {\n cols: { type: 'u32', default: 0 },\n rows: { type: 'u32', default: 0 },\n // tileSize carries an explicit layer-2 default [1,1] (unit cell); the array\n // layer-3 fallback is all-zero, so the default MUST be explicit (D-5).\n tileSize: { type: 'array<f32, 2>', default: new Float32Array([1, 1]) },\n chunkSize: { type: 'u32', default: 16 },\n tileset: { type: 'string' },\n});\n","// @forgeax/engine-render -- render cluster error classes.\n//\n// feat-20260704-runtime-tier1-decomposition M2 / w8 (D-3): the monolithic\n// errors.ts RuntimeErrorCode / RuntimeError top-level aggregate unions are\n// decomposed into five per-cluster files (render / asset / skin / recover /\n// environment). Each cluster owns a closed *ErrorCode code union + a closed\n// *Error class union; error class names, .code literals, and .detail shapes\n// are preserved byte-for-byte (OOS-4: zero semantic change).\n//\n// The render cluster holds the shadow / HDRP cluster-forward + deferred /\n// g-buffer / point-shadow-atlas / video-upload / vertex-storage-buffer render\n// path errors. ShadowInvalidConfigError is consumed by the DirectionalLight /\n// SpotLight / PointLightShadow component validators (forward cross-directory\n// import, no cycle -- research Finding C2).\n\nimport type {\n RenderFeatureCapabilityMissingDetail,\n RenderFeatureDrawRecordingFailedDetail,\n RenderFeaturePassOrderConflictDetail,\n RenderFeaturePreparationFailedDetail,\n RenderFeaturePreparedStateMismatchDetail,\n RenderFeatureRecovery,\n RenderFeatureRegistrationConflictDetail,\n RenderFeatureStage,\n RenderFeatureStageFailedDetail,\n} from '../features/types';\nimport type { MaterialRenderError } from '../renderer/material/pipeline-projection';\n\n// -- Scene Fog owner errors --------------------------------------------------\n\n/** Bounded identity facts for a resource-owner Fog cardinality conflict. */\nexport interface FogOwnerConflictDetail {\n readonly resourceOwner: number;\n readonly entities: readonly number[];\n readonly omitted: number;\n}\n\n/** The resource owner contains more than one Fog authoring entity. */\nexport class FogOwnerConflictError extends Error {\n readonly code = 'fog-owner-conflict' as const;\n readonly expected = 'resourceOwner contains zero or one Fog entity';\n readonly hint =\n 'remove every Fog entity except one from the resourceOwner World, then retry draw';\n readonly detail: FogOwnerConflictDetail;\n\n constructor(resourceOwner: number, entities: readonly number[], omitted: number) {\n super(\n `Fog owner conflict in resourceOwner ${resourceOwner}: ${entities.length + omitted} entities`,\n );\n this.name = 'FogOwnerConflictError';\n this.detail = {\n resourceOwner,\n entities: [...entities],\n omitted,\n };\n }\n}\n\n/** Structured detail for one invalid Fog field. */\nexport interface FogParametersInvalidDetail {\n readonly entity: number;\n readonly field: string;\n readonly expected: string;\n readonly actual: unknown;\n}\n\n/** A resource-owner Fog entity contains an invalid authored parameter. */\nexport class FogParametersInvalidError extends Error {\n readonly code = 'fog-parameters-invalid' as const;\n readonly expected: string;\n readonly hint: string;\n readonly detail: FogParametersInvalidDetail;\n\n constructor(entity: number, field: string, expected: string, actual: unknown) {\n super(`Fog.${field} is invalid on entity ${entity}`);\n this.name = 'FogParametersInvalidError';\n this.expected = expected;\n this.hint = `set Fog.${field} to ${expected} on entity ${entity}, then retry draw`;\n this.detail = { entity, field, expected, actual };\n }\n}\n\n// ── ShadowInvalidConfigError ──────────────────────────────────────────────\n\n/**\n * Detail for `RuntimeErrorCode 'shadow-invalid-config'`.\n *\n * Emitted by `DirectionalLight.validate` shadow-field path when a field value violates\n * runtime constraints (e.g. mapSize < 1, cascadeCount not in {1..4}).\n * AI users access `.detail.field` / `.detail.value` / `.detail.min` /\n * `.detail.max` via property access — no string parsing.\n *\n * `max` is `undefined` for lower-bound-only validations (e.g. mapSize < 1).\n * feat-20260613-csm: max added for upper-bound cascade validations\n * (cascadeCount max=4, splitLambda max=1, cascadeBlend max=0.5).\n */\nexport interface ShadowInvalidConfigDetail {\n readonly field: string;\n readonly value: number;\n readonly min: number;\n readonly max?: number;\n}\n\n/**\n * Structured error for shadow component config validation failures.\n *\n * Emitted by `DirectionalLight.validate()` shadow-field path (mapSize / cascadeCount /\n * splitLambda / cascadeBlend / shadowDistance) and `PointLightShadow.validate()`\n * (mapSize / farPlane > nearPlane / pcfKernelSize); both shadow component\n * types share this single error class so `switch (err.code)` on\n * `RuntimeErrorCode` only needs one branch (charter P4 — closed-union SSOT).\n * Four-field surface per AGENTS.md error model:\n * - `.code = 'shadow-invalid-config'` (closed RuntimeErrorCode)\n * - `.expected` — expected-state description (programmatic predicate form)\n * - `.hint` — actionable recovery guidance (imperative; AI users paste into\n * spawn calls). Integer-typed fields (e.g. `cascadeCount`, `pcfKernelSize`)\n * get an \"integer in [min, max]\" hint; otherwise \"[min, max]\" range or\n * \"<comparator> min\".\n * - `.detail = { field, value, min, max? }` — structured values (charter P4)\n *\n * 4th constructor parameter is a union over the two range shapes:\n * - `number` — `max` for a closed `[min, max]` range (CSM cascadeCount /\n * splitLambda / cascadeBlend). hint uses \"in [min, max]\"; integer-typed\n * fields get \"integer in [min, max]\".\n * - `'>' | '>='` — comparator for an open lower-bound predicate. `'>'` is\n * used when `min` carries dynamic context (e.g. `farPlane > nearPlane` —\n * the surfaced hint reads \"must be > nearPlane\" so AI users setting\n * farPlane=nearPlane don't re-fail the spawn loop with the wrong cue).\n * - `undefined` — defaults to `'>='`. Callsites for mapSize < 1 validation\n * stay backward-compatible (3-arg form).\n */\nexport class ShadowInvalidConfigError extends Error {\n readonly code = 'shadow-invalid-config' as const;\n readonly expected: string;\n readonly hint: string;\n readonly detail: ShadowInvalidConfigDetail;\n\n constructor(field: string, value: number, min: number, maxOrComparator?: number | '>' | '>=') {\n const isComparator = maxOrComparator === '>' || maxOrComparator === '>=';\n const max = !isComparator && typeof maxOrComparator === 'number' ? maxOrComparator : undefined;\n const comparator: '>' | '>=' = isComparator ? (maxOrComparator as '>' | '>=') : '>=';\n // Integer-typed fields get an \"integer in [min, max]\" hint when a range\n // is supplied. Expand this set as new integer-typed shadow fields land.\n const isInteger = field === 'cascadeCount' || field === 'pcfKernelSize';\n // pcfKernelSize must be odd (kernel is symmetric around the center tap).\n // Naming \"odd\" in the hint stops an AI retry from looping min->min+1 (4->6).\n const isOdd = field === 'pcfKernelSize';\n const hint =\n max !== undefined\n ? isInteger\n ? `set ${field} to an integer in [${min}, ${max}]; got ${value}`\n : `set ${field} to a value in [${min}, ${max}]; got ${value}`\n : isOdd\n ? `set ${field} to an odd integer ${comparator} ${min}; got ${value}`\n : `set ${field} to a value ${comparator} ${min}; got ${value}`;\n const expected =\n max !== undefined ? `${field} in [${min}, ${max}]` : `${field} ${comparator} ${min}`;\n super(\n max !== undefined\n ? `shadow component .${field} must be in [${min}, ${max}], got ${value}`\n : `shadow component .${field} must be ${comparator} ${min}, got ${value}`,\n );\n this.name = 'ShadowInvalidConfigError';\n this.hint = hint;\n this.expected = expected;\n this.detail = { field, value, min, ...(max !== undefined ? { max } : {}) };\n }\n}\n\n// ── EquirectProjectionFailedError ────────────────────────────────────────────\n\n/**\n * Detail for `RuntimeErrorCode 'equirect-projection-failed'`.\n *\n * Emitted when the equirect-to-cubemap IBL projection fails for the equirect\n * handle referenced by a `Skylight` / `SkyboxBackground` component. The handle\n * id is carried so AI users can trace which equirect source failed projection.\n * Degradation: the record arm records `status:'failed'`, binds the white-cube\n * fallback, fires this error ONCE, and does NOT retry the projection.\n *\n * feat-20260630 D-5: structured error with detail carrying the handle id.\n */\nexport interface EquirectProjectionFailedDetail {\n readonly handle: number;\n}\n\n/**\n * Structured error for a failed equirect-to-cubemap IBL projection.\n *\n * Emitted by the record stage when the internal cubemap projection for an\n * equirect handle returns a failure (or records `status:'failed'`). Four-field\n * surface per AGENTS.md error model:\n * - `.code = 'equirect-projection-failed'` (closed RuntimeErrorCode)\n * - `.expected` — equirect-to-cubemap projection + IBL precompute succeeds\n * - `.hint` — declare `Skylight{equirect}` with a valid HDR equirect source;\n * check `device.caps.rgba16floatRenderable`. The projection is internal —\n * there is no user upload call to retry\n * - `.detail = { handle }` — the numeric equirect handle id for diagnostics\n */\nexport class EquirectProjectionFailedError extends Error {\n readonly code = 'equirect-projection-failed' as const;\n readonly expected: string;\n readonly hint: string;\n readonly detail: EquirectProjectionFailedDetail;\n\n constructor(handle: number) {\n const expected = `equirect handle ${handle} projects to a GPU cubemap + IBL precompute`;\n const hint =\n `equirect handle ${handle} referenced by Skylight/SkyboxBackground failed projection; ` +\n `declare Skylight{equirect} with a valid HDR equirect source and check device.caps.rgba16floatRenderable. ` +\n `The projection is internal (no user upload call); the record arm does not retry`;\n super(`equirect handle ${handle} cubemap projection failed`);\n this.name = 'EquirectProjectionFailedError';\n this.expected = expected;\n this.hint = hint;\n this.detail = { handle };\n }\n}\n\n// ── HdrpCapsInsufficientError ──────────────────────────────────────────────\n\n/**\n * Detail for `RuntimeErrorCode 'hdrp-caps-insufficient'`.\n *\n * Emitted at install time when `device.caps.maxStorageBuffersPerShaderStage < 4`.\n */\nexport interface HdrpCapsInsufficientDetail {\n readonly capName: string;\n readonly actual: number;\n readonly required: number;\n}\n\n/**\n * Structured error for HDRP storage-buffer capability gate failure (AC-17/AC-18).\n *\n * Emitted at `installPipeline(hdrpAsset)` time — synchronous throw.\n * - `.code = 'hdrp-caps-insufficient'` (closed RuntimeErrorCode)\n * - `.expected` — describes the required capability\n * - `.hint` — 'fall back to URP by not calling installPipeline'\n * - `.detail = { capName, actual, required }`\n */\nexport class HdrpCapsInsufficientError extends Error {\n readonly code = 'hdrp-caps-insufficient' as const;\n readonly expected: string;\n readonly hint: string;\n readonly detail: HdrpCapsInsufficientDetail;\n\n constructor(capName: string, actual: number, required: number) {\n const expected = `${capName} >= ${required}`;\n const hint =\n `${capName} = ${actual} (need >= ${required}); ` +\n 'this device does not have enough storage buffer slots for HDRP cluster-forward rendering. ' +\n 'Fall back to URP by not calling installPipeline(hdrpAsset)';\n super(`HDRP caps insufficient: ${capName} = ${actual} (need >= ${required})`);\n this.name = 'HdrpCapsInsufficientError';\n this.expected = expected;\n this.hint = hint;\n this.detail = { capName, actual, required };\n }\n}\n\n// ── HdrpLightBudgetExceededError ───────────────────────────────────────────\n\n/**\n * Detail for `RuntimeErrorCode 'hdrp-light-budget-exceeded'`.\n *\n * Emitted per-frame (once-per-frame fire) when light count exceeds HDRP budget.\n */\nexport interface HdrpLightBudgetExceededDetail {\n readonly actual: number;\n readonly budget: number;\n}\n\n/**\n * Structured error for HDRP light budget exceeded (AC-06/AC-07).\n *\n * Emitted per-frame in recordFrame when the total punctual light count\n * exceeds the HDRP budget (256). Fail-soft: fire once per frame, truncate to 256.\n * - `.code = 'hdrp-light-budget-exceeded'` (closed RuntimeErrorCode)\n * - `.expected` — 'light count <= 256'\n * - `.hint` — 'reduce world light count or increase budget (OOS-hdrp-larger-budget)'\n * - `.detail = { actual, budget }`\n */\nexport class HdrpLightBudgetExceededError extends Error {\n readonly code = 'hdrp-light-budget-exceeded' as const;\n readonly expected: string;\n readonly hint: string;\n readonly detail: HdrpLightBudgetExceededDetail;\n\n constructor(actual: number, budget: number) {\n const expected = `light count <= ${budget}`;\n const hint =\n `${actual} lights exceed HDRP budget ${budget}; ` +\n 'truncating to 256. Reduce light count or wait for OOS-hdrp-larger-budget';\n super(`HDRP light budget exceeded: ${actual} > ${budget}`);\n this.name = 'HdrpLightBudgetExceededError';\n this.expected = expected;\n this.hint = hint;\n this.detail = { actual, budget };\n }\n}\n\n// ── HdrpIndexListOverflowError ─────────────────────────────────────────────\n\n/**\n * Detail for `RuntimeErrorCode 'hdrp-index-list-overflow'`.\n *\n * Emitted per-frame (once-per-frame fire) when the cluster binner overflows\n * the light index list capacity (65536). Upgraded from ClusterBinError.\n */\nexport interface HdrpIndexListOverflowDetail {\n readonly actual: number;\n readonly capacity: number;\n}\n\n/**\n * Structured error for HDRP cluster binner index list overflow (AC-24).\n *\n * Emitted per-frame in recordFrame when the CPU binner returns\n * `ClusterBinError('index-overflow')`. Fail-soft: fire once per frame,\n * continue rendering with what fit.\n * - `.code = 'hdrp-index-list-overflow'` (closed RuntimeErrorCode)\n * - `.expected` — 'light index list entries <= 65536'\n * - `.hint` — 'reduce lights, shrink cluster grid, or increase capacity'\n * - `.detail = { actual, capacity }`\n */\nexport class HdrpIndexListOverflowError extends Error {\n readonly code = 'hdrp-index-list-overflow' as const;\n readonly expected: string;\n readonly hint: string;\n readonly detail: HdrpIndexListOverflowDetail;\n\n constructor(actual: number, capacity: number) {\n const expected = `light index list entries <= ${capacity}`;\n const hint =\n `cluster binner overflow: writeCount ${actual} exceeds capacity ${capacity}; ` +\n 'reduce lights, shrink cluster grid, or increase LIGHT_INDEX_LIST_CAPACITY';\n super(`HDRP index list overflow: ${actual} > ${capacity}`);\n this.name = 'HdrpIndexListOverflowError';\n this.expected = expected;\n this.hint = hint;\n this.detail = { actual, capacity };\n }\n}\n\n// ── HdrpDeferredCapsInsufficientError ──────────────────────────────────────\n\n/**\n * Detail for `RuntimeErrorCode 'hdrp-deferred-caps-insufficient'`.\n *\n * Emitted at `installPipeline(hdrpAsset)` time when `device.caps.maxColorAttachments < 4`,\n * meaning the deferred path cannot allocate 3 g-buffer color targets + depth.\n */\nexport interface HdrpDeferredCapsInsufficientDetail {\n readonly actual: number;\n readonly expected: number;\n}\n\n/**\n * Structured error for deferred-path capability gate failure.\n *\n * Emitted at `installPipeline(hdrpAsset)` time — synchronous throw.\n * - `.code = 'hdrp-deferred-caps-insufficient'` (closed RuntimeErrorCode)\n * - `.expected` — 'maxColorAttachments >= 4'\n * - `.hint` — actionable guidance to upgrade browser or select URP\n * - `.detail = { actual, expected }`\n *\n * @see plan-strategy D-5 (install-time caps check, no silent fallback)\n */\nexport class HdrpDeferredCapsInsufficientError extends Error {\n readonly code = 'hdrp-deferred-caps-insufficient' as const;\n readonly expected: string;\n readonly hint: string;\n readonly detail: HdrpDeferredCapsInsufficientDetail;\n\n constructor(actual: number) {\n const _expected = 4;\n const _expectedStr = `maxColorAttachments >= ${_expected}`;\n const hint =\n `WebGPU maxColorAttachments = ${actual} (need >= ${_expected}). ` +\n 'Upgrade browser to latest Chrome/Edge/Safari, or use URP (forgeax::urp) instead of HDRP.';\n super(\n `HDRP deferred caps insufficient: maxColorAttachments = ${actual} (need >= ${_expected})`,\n );\n this.name = 'HdrpDeferredCapsInsufficientError';\n this.expected = _expectedStr;\n this.hint = hint;\n this.detail = { actual, expected: _expected };\n }\n}\n\n// ── GbufferRtAllocFailedError ──────────────────────────────────────────────\n\n/**\n * Detail for `RuntimeErrorCode 'gbuffer-rt-alloc-failed'`.\n *\n * Emitted at runtime when a g-buffer color target pool allocation fails\n * (OOM or backend resource limit). The attachmentIndex identifies which\n * g-buffer slot failed.\n */\nexport interface GbufferRtAllocFailedDetail {\n readonly attachmentIndex: number;\n readonly requestedBytes: number;\n}\n\n/**\n * Structured error for g-buffer color-target pool allocation failure.\n *\n * Emitted at runtime during g-buffer pass setup.\n * - `.code = 'gbuffer-rt-alloc-failed'` (closed RuntimeErrorCode)\n * - `.expected` — 'g-buffer color target allocation succeeded'\n * - `.hint` — actionable recovery steps (check GPU memory / reduce resolution)\n * - `.detail = { attachmentIndex, requestedBytes }`\n *\n * @note This error is declared in M1 but only triggered in M2 (g-buffer RT\n * allocation path). The union member exists for compile-time narrowing now.\n */\nexport class GbufferRtAllocFailedError extends Error {\n readonly code = 'gbuffer-rt-alloc-failed' as const;\n readonly expected: string;\n readonly hint: string;\n readonly detail: GbufferRtAllocFailedDetail;\n\n constructor(attachmentIndex: number, requestedBytes: number) {\n const expected = 'g-buffer color target allocation succeeded';\n const hint =\n `g-buffer color target (attachment ${attachmentIndex}, ${requestedBytes} bytes) allocation failed. ` +\n 'Common causes: (a) GPU memory pressure; (b) framebuffer resolution too large; ' +\n '(c) RHI backend limits hit. Check device.limits and reduce frame resolution.';\n super(`g-buffer RT alloc failed: attachment[${attachmentIndex}] = ${requestedBytes} bytes`);\n this.name = 'GbufferRtAllocFailedError';\n this.expected = expected;\n this.hint = hint;\n this.detail = { attachmentIndex, requestedBytes };\n }\n}\n\n// ── GbufferAttachmentCountMismatchError ────────────────────────────────────\n\n/**\n * Detail for `RuntimeErrorCode 'gbuffer-attachment-count-mismatch'`.\n *\n * Emitted at install-time when the g-buffer attachment count declared\n * in the pipeline schema does not equal 3.\n */\nexport interface GbufferAttachmentCountMismatchDetail {\n readonly actual: number;\n readonly expected: number;\n}\n\n/**\n * Structured error for g-buffer attachment count mismatch.\n *\n * Emitted at `installPipeline(hdrpAsset)` time via topology validation.\n * - `.code = 'gbuffer-attachment-count-mismatch'` (closed RuntimeErrorCode)\n * - `.expected` — 'exactly 3 g-buffer color attachments'\n * - `.hint` — check pipeline internal schema or custom g-buffer override\n * - `.detail = { actual, expected }`\n *\n * @note This error is declared in M1 but only triggered in M2 (g-buffer\n * topology validation). The union member exists for compile-time narrowing now.\n */\nexport class GbufferAttachmentCountMismatchError extends Error {\n readonly code = 'gbuffer-attachment-count-mismatch' as const;\n readonly expected: string;\n readonly hint: string;\n readonly detail: GbufferAttachmentCountMismatchDetail;\n\n constructor(actual: number) {\n const _expected = 3;\n const _expectedStr = `exactly ${_expected} g-buffer color attachments`;\n const hint =\n `HDRP deferred expects ${_expected} g-buffer color attachments, got ${actual}. ` +\n 'Check hdrp-pipeline internal schema or custom g-buffer override.';\n super(`g-buffer attachment count mismatch: got ${actual}, expected ${_expected}`);\n this.name = 'GbufferAttachmentCountMismatchError';\n this.expected = _expectedStr;\n this.hint = hint;\n this.detail = { actual, expected: _expected };\n }\n}\n\n// ── PointShadowAtlasUninitializedError ─────────────────────────────────────\n\n/**\n * Structured error for `ShadowAtlas.faceView` called before `ensure()`\n * allocated the cube_array texture. Replaces the prior bare\n * `throw new Error()` (Round-2 F-4: P3 closed-union compliance).\n *\n * - `.code = 'point-shadow-atlas-uninitialized'`\n * - `.expected` — call `ensure()` before iterating face views\n * - `.hint` — gate `faceView` on `isAllocated()` or call `ensure()` once\n * in the per-frame extract step before recording the 6 x N caster passes\n * - `.detail = undefined` (no per-call data needed)\n */\nexport class PointShadowAtlasUninitializedError extends Error {\n readonly code = 'point-shadow-atlas-uninitialized' as const;\n readonly expected: string;\n readonly hint: string;\n\n constructor() {\n const expected = 'ShadowAtlas.ensure() invoked before faceView()';\n const hint =\n 'Gate faceView on isAllocated() or call ensure() once in the per-frame extract step before iterating face views';\n super('ShadowAtlas.faceView called before ensure(); the cube_array texture is not allocated');\n this.name = 'PointShadowAtlasUninitializedError';\n this.expected = expected;\n this.hint = hint;\n }\n}\n\n// ── PointShadowAtlasBoundsViolationError ───────────────────────────────────\n\n/**\n * Detail for `RuntimeErrorCode 'point-shadow-atlas-bounds-violation'`.\n *\n * Emitted by `ShadowAtlas.faceView` when `layer` falls outside `[0, layers)`\n * or `face` falls outside `[0, 6)`. Both axes are reported as\n * `{ axis, value, max }` so AI users discriminate without parsing the message.\n */\nexport interface PointShadowAtlasBoundsViolationDetail {\n readonly axis: 'layer' | 'face';\n readonly value: number;\n readonly max: number;\n}\n\n/**\n * Structured error for `ShadowAtlas.faceView(layer, face)` arguments outside\n * the allocated atlas range. Replaces the prior bare `throw new Error()`\n * (Round-2 F-4: P3 closed-union compliance).\n *\n * - `.code = 'point-shadow-atlas-bounds-violation'`\n * - `.expected` — `0 <= layer < layers && 0 <= face < 6`\n * - `.hint` — clamp `shadowAtlasLayer` or face index before calling\n * `faceView`; the cap on layers is `PointLightShadow` cardinality (4)\n * - `.detail = { axis, value, max }` — discriminates layer vs face\n */\nexport class PointShadowAtlasBoundsViolationError extends Error {\n readonly code = 'point-shadow-atlas-bounds-violation' as const;\n readonly expected: string;\n readonly hint: string;\n readonly detail: PointShadowAtlasBoundsViolationDetail;\n\n constructor(axis: 'layer' | 'face', value: number, max: number) {\n const expected = `0 <= ${axis} < ${max}`;\n const hint =\n axis === 'layer'\n ? `clamp PointLight.shadowAtlasLayer to [0, ${max}); the cap on layers equals PointLightShadow cardinality (4)`\n : `clamp face index to [0, ${max}); cube faces are indexed 0..5 in +X/-X/+Y/-Y/+Z/-Z order`;\n super(`ShadowAtlas.faceView ${axis} out of range: ${value} (must be in [0, ${max}))`);\n this.name = 'PointShadowAtlasBoundsViolationError';\n this.expected = expected;\n this.hint = hint;\n this.detail = { axis, value, max };\n }\n}\n\n// ── VideoUploadUnsupportedError ─────────────────────────────────────────\n\n/**\n * Structured error for `RuntimeErrorCode 'video-upload-unsupported'`\n * (feat-20260623-world-space-video-asset M3 / w11 — AC-10).\n *\n * Fired by the per-frame record stage (`videoTextureView`) when a VideoPlayer\n * entity can reach neither video upload path this frame: the general\n * `copyExternalImageToTexture` path (no host HTMLVideoElement resolved via\n * `VideoElementProvider`) AND the high-perf `GPUExternalTexture` path\n * (capability absent). The engine surfaces this explicit failure rather than\n * silently rendering a stale/garbage texture (charter P3, plan-strategy D-6).\n * - `.code = 'video-upload-unsupported'`\n * - `.expected` — at least one upload path available (host element or\n * GPUExternalTexture capability)\n * - `.hint` — actionable recovery: use a static texture or switch backend\n * - `.detail` — undefined (no narrowed detail variant)\n */\nexport class VideoUploadUnsupportedError extends Error {\n readonly code = 'video-upload-unsupported' as const;\n readonly expected: string;\n readonly hint: string;\n\n constructor() {\n const expected =\n 'at least one video upload path available: a host HTMLVideoElement (general copyExternalImageToTexture path) or GPUExternalTexture capability (high-perf path)';\n const hint =\n 'this backend exposes no usable video upload path; render a static texture instead, or switch to a WebGPU backend that supports video texture upload';\n super('video upload unsupported — no general or high-perf path available');\n this.name = 'VideoUploadUnsupportedError';\n this.expected = expected;\n this.hint = hint;\n }\n}\n\n// ── VertexStorageBufferUnavailableError ─────────────────────────────────\n\n/**\n * Structured error for missing vertex-stage storage buffer capability.\n *\n * Emitted at createRenderer time (cap-gate).\n * - `.code = 'vertex-storage-buffer-unavailable'`\n * - `.expected` — device.caps supports vertex-stage storage buffer\n * - `.hint` — switch to a WebGPU adapter with vertex storage buffer support or use uniform-buffer fallback (OOS-uniform-palette)\n * - `.detail` — undefined (no narrowed detail variant)\n */\nexport class VertexStorageBufferUnavailableError extends Error {\n readonly code = 'vertex-storage-buffer-unavailable' as const;\n readonly expected: string;\n readonly hint: string;\n\n constructor() {\n const expected =\n 'device.caps supports vertex-stage storage buffer (maxStorageBuffersPerShaderStage >= 1)';\n const hint =\n 'this device does not support vertex-stage storage buffers; skinning requires vertex-stage storage buffer access (OOS-uniform-palette fallback not implemented)';\n super('vertex-stage storage buffer unavailable — skinning cannot operate');\n this.name = 'VertexStorageBufferUnavailableError';\n this.expected = expected;\n this.hint = hint;\n }\n}\n\n// ── Skin palette/material validation errors ────────────────────────────────\n\n/** Detail for a palette buffer that exceeds the device storage limit. */\nexport interface SkinPaletteOverflowDetail {\n readonly requestedBytes: number;\n readonly limit: number;\n}\n\n/**\n * Structured render error for a skin palette allocation that exceeds the\n * device storage-buffer binding limit. The allocator that emits this error\n * lives in render, so the error belongs to the render union rather than the\n * renderer-independent skinning binding package.\n */\nexport class SkinPaletteOverflowError extends Error {\n readonly code = 'skin-palette-overflow' as const;\n readonly expected: string;\n readonly hint: string;\n readonly detail: SkinPaletteOverflowDetail;\n\n constructor(requestedBytes: number, limit: number) {\n const expected = `skinned joint palette (${requestedBytes} B) fits within device.limits.maxStorageBufferBindingSize (${limit} B)`;\n const hint =\n 'palette buffer exceeds device maxStorageBufferBindingSize; reduce skinned entity count or split into multiple palette buffers (OOS-skin-palette-batch)';\n super(`skin palette buffer needs ${requestedBytes} B, exceeds device limit ${limit} B`);\n this.name = 'SkinPaletteOverflowError';\n this.expected = expected;\n this.hint = hint;\n this.detail = { requestedBytes, limit };\n }\n}\n\n/** Detail for a skinned entity using a non-skin material shader. */\nexport interface SkinMaterialMismatchDetail {\n readonly entity: number;\n readonly actualShader: string | undefined;\n}\n\n/** Structured render error for a Skin/non-skin-material mismatch. */\nexport class SkinMaterialMismatchError extends Error {\n readonly code = 'skin-material-mismatch' as const;\n readonly expected: string;\n readonly hint: string;\n readonly detail: SkinMaterialMismatchDetail;\n\n constructor(entity: number, actualShader: string | undefined) {\n const expected = \"Skin entity's first material program module === 'forgeax::pbr-skin'\";\n const hint = `entity ${entity} has Skin but the first material program module is ${actualShader ?? '<empty>'}; load the mesh via the gltf importer (cooker auto-routes 'forgeax::pbr-skin' for skinned primitives), or remove the Skin component to render the entity unskinned with Materials.standard / Materials.unlit`;\n super(\n `Skin / material mismatch on entity ${entity}: expected forgeax::pbr-skin, got ${actualShader ?? '<empty>'}`,\n );\n this.name = 'SkinMaterialMismatchError';\n this.expected = expected;\n this.hint = hint;\n this.detail = { entity, actualShader };\n }\n}\n\n/** Detail for a pbr-skin material whose mesh lacks skin attributes. */\nexport interface MaterialSkinAttrMissingDetail {\n readonly entity: number;\n readonly missing: 'skinIndex' | 'skinWeight' | 'both';\n}\n\n/** Structured render error for a pbr-skin material/mesh attribute mismatch. */\nexport class MaterialSkinAttrMissingError extends Error {\n readonly code = 'material-skin-attr-missing' as const;\n readonly expected: string;\n readonly hint: string;\n readonly detail: MaterialSkinAttrMissingDetail;\n\n constructor(entity: number, missing: 'skinIndex' | 'skinWeight' | 'both') {\n const expected = 'pbr-skin material requires mesh.attributes.skinIndex + skinWeight';\n const hint = `entity ${entity} uses forgeax::pbr-skin but its MeshAsset is missing ${missing}; switch the entity to a skinned glTF mesh authored with JOINTS_0 + WEIGHTS_0, or change the material to a non-skin shader via Materials.standard / Materials.unlit`;\n super(\n `material/skin attribute mismatch on entity ${entity}: pbr-skin material with mesh missing ${missing}`,\n );\n this.name = 'MaterialSkinAttrMissingError';\n this.expected = expected;\n this.hint = hint;\n this.detail = { entity, missing };\n }\n}\n\n// -- RenderFeature errors ---------------------------------------------------\n\nconst renderFeatureRecoveryHintByRecovery = {\n 'next-frame': (featureIdentity: string, stage: RenderFeatureStage) =>\n `correct '${featureIdentity}' ${stage} data and retry on the next frame`,\n 'renderer-recover': (featureIdentity: string, _stage: RenderFeatureStage) =>\n `wait for renderer recovery before retrying '${featureIdentity}'`,\n registration: (featureIdentity: string, _stage: RenderFeatureStage) =>\n `correct '${featureIdentity}' registration before retrying`,\n} satisfies Record<\n RenderFeatureRecovery,\n (featureIdentity: string, stage: RenderFeatureStage) => string\n>;\n\nexport class RenderFeatureRegistrationConflictError extends Error {\n readonly code = 'render-feature-registration-conflict' as const;\n readonly expected: string;\n readonly hint: string;\n readonly detail: RenderFeatureRegistrationConflictDetail;\n\n constructor(featureIdentity: string, order: number, conflictingOrder: number) {\n const expected = `feature identity '${featureIdentity}' is unique`;\n const hint = `rename '${featureIdentity}' or remove the duplicate feature before registration`;\n super(`render feature registration conflict for '${featureIdentity}'`);\n this.name = 'RenderFeatureRegistrationConflictError';\n this.expected = expected;\n this.hint = hint;\n this.detail = { featureIdentity, order, conflictingOrder };\n }\n}\n\nexport class RenderFeatureStageFailedError extends Error {\n readonly code = 'render-feature-stage-failed' as const;\n readonly expected: string;\n readonly hint: string;\n readonly detail: RenderFeatureStageFailedDetail;\n\n constructor(\n featureIdentity: string,\n order: number,\n stage: RenderFeatureStage,\n recovery: RenderFeatureRecovery,\n ) {\n const expected = `feature '${featureIdentity}' completes its ${stage} stage without an error`;\n const hint = renderFeatureRecoveryHintByRecovery[recovery](featureIdentity, stage);\n super(`render feature '${featureIdentity}' failed during ${stage}`);\n this.name = 'RenderFeatureStageFailedError';\n this.expected = expected;\n this.hint = hint;\n this.detail = { featureIdentity, order, stage, recovery };\n }\n}\n\nexport class RenderFeatureCapabilityMissingError extends Error {\n readonly code = 'render-feature-capability-missing' as const;\n readonly expected: string;\n readonly hint: string;\n readonly detail: RenderFeatureCapabilityMissingDetail;\n\n constructor(\n featureIdentity: string,\n order: number,\n capability: RenderFeatureCapabilityMissingDetail['capability'],\n ) {\n const expected = `device capability '${capability}' is available for feature '${featureIdentity}'`;\n const hint = `disable '${featureIdentity}' or use a device with '${capability}' capability`;\n super(`render feature '${featureIdentity}' requires missing capability '${capability}'`);\n this.name = 'RenderFeatureCapabilityMissingError';\n this.expected = expected;\n this.hint = hint;\n this.detail = { featureIdentity, order, capability };\n }\n}\n\nexport class RenderFeaturePassOrderConflictError extends Error {\n readonly code = 'render-feature-pass-order-conflict' as const;\n readonly expected: string;\n readonly hint: string;\n readonly detail: RenderFeaturePassOrderConflictDetail;\n\n constructor(\n featureIdentity: string,\n order: number,\n passIdentity: string,\n dependencyIdentity: string,\n ) {\n const expected = `feature pass '${passIdentity}' follows dependency '${dependencyIdentity}'`;\n const hint = `reorder '${featureIdentity}' passes so '${passIdentity}' follows '${dependencyIdentity}'`;\n super(`render feature '${featureIdentity}' pass order conflict`);\n this.name = 'RenderFeaturePassOrderConflictError';\n this.expected = expected;\n this.hint = hint;\n this.detail = { featureIdentity, order, passIdentity, dependencyIdentity };\n }\n}\n\nexport class RenderFeaturePreparationFailedError extends Error {\n readonly code = 'render-feature-preparation-failed' as const;\n readonly expected: string;\n readonly hint: string;\n readonly detail: RenderFeaturePreparationFailedDetail;\n\n constructor(\n featureIdentity: string,\n order: number,\n operation: string,\n resourceKind: RenderFeaturePreparationFailedDetail['resourceKind'],\n resourceName: string,\n reason: string,\n recovery: RenderFeatureRecovery,\n ) {\n const expected = `${resourceKind} '${resourceName}' is prepared during ${operation}`;\n const hint = `repair '${resourceName}' and retry feature '${featureIdentity}' on ${recovery}`;\n super(`render feature '${featureIdentity}' preparation failed for '${resourceName}'`);\n this.name = 'RenderFeaturePreparationFailedError';\n this.expected = expected;\n this.hint = hint;\n this.detail = {\n featureIdentity,\n order,\n stage: 'prepare',\n operation,\n resourceKind,\n resourceName,\n reason,\n recovery,\n };\n }\n}\n\nexport class RenderFeaturePreparedStateMismatchError extends Error {\n readonly code = 'render-feature-prepared-state-mismatch' as const;\n readonly expected: string;\n readonly hint: string;\n readonly detail: RenderFeaturePreparedStateMismatchDetail;\n\n constructor(detail: RenderFeaturePreparedStateMismatchDetail) {\n const expected = `${detail.resourceKind} state is compatible for '${detail.operation}'`;\n const hint = `repair '${detail.reason}' for feature '${detail.featureIdentity}' and retry`;\n super(`render feature '${detail.featureIdentity}' prepared state mismatch`);\n this.name = 'RenderFeaturePreparedStateMismatchError';\n this.expected = expected;\n this.hint = hint;\n this.detail = detail;\n }\n}\n\nexport class RenderFeatureDrawRecordingFailedError extends Error {\n readonly code = 'render-feature-draw-recording-failed' as const;\n readonly expected: string;\n readonly hint: string;\n readonly detail: RenderFeatureDrawRecordingFailedDetail;\n\n constructor(\n featureIdentity: string,\n order: number,\n operation: string,\n resourceKind: RenderFeatureDrawRecordingFailedDetail['resourceKind'],\n reason: string,\n backendReason: string,\n recovery: RenderFeatureRecovery,\n ) {\n const expected = `${resourceKind} recording succeeds for '${operation}'`;\n const hint = `repair '${reason}' and retry feature '${featureIdentity}' after ${recovery}`;\n super(`render feature '${featureIdentity}' draw recording failed`);\n this.name = 'RenderFeatureDrawRecordingFailedError';\n this.expected = expected;\n this.hint = hint;\n this.detail = {\n featureIdentity,\n order,\n stage: 'record',\n operation,\n resourceKind,\n reason,\n backendReason,\n recovery,\n };\n }\n}\n\n// ── ObservationUnavailableError ───────────────────────────────────────────\n\nexport type ObservationUnavailableReason =\n | 'no-frame'\n | 'resource'\n | 'copy-src'\n | 'stale'\n | 'identity'\n | 'format'\n | 'readback-failed';\n\nexport interface ObservationUnavailableDetail {\n readonly reason: ObservationUnavailableReason;\n readonly recovery: 'draw-current-frame' | 'enable-copy-src' | 'retry-readback';\n}\n\n/** A producer-owned current-frame observation could not be made available. */\nexport class ObservationUnavailableError extends Error {\n readonly code = 'observation-unavailable' as const;\n readonly expected: string;\n readonly hint: string;\n readonly detail: ObservationUnavailableDetail;\n\n constructor(reason: ObservationUnavailableReason, hint: string) {\n let recovery: ObservationUnavailableDetail['recovery'];\n if (reason === 'copy-src') recovery = 'enable-copy-src';\n else if (reason === 'resource' || reason === 'readback-failed') recovery = 'retry-readback';\n else recovery = 'draw-current-frame';\n super(`current-frame observation unavailable: ${reason}`);\n this.name = 'ObservationUnavailableError';\n this.expected = 'a fresh producer-owned rgba16float current-frame observation';\n this.hint = hint;\n this.detail = { reason, recovery };\n }\n}\n\nexport interface TaaCapsInsufficientDetail {\n readonly rgba16floatRenderable: boolean;\n readonly maxColorAttachments: number;\n readonly recovery: 'enable-temporal-capabilities';\n}\n\n/** The active device cannot support the renderer-owned temporal attachments. */\nexport class TaaCapsInsufficientError extends Error {\n readonly code = 'taa-caps-insufficient' as const;\n readonly expected = 'rgba16floatRenderable and maxColorAttachments >= 2';\n readonly hint =\n 'select a device with rgba16float render targets and at least two color attachments, then rebuild the renderer';\n readonly detail: TaaCapsInsufficientDetail;\n\n constructor(rgba16floatRenderable: boolean, maxColorAttachments: number) {\n super(\n `TAA capabilities insufficient: rgba16floatRenderable=${rgba16floatRenderable}, maxColorAttachments=${maxColorAttachments}`,\n );\n this.name = 'TaaCapsInsufficientError';\n this.detail = {\n rgba16floatRenderable,\n maxColorAttachments,\n recovery: 'enable-temporal-capabilities',\n };\n }\n}\n\nexport type TemporalUnsupportedReason =\n | 'resolve-count'\n | 'scene-color-domain'\n | 'scene-color-sample-count'\n | 'scene-depth-sample-count'\n | 'temporal-attachment-missing'\n | 'temporal-attachment-format'\n | 'temporal-attachment-sample-count'\n | 'resolve-resources-missing'\n | 'resolve-frame-missing';\n\nexport interface TemporalUnsupportedDetail {\n readonly reason: TemporalUnsupportedReason;\n readonly actual: string;\n readonly recovery: 'fix-temporal-pipeline-topology';\n}\n\n/** A pipeline violated the single renderer-owned temporal resolve seam. */\nexport class TemporalUnsupportedError extends Error {\n readonly code = 'temporal-unsupported' as const;\n readonly expected: string;\n readonly hint =\n 'call resolveTemporal exactly once after temporal raster and pass single-sample rgba16float scene and temporal targets';\n readonly detail: TemporalUnsupportedDetail;\n\n constructor(reason: TemporalUnsupportedReason, expected: string, actual: string) {\n super(`temporal pipeline unsupported: ${reason}; expected ${expected}, got ${actual}`);\n this.name = 'TemporalUnsupportedError';\n this.expected = expected;\n this.detail = { reason, actual, recovery: 'fix-temporal-pipeline-topology' };\n }\n}\n\n// -- Analytic sky authoring/source errors ----------------------------------\n\nexport type AtmosphereField =\n | 'turbidity'\n | 'rayleigh'\n | 'mieCoefficient'\n | 'mieDirectionalG'\n | 'sunAngularRadius';\n\nexport interface AtmosphereParameterInvalidDetail {\n readonly field: AtmosphereField;\n readonly value: number;\n readonly min: number;\n readonly max: number;\n readonly minExclusive: boolean;\n}\n\n/** A finite Atmosphere field is outside its authoring range. */\nexport class AtmosphereParameterInvalidError extends Error {\n readonly code = 'atmosphere-parameter-invalid' as const;\n readonly expected: string;\n readonly hint: string;\n readonly detail: AtmosphereParameterInvalidDetail;\n\n constructor(\n field: AtmosphereField,\n value: number,\n min: number,\n max: number,\n minExclusive = false,\n ) {\n const lower = minExclusive ? `>${min}` : `>=${min}`;\n super(`Atmosphere.${field} must be ${lower} and <=${max}; got ${value}`);\n this.name = 'AtmosphereParameterInvalidError';\n this.expected = `${field} ${lower} and <=${max}`;\n this.hint = `set Atmosphere.${field} to a finite value in the accepted range; got ${value}`;\n this.detail = { field, value, min, max, minExclusive };\n }\n}\n\nexport interface AtmosphereCardinalityInvalidDetail {\n readonly count: number;\n readonly max: 1;\n readonly entities: readonly number[];\n}\n\n/** More than one Atmosphere authoring component exists in one resource World. */\nexport class AtmosphereCardinalityInvalidError extends Error {\n readonly code = 'atmosphere-cardinality-invalid' as const;\n readonly expected = 'exactly one Atmosphere component in the resourceOwner World';\n readonly hint = 'remove extra Atmosphere entities and keep one analytic source';\n readonly detail: AtmosphereCardinalityInvalidDetail;\n\n constructor(count: number, entities: readonly number[]) {\n super(`Atmosphere cardinality exceeded: ${count} entities (max 1)`);\n this.name = 'AtmosphereCardinalityInvalidError';\n this.detail = { count, max: 1, entities: [...entities] };\n }\n}\n\nexport interface AtmosphereSunMissingDetail {\n readonly atmosphereEntity: number;\n}\n\n/** An Atmosphere entity is not a Sun unless its same entity carries DirectionalLight. */\nexport class AtmosphereSunMissingError extends Error {\n readonly code = 'atmosphere-sun-missing' as const;\n readonly expected = 'Atmosphere and DirectionalLight share one entity';\n readonly hint = 'add a valid DirectionalLight to the Atmosphere entity';\n readonly detail: AtmosphereSunMissingDetail;\n\n constructor(atmosphereEntity: number) {\n super(`Atmosphere entity ${atmosphereEntity} has no co-located DirectionalLight`);\n this.name = 'AtmosphereSunMissingError';\n this.detail = { atmosphereEntity };\n }\n}\n\nexport interface EnvironmentSourceConflictDetail {\n readonly atmosphereEntities: readonly number[];\n readonly imageEntities: readonly number[];\n}\n\n/** Image and analytic environment facts cannot silently choose a precedence. */\nexport class EnvironmentSourceConflictError extends Error {\n readonly code = 'environment-source-conflict' as const;\n readonly expected = 'exactly one image or atmosphere environment source';\n readonly hint = 'remove either the image environment or the Atmosphere source';\n readonly detail: EnvironmentSourceConflictDetail;\n\n constructor(atmosphereEntities: readonly number[], imageEntities: readonly number[]) {\n super('image and Atmosphere environment sources cannot coexist');\n this.name = 'EnvironmentSourceConflictError';\n this.detail = {\n atmosphereEntities: [...atmosphereEntities],\n imageEntities: [...imageEntities],\n };\n }\n}\n\nexport interface AtmosphereCapsInsufficientDetail {\n readonly capability: string;\n readonly actual: boolean | number;\n readonly required: boolean | number;\n}\n\n/** The selected device cannot render the required HDR atmosphere resources. */\nexport class AtmosphereCapsInsufficientError extends Error {\n readonly code = 'atmosphere-caps-insufficient' as const;\n readonly expected: string;\n readonly hint = 'select a backend with the required HDR render and sample capabilities';\n readonly detail: AtmosphereCapsInsufficientDetail;\n\n constructor(capability: string, actual: boolean | number, required: boolean | number) {\n super(`Atmosphere capability ${capability} is insufficient: ${actual}; required ${required}`);\n this.name = 'AtmosphereCapsInsufficientError';\n this.expected = `${capability} >= ${required}`;\n this.detail = { capability, actual, required };\n }\n}\n\nexport interface AtmosphereProducerFailedDetail {\n readonly stage: 'build' | 'execute' | 'submit';\n readonly reason: string;\n readonly generation?: number;\n}\n\n/** The candidate atmosphere producer did not complete atomically. */\nexport class AtmosphereProducerFailedError extends Error {\n readonly code = 'atmosphere-producer-failed' as const;\n readonly expected = 'candidate atmosphere generation builds, executes, and submits atomically';\n readonly hint =\n 'retain the last-known-good generation, inspect the stage, and retry after repair';\n readonly detail: AtmosphereProducerFailedDetail;\n\n constructor(stage: AtmosphereProducerFailedDetail['stage'], reason: string, generation?: number) {\n super(`Atmosphere producer ${stage} failed: ${reason}`);\n this.name = 'AtmosphereProducerFailedError';\n this.detail = { stage, reason, ...(generation === undefined ? {} : { generation }) };\n }\n}\n\n/**\n * Render-owned projection of a failed material readiness result.\n *\n * The readiness owner supplies the structured fields; render adds only the\n * stable draw dedupe key. This is a diagnostic fact, not a second error or\n * material registry.\n */\nexport interface MaterialDrawDiagnostic {\n readonly key: string;\n readonly code: MaterialRenderError['error']['code'];\n readonly materialGuid: string;\n readonly specializationKey: string;\n readonly publicationGeneration?: number;\n readonly expected: string;\n readonly actual?: string;\n readonly hint: string;\n readonly retryable: boolean;\n readonly recoveryActions: readonly string[];\n}\n\nexport function materialDrawDiagnostic(error: MaterialRenderError): MaterialDrawDiagnostic {\n const detail = error.error.detail;\n const generation = detail.publicationGeneration;\n return {\n key: `${detail.guid}::${detail.specializationKey}::${generation ?? 'unknown'}`,\n code: error.error.code,\n materialGuid: detail.guid,\n specializationKey: detail.specializationKey,\n ...(generation === undefined ? {} : { publicationGeneration: generation }),\n expected: error.error.expected,\n ...(detail.actual === undefined ? {} : { actual: detail.actual }),\n hint: error.error.hint,\n retryable: error.error.retryable,\n recoveryActions: error.error.recoveryActions,\n };\n}\n\nexport class MeshSsboCeilingReachedError extends Error {\n readonly code = 'mesh-ssbo-ceiling-reached' as const;\n readonly expected: string;\n readonly hint: string;\n readonly detail: {\n readonly requested: number;\n readonly capacity: number;\n readonly ceiling: number;\n };\n\n constructor(requested: number, capacity: number, ceiling: number) {\n super(`mesh SSBO request ${requested} exceeds device ceiling ${ceiling}`);\n this.name = 'MeshSsboCeilingReachedError';\n this.expected = `mesh SSBO capacity remains within ${ceiling} bytes`;\n this.hint = 'reduce per-frame renderable count or split the workload across frames';\n this.detail = { requested, capacity, ceiling };\n }\n}\n\nexport class MeshSsboCapacityExceededError extends Error {\n readonly code = 'mesh-ssbo-capacity-exceeded' as const;\n readonly expected: string;\n readonly hint: string;\n readonly detail: {\n readonly requested: number;\n readonly capacity: number;\n readonly ceiling: number;\n };\n\n constructor(requested: number, capacity: number, ceiling: number) {\n super(`mesh SSBO capacity ${capacity} cannot satisfy request ${requested}`);\n this.name = 'MeshSsboCapacityExceededError';\n this.expected = `mesh SSBO capacity >= ${requested} slots`;\n this.hint = 'reduce per-frame renderable count or split the workload across frames';\n this.detail = { requested, capacity, ceiling };\n }\n}\n\n// -- RenderErrorCode / RenderError closed unions --------------------------------\n\n/**\n * Closed union of render-cluster error codes. AI users perform exhaustive\n * `switch (err.code)` without default; TS guards completeness.\n */\nexport type RenderErrorCode = RenderError['code'];\n\n/**\n * Closed union of the render-cluster structured error classes, each carrying a\n * `RenderErrorCode` discriminant on `.code`.\n */\nexport type RenderError =\n | FogOwnerConflictError\n | FogParametersInvalidError\n | ObservationUnavailableError\n | TaaCapsInsufficientError\n | TemporalUnsupportedError\n | AtmosphereCardinalityInvalidError\n | AtmosphereSunMissingError\n | EnvironmentSourceConflictError\n | AtmosphereParameterInvalidError\n | AtmosphereCapsInsufficientError\n | AtmosphereProducerFailedError\n | ShadowInvalidConfigError\n | EquirectProjectionFailedError\n | HdrpCapsInsufficientError\n | HdrpLightBudgetExceededError\n | HdrpIndexListOverflowError\n | HdrpDeferredCapsInsufficientError\n | GbufferRtAllocFailedError\n | GbufferAttachmentCountMismatchError\n | PointShadowAtlasUninitializedError\n | PointShadowAtlasBoundsViolationError\n | VideoUploadUnsupportedError\n | VertexStorageBufferUnavailableError\n | SkinPaletteOverflowError\n | SkinMaterialMismatchError\n | MaterialSkinAttrMissingError\n | RenderFeatureRegistrationConflictError\n | RenderFeatureStageFailedError\n | RenderFeatureCapabilityMissingError\n | RenderFeaturePassOrderConflictError\n | RenderFeaturePreparationFailedError\n | RenderFeaturePreparedStateMismatchError\n | RenderFeatureDrawRecordingFailedError;\n","import { defineComponent } from '@forgeax/engine-ecs';\nimport { err, ok, type Result } from '@forgeax/engine-types';\nimport { type AtmosphereField, AtmosphereParameterInvalidError } from '../errors/render';\n\n/**\n * Analytic atmosphere medium parameters. Sun direction, color, and\n * illuminance belong to a co-located DirectionalLight, never to this token.\n * The renderer-owned environment selector enforces one Atmosphere source per\n * resource World; ECS component schemas do not carry cardinality policy.\n */\nexport const Atmosphere = defineComponent('Atmosphere', {\n turbidity: { type: 'f32', default: 2 },\n rayleigh: { type: 'f32', default: 1 },\n mieCoefficient: { type: 'f32', default: 0.005 },\n mieDirectionalG: { type: 'f32', default: 0.8 },\n sunAngularRadius: { type: 'f32', default: 0.004675 },\n});\n\nconst ATMOSPHERE_CHECKS: readonly {\n readonly field: AtmosphereField;\n readonly min: number;\n readonly max: number;\n readonly minExclusive?: boolean;\n}[] = [\n { field: 'turbidity', min: 1, max: 20 },\n { field: 'rayleigh', min: 0, max: 4 },\n { field: 'mieCoefficient', min: 0, max: 0.1 },\n { field: 'mieDirectionalG', min: 0, max: 0.999 },\n { field: 'sunAngularRadius', min: 0, max: 0.02, minExclusive: true },\n];\n\n/** Validate Atmosphere payloads at the renderer owner boundary. */\nexport function validateAtmosphereData(\n data: Readonly<Record<string, unknown>>,\n): Result<void, AtmosphereParameterInvalidError> {\n for (const check of ATMOSPHERE_CHECKS) {\n const reflectedDefault = Atmosphere.fields[check.field]?.default;\n const rawValue = data[check.field] ?? reflectedDefault;\n const value = typeof rawValue === 'number' ? rawValue : Number.NaN;\n if (!Number.isFinite(value)) {\n return err(\n new AtmosphereParameterInvalidError(\n check.field,\n value,\n check.min,\n check.max,\n check.minExclusive ?? false,\n ),\n );\n }\n if ((check.minExclusive ? value <= check.min : value < check.min) || value > check.max) {\n return err(\n new AtmosphereParameterInvalidError(\n check.field,\n value,\n check.min,\n check.max,\n check.minExclusive ?? false,\n ),\n );\n }\n }\n return ok(undefined);\n}\n","// @forgeax/engine-render - Camera (projection variant + ortho extension).\n//\n// Schema: 9 f32 columns — perspective quartet (fov + aspect + near + far)\n// + projection discriminator (0 = perspective, 1 = orthographic) + ortho\n// quartet (left + right + bottom + top). The view matrix continues to be\n// derived from the entity's Transform (AC-06 case B fires\n// 'render-system-no-camera' when 0 such entities exist).\n//\n// Projection discriminator:\n// projection === 0 → perspective path; RenderSystem builds\n// mat4.perspective(out, fov, aspect, near, far).\n// WebGPU [0, 1] NDC z; perspective reverse-Z hook is\n// a future spin-off path (plan-strategy §R-7) kept\n// outside M3 scope — the short-name mat4.perspective\n// already writes [0, 1] NDC, matching the ortho branch.\n// projection === 1 → orthographic path; RenderSystem builds\n// mat4.orthographic(out, left, right, bottom, top,\n// near, far) (WebGPU [0, 1] NDC; same z convention).\n//\n// Naming convention: forgeax uses the bare `Camera` name (no `Component`\n// suffix) to follow the unity-style flavor for \"individuating\" component\n// names per plan-strategy 7.2 + D-Q5a user lock.\n//\n// Related: requirements §AC-16 (Camera Ortho + Box3 / Sphere);\n// plan-strategy §M3 range + §R-7 risk (single perspective camera\n// in hello-room does NOT trigger depth-func conflict; multi-camera\n// mixed perspective + ortho deferred to feat-future-camera-depth-func);\n// plan-tasks.json w9 acceptanceCheck.\n\nimport { defineComponent, type SchemaOf, type ShapeOf } from '@forgeax/engine-ecs';\nimport { TONEMAP_SHADER_MODE } from '@forgeax/engine-shader';\n\n/**\n * Projection discriminator literal union (AC-16 narrowing surface).\n * Exposed for consumer code that maps `camera.projection` numeric values back\n * to a switch-able string literal (e.g. RenderSystem dispatch / inspector\n * snapshot rendering).\n */\nexport type CameraProjection = 'perspective' | 'orthographic';\n\n/** Numeric encoding of perspective projection (schema value for `projection`). */\nexport const CAMERA_PROJECTION_PERSPECTIVE = 0;\n/** Numeric encoding of orthographic projection (schema value for `projection`). */\nexport const CAMERA_PROJECTION_ORTHOGRAPHIC = 1;\n\n/**\n * Map a `camera.projection` numeric value to the closed `CameraProjection`\n * string-literal union. Values other than 0 / 1 fall back to `'perspective'`\n * (defensive for defaulted / uninitialised entities; charter proposition 4\n * no silent exception).\n */\nexport function cameraProjectionFromF32(value: number): CameraProjection {\n return value === CAMERA_PROJECTION_ORTHOGRAPHIC ? 'orthographic' : 'perspective';\n}\n\n/**\n * Tone-mapping mode discriminator literal union (AC-01 narrowing surface;\n * feat-20260519-tonemap-reinhard-mvp / M1).\n *\n * Two members for the MVP:\n * `'none'` - default; render-target stays `bgra8unorm-srgb`\n * and the geometry pass writes directly to the\n * swap-chain (zero-overhead opt-out path).\n * `'reinhard-extended'` - Forgeax Reinhard 2002 extended (luminance-domain)\n * opt-in;\n * `'reinhard'` - Three r184 per-channel Reinhard opt-in;\n * geometry pass routes through an `rgba16float`\n * HDR target and a fullscreen tonemap pass\n * (`packages/shader/src/tonemap.wgsl`).\n *\n * The remaining members mirror the Three r184 public names and formulas.\n */\nexport type Tonemap =\n | 'none'\n | 'reinhard-extended'\n | 'reinhard'\n | 'linear'\n | 'cineon'\n | 'aces-filmic'\n | 'agx'\n | 'neutral';\n\n/** Numeric encoding of the no-op tonemap path (schema value for `tonemap`). */\nexport const TONEMAP_NONE = TONEMAP_SHADER_MODE.none;\n/**\n * Numeric encoding of the Reinhard-extended tonemap path\n * (schema value for `tonemap`).\n */\nexport const TONEMAP_REINHARD_EXTENDED = TONEMAP_SHADER_MODE.reinhardExtended;\n/** Numeric encoding of the Three r184 per-channel Reinhard path. */\nexport const TONEMAP_REINHARD = TONEMAP_SHADER_MODE.reinhard;\n/** Numeric encoding of the linear (identity after exposure) tonemap path. */\nexport const TONEMAP_LINEAR = TONEMAP_SHADER_MODE.linear;\n/** Numeric encoding of the Cineon (Kodak log) tonemap path. */\nexport const TONEMAP_CINEON = TONEMAP_SHADER_MODE.cineon;\n/** Numeric encoding of the ACES filmic (Narkowicz 2015) tonemap path. */\nexport const TONEMAP_ACES_FILMIC = TONEMAP_SHADER_MODE.acesFilmic;\n/** Numeric encoding of the AgX (Troy Sobotka / Blender 3.x) tonemap path. */\nexport const TONEMAP_AGX = TONEMAP_SHADER_MODE.agx;\n/** Numeric encoding of the Khronos PBR neutral tonemap path. */\nexport const TONEMAP_NEUTRAL = TONEMAP_SHADER_MODE.neutral;\n\n/**\n * Map a `camera.tonemap` numeric value to the closed `Tonemap` string-literal\n * union. Unknown values fall back to `'none'` for defensive schema decoding.\n */\nexport function tonemapFromF32(value: number): Tonemap {\n switch (value) {\n case TONEMAP_REINHARD_EXTENDED:\n return 'reinhard-extended';\n case TONEMAP_REINHARD:\n return 'reinhard';\n case TONEMAP_LINEAR:\n return 'linear';\n case TONEMAP_CINEON:\n return 'cineon';\n case TONEMAP_ACES_FILMIC:\n return 'aces-filmic';\n case TONEMAP_AGX:\n return 'agx';\n case TONEMAP_NEUTRAL:\n return 'neutral';\n default:\n return 'none';\n }\n}\n\n/**\n * Inverse of {@link tonemapFromF32}: map the closed `Tonemap` string-literal\n * union to the u32 mode the tonemap WGSL `params.mode` switch reads. SSOT for\n * the mode encoding shared by the extract-stage built-in tonemap provider\n * (feat-20260621 M-A3 / w13: `Camera.tonemap` -> `forgeax::tonemap` 16B data)\n * and any other consumer. `'none'` maps to 0 (the tonemap pass never dispatches\n * on the LDR path, so 0 is only ever a placeholder).\n */\nexport function tonemapToU32(mode: Tonemap): number {\n switch (mode) {\n case 'reinhard-extended':\n return TONEMAP_REINHARD_EXTENDED;\n case 'reinhard':\n return TONEMAP_REINHARD;\n case 'linear':\n return TONEMAP_LINEAR;\n case 'cineon':\n return TONEMAP_CINEON;\n case 'aces-filmic':\n return TONEMAP_ACES_FILMIC;\n case 'agx':\n return TONEMAP_AGX;\n case 'neutral':\n return TONEMAP_NEUTRAL;\n case 'none':\n return TONEMAP_NONE;\n }\n throw new RangeError(`Invalid tonemap mode: ${String(mode)}.`);\n}\n\n/**\n * Anti-alias mode discriminator literal union\n * (feat-20260528-fxaa-post-processing / w2;\n * feat-20260604-learn-render-4-10-anti-aliasing-msaa adds `'msaa'`).\n *\n * Four members:\n * `'none'` - default; no anti-aliasing (zero-overhead opt-out path)\n * `'fxaa'` - FXAA 3.11 fullscreen post-processing pass (screen-space, shading-aliasing)\n * `'msaa'` - 4x hardware multi-sample anti-aliasing (geometry-edge coverage).\n * Active on both HDR and LDR-swap-chain paths, so a default Camera\n * (`tonemap='none'`) with `antialias='msaa'` is NOT a silent no-op.\n * `'taa'` - temporal anti-aliasing; renderer temporal projection owns its\n * jitter and successful-submit history contract.\n *\n * MSAA and FXAA are orthogonal: MSAA resolves geometry-edge aliasing, FXAA\n * resolves shading/high-frequency aliasing. TAA is mutually exclusive with both.\n */\nexport type Antialias = 'none' | 'fxaa' | 'msaa' | 'taa';\n\n/** Numeric encoding of anti-alias disabled (schema value for `antialias`). */\nexport const ANTIALIAS_NONE = 0;\n/** Numeric encoding of FXAA anti-aliasing (schema value for `antialias`). */\nexport const ANTIALIAS_FXAA = 1;\n/** Numeric encoding of MSAA multi-sample anti-aliasing (schema value for `antialias`). */\nexport const ANTIALIAS_MSAA = 2;\n/** Numeric encoding of temporal anti-aliasing (schema value for `antialias`). */\nexport const ANTIALIAS_TAA = 3;\n\n/**\n * Map a `camera.antialias` numeric value to the closed `Antialias`\n * string-literal union. Invalid values fail-fast with structured error (charter P3).\n */\nexport function antialiasFromF32(value: number): Antialias {\n if (value === ANTIALIAS_NONE) return 'none';\n if (value === ANTIALIAS_FXAA) return 'fxaa';\n if (value === ANTIALIAS_MSAA) return 'msaa';\n if (value === ANTIALIAS_TAA) return 'taa';\n throw new RangeError(\n `Invalid antialias value: ${value}. Expected ${ANTIALIAS_NONE} (none), ${ANTIALIAS_FXAA} (fxaa), ${ANTIALIAS_MSAA} (msaa), or ${ANTIALIAS_TAA} (taa).`,\n );\n}\n\n/**\n * Bloom enabled discriminator literal union\n * (feat-20260531-bloom-first-declarative-render-graph-pass / w2).\n *\n * Two members:\n * `'off'` - default; no bloom post-processing (zero-overhead opt-out path)\n * `'on'` - bloom bright-pass + separable blur + composite pipeline\n *\n * Bloom is a discrete enum (0/1) — illegal values fail-fast with RangeError\n * (charter P3), matching antialiasFromF32 precedent.\n */\nexport type BloomEnabled = 'off' | 'on';\n\n/** Numeric encoding of bloom disabled (schema value for `bloom`). */\nexport const BLOOM_DISABLED = 0;\n/** Numeric encoding of bloom enabled (schema value for `bloom`). */\nexport const BLOOM_ENABLED = 1;\n\n/**\n * Map a `camera.bloom` numeric value to the closed `BloomEnabled` string-literal\n * union. Invalid values fail-fast with structured error (charter P3).\n */\nexport function bloomEnabledFromF32(value: number): BloomEnabled {\n if (value === BLOOM_DISABLED) return 'off';\n if (value === BLOOM_ENABLED) return 'on';\n throw new RangeError(\n `Invalid bloom value: ${value}. Expected ${BLOOM_DISABLED} (off) or ${BLOOM_ENABLED} (on).`,\n );\n}\n\n/**\n * Camera projection parameters (perspective + orthographic variants) +\n * tonemap trio (mode + exposure + whitePoint).\n *\n * Camera transform comes from the entity's `Transform` (AI users\n * spawn camera entities with both components: see example below).\n *\n * Defaults (do not auto-apply; spawn explicitly for the perspective quartet):\n * fov = pi/4 - 45-degree vertical field of view\n * aspect = 16/9 - widescreen aspect (use canvas.width / canvas.height)\n * near = 0.1\n * far = 100\n * projection = 0 - CAMERA_PROJECTION_PERSPECTIVE (layer-2)\n * left = -1, right = 1, bottom = -1, top = 1 (orthographic; layer-2)\n * tonemap = 0 - TONEMAP_NONE (layer-2; opt-in path stays\n * 0-overhead by default)\n * exposure = 1.0 - layer-2 default for the Reinhard-extended path\n * @applicableWhen tonemap === 'reinhard-extended'\n * whitePoint = 4.0 - layer-2 default for the Reinhard-extended path\n * @applicableWhen tonemap === 'reinhard-extended'\n * @minimum 0 (shader floor `max(Y, 1e-5)` keeps\n * the divisor finite even at 0; D-O3)\n * clearColor = [0, 0, 0, 0]\n * - feat-20260709 M3 / D-3: clear-color is one\n * inline `array<f32,4>` column (collapsed from the\n * feat-20260608 clearR/G/B/A quartet). Defaults to\n * transparent black; an explicit alpha remains\n * visible through this public field.\n *\n * MVP supports a single active camera (the first archetype iteration hit;\n * N>1 fires 'render-system-multi-camera' + uses first). Multi-viewport is\n * OOS (see feat-future-multi-viewport). The orthographic path reuses the\n * same near / far as the perspective path — both variants share the single\n * Camera archetype (17 scalar f32 columns + one historyVersion u32 column +\n * the `clearColor` array<f32,4> column + the `autoAspect` bool column).\n *\n * @example Perspective camera at (0, 0, 3) looking down -Z (zero-config tonemap):\n * world.spawn(\n * { component: Transform, data: {\n * pos: [0, 0, 3],\n * quat: [0, 0, 0, 1],\n * scale: [1, 1, 1],\n * } },\n * { component: Camera, data: {\n * fov: Math.PI / 4, aspect: 16 / 9, near: 0.1, far: 100,\n * } },\n * );\n * // tonemap defaults to 0 (TONEMAP_NONE) - 0-overhead path.\n *\n * @example Opt-in Reinhard-extended tonemap (high-intensity HDR scene):\n * world.spawn(\n * { component: Transform, data: { ... } },\n * { component: Camera, data: {\n * fov: Math.PI / 4, aspect: 16 / 9, near: 0.1, far: 100,\n * tonemap: TONEMAP_REINHARD_EXTENDED,\n * exposure: 1.0,\n * whitePoint: 4.0,\n * } },\n * );\n *\n * @example Orthographic camera spanning [-10, 10]^2 on the near plane:\n * world.spawn(\n * { component: Transform, data: {\n * pos: [0, 0, 5],\n * quat: [0, 0, 0, 1],\n * scale: [1, 1, 1],\n * } },\n * { component: Camera, data: {\n * fov: 0, aspect: 1, near: 0.1, far: 100,\n * projection: CAMERA_PROJECTION_ORTHOGRAPHIC,\n * left: -10, right: 10, bottom: -10, top: 10,\n * } },\n * );\n */\nexport const Camera = defineComponent('Camera', {\n fov: { type: 'f32' },\n aspect: { type: 'f32' },\n near: { type: 'f32' },\n far: { type: 'f32' },\n projection: { type: 'f32', default: 0 },\n left: { type: 'f32', default: -1 },\n right: { type: 'f32', default: 1 },\n bottom: { type: 'f32', default: -1 },\n top: { type: 'f32', default: 1 },\n tonemap: { type: 'f32', default: 0 },\n exposure: { type: 'f32', default: 1.0 },\n whitePoint: { type: 'f32', default: 4.0 },\n antialias: { type: 'f32', default: 0 },\n historyVersion: { type: 'u32', default: 0 },\n bloom: { type: 'f32', default: 0 },\n bloomThreshold: { type: 'f32', default: 1.0 },\n bloomIntensity: { type: 'f32', default: 1.0 },\n bloomBlurRadius: { type: 'f32', default: 4.0 },\n // feat-20260709 M3 / D-3: clear-color is one inline `array<f32,4>` column.\n // The earlier 4-scalar form (clearR/G/B/A) was chosen when this was believed\n // to be the only SoA-safe shape; the Transform (pos/quat/scale) and light\n // (direction/color) precedents disprove that -- an `array<f32,N>` IS an\n // inline stride-N SoA column, read on the hot path as `col[i*N+a]` with zero\n // allocation, so collapsing four scalars into one column removes three field\n // names a reader must track without changing the storage layout or read\n // pattern. The default `[0, 0, 0, 0]` is transparent black; explicit alpha\n // stays visible through the same public array field.\n clearColor: { type: 'array<f32, 4>', default: new Float32Array([0, 0, 0, 0]) },\n // feat-20260617-host-engine-contract-and-video-cutscene / M3 / D-4: the\n // aspect-sync sidecar on the createApp(canvas) path writes\n // canvas.width / canvas.height into `aspect` every frame when this flag is\n // true. Reuses the existing `bool` column tier (AnimationPlayer.paused /\n // AudioSource.playing precedent) -- zero ECS infrastructure change. Default\n // true so demos that never touch aspect track the canvas automatically\n // (charter P1 default-is-correct); set false for render-to-texture /\n // split-screen cameras that drive aspect themselves. Read it via\n // world.get (readRow narrows bool -> JS boolean); the query-bundle path\n // returns a raw 0/1 number (the `!== 0` always-true trap).\n autoAspect: { type: 'bool', default: true },\n});\n\n// ─── Camera POD type (derived from Camera token — single source, AC-07) ─────\n//\n// ShapeOf<SchemaOf<typeof Camera>> resolves the 20-field POD from the Camera\n// token's schema, which is itself derived from Camera.fields[k].type (D-A7).\n// This replaces the hand-maintained CameraDataPod interface — the field set\n// lives exclusively in the Camera component definition above.\ntype CameraPod = ShapeOf<SchemaOf<typeof Camera>>;\n\n// ─── Camera factory functions (w13 SSOT refactoring) ─────────────────────\n//\n// Standalone factory functions that return 20-field CameraPod objects\n// matching the Camera component column shape. Not static methods because\n// TypeScript const-namespace merge is not supported, and Object.assign\n// would break the Camera token's reference identity (archetype columns /\n// queries key off the global owner identity associated with the token).\n//\n// Import as:\n// import { Camera, perspective, orthographic } from '@forgeax/engine-render';\n// world.spawn({ component: Camera, data: perspective({ fov: 60, aspect: 4/3 }) });\n//\n// Charter P1 progressive disclosure: Barrel re-exports put perspective\n// / orthographic next to Camera in IDE autocomplete.\n//\n// D-A4 factory retention reason: perspective() / orthographic() carry\n// required/optional parameter semantics that cannot be derived from\n// the schema. perspective requires fov + aspect (no universal default),\n// orthographic requires left/right/bottom/top. The schema/defaults system\n// only records type + optional default value per field — it has no concept\n// of \"this field MUST be supplied by the caller.\" The factories encode\n// that contract at the TypeScript type level, which schema/defaults alone\n// cannot express. Per AC-07, the factories are kept; only the POD type\n// and default literals are derived from the Camera token (SSOT).\n\ninterface CameraPerspectiveOpts {\n fov: number;\n aspect: number;\n near?: number;\n far?: number;\n /**\n * feat-20260617-host-engine-contract-and-video-cutscene / M3: when true\n * (the schema default), the aspect-sync sidecar on the createApp(canvas)\n * path overwrites `aspect` with `canvas.width / canvas.height` every frame.\n * Omit it for the default-correct behaviour; set `false` to opt out (the\n * factory then leaves `aspect` under your control -- render-to-texture,\n * split-screen). Cameras built on the bare `createRenderer` path never\n * receive aspect-sync regardless of this flag.\n */\n autoAspect?: boolean;\n}\n\ninterface CameraOrthographicOpts {\n left: number;\n right: number;\n bottom: number;\n top: number;\n near?: number;\n far?: number;\n}\n\n/**\n * Build a CameraPod base from Camera.fields defaults (per-field SSOT).\n * Fields without a default (fov / aspect / near / far — OOS-5) are left\n * unset; caller fills them from opts or sentinel values.\n */\nfunction cameraPodFromDefaults(): CameraPod {\n const base: Record<string, unknown> = {};\n for (const [key, field] of Object.entries(Camera.fields)) {\n if ('default' in field && field.default !== undefined) {\n base[key] = field.default;\n }\n }\n return base as CameraPod;\n}\n\n/**\n * Convenience factory: perspective CameraData POD.\n *\n * `fov` and `aspect` are required (no sensible universal default).\n * `near` defaults to 0.1, `far` defaults to 100.\n * Orthographic quartet defaults to [-1, 1]x[-1, 1]; tonemap defaults to\n * TONEMAP_NONE (0-overhead path).\n *\n * When `autoAspect` is `true` (the default once shipped in M3), the\n * aspect-sync sidecar on the `createApp(canvas)` path automatically writes\n * `canvas.width / canvas.height` into `Camera.aspect` every frame. Set\n * `autoAspect = false` to opt out (render-to-texture, split-screen).\n * Cameras on the `createRenderer` path do not receive aspect-sync.\n *\n * @see {@link https://github.com/Ubpa/forgeax-engine/blob/main/docs/how-to/2026-06-18-host-engine-contract.md | Host-engine contract SSOT}\n *\n * @example\n * ```ts\n * import { Camera, perspective } from '@forgeax/engine-render';\n * world.spawn(\n * { component: Camera, data: perspective({ fov: Math.PI / 3, aspect: 4 / 3 }) }\n * ).unwrap();\n * ```\n *\n * @example With explicit near/far:\n * ```ts\n * const camData = perspective({ fov: Math.PI / 4, aspect: 16 / 9, near: 0.01, far: 1000 });\n * world.spawn({ component: Camera, data: camData }).unwrap();\n * ```\n *\n * @example With non-default clear color (default is `[0, 0, 0, 0]`).\n * `clearColor` is an inline `array<f32,4>` field on `Camera`; spread the\n * factory then override:\n * ```ts\n * world.spawn({\n * component: Camera,\n * data: { ...perspective({ fov: Math.PI / 3, aspect: 4 / 3 }), clearColor: [0, 1, 0, 1] },\n * }).unwrap();\n * ```\n */\nexport function perspective(opts: CameraPerspectiveOpts): CameraPod {\n return {\n // cameraPodFromDefaults() reads autoAspect's schema default (true), so an\n // omitted opts.autoAspect lands the default-correct value; an explicit\n // false overrides it below (D-4: factory one-step opt-out, charter P1).\n ...cameraPodFromDefaults(),\n fov: opts.fov,\n aspect: opts.aspect,\n near: opts.near ?? 0.1,\n far: opts.far ?? 100,\n projection: CAMERA_PROJECTION_PERSPECTIVE,\n ...(opts.autoAspect !== undefined ? { autoAspect: opts.autoAspect } : {}),\n };\n}\n\n/**\n * Convenience factory: orthographic CameraData POD.\n *\n * All four ortho bounds (`left` / `right` / `bottom` / `top`) are required.\n * `near` defaults to 0.1, `far` defaults to 100.\n * Perspective fields get sentinel defaults (fov=0, aspect=1) for column\n * alignment with the 12-field schema.\n *\n * @example\n * ```ts\n * import { Camera, orthographic } from '@forgeax/engine-render';\n * world.spawn(\n * { component: Camera, data: orthographic({\n * left: -10, right: 10, bottom: -10, top: 10,\n * }) }\n * ).unwrap();\n * ```\n *\n * @example Screen-aligned orthographic for pixel-unit rendering:\n * ```ts\n * const camData = orthographic({ left: 0, right: 800, bottom: 600, top: 0 });\n * world.spawn({ component: Camera, data: camData }).unwrap();\n * ```\n */\nexport function orthographic(opts: CameraOrthographicOpts): CameraPod {\n return {\n ...cameraPodFromDefaults(),\n fov: 0,\n aspect: 1,\n near: opts.near ?? 0.1,\n far: opts.far ?? 100,\n projection: CAMERA_PROJECTION_ORTHOGRAPHIC,\n left: opts.left,\n right: opts.right,\n bottom: opts.bottom,\n top: opts.top,\n };\n}\n","// @forgeax/engine-render - DirectionalLight (directional light parameters\n// with merged shadow config).\n//\n// Schema: direction array<f32,3> + color array<f32,3> + intensity f32 + 1 bool\n// castShadow + 8 f32 shadow columns (feat-20260709 M2: direction/color collapsed\n// from 6 per-axis scalar columns to two inline array<f32,3> columns).\n//\n// Direction (xyz, outgoing) + color (rgb, linear space) + intensity in lux.\n// No Transform dependency (directional lights have no position).\n// The public world-unit convention is 1 world unit = 1 meter. Exposure is a\n// camera output concern and is not folded into this light's intensity.\n//\n// 0 DirectionalLight + standard material -> physically correct black render\n// (charter v2 P3/P4); details: AGENTS.md section Breaking changes 2026-05-18.\n//\n// Naming convention: bare entity name aligned with Bevy ECS conventions\n// (feat-20260513-component-naming-bevy-align). Camera / Transform / etc.\n// follow the same single-semantic-entity rule (charter proposition 5).\n//\n// charter mapping: proposition 1 (single import) + proposition 3 (silent\n// failure -> explicit warning; first-frame warn) + proposition 5 (consistent\n// abstraction: lighting parameters mirror GPU-side pbr.wgsl @group(0) view\n// BG light fields).\n//\n// feat-20260621-merge-directionallightshadow-into-directionallight M1:\n// DirectionalLightShadow's 9 shadow fields are merged into DirectionalLight\n// to collapse the dual-component spawn into a single component (D-6 primary\n// decision). castShadow defaults to true so zero-config spawns get shadows\n// by default; set castShadow=false to opt out. D-6 directional stays\n// first-hit-wins -- no ECS cardinality cap. Renderer allocation policy stays\n// with the shadow atlas owner.\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Directional light (sun-like infinite light source) with merged shadow\n * parameters.\n *\n * `direction` @semantics outgoing — points FROM light source TO surface\n * (opposite of Three.js convention; the shader internally negates this\n * vector to obtain the L vector for BRDF evaluation). `color` is\n * linear-space rgb in [0, 1] per channel and `intensity` is lux. Exposure is\n * applied after lighting by the camera output stage; no hidden light\n * multiplier is applied here.\n *\n * castShadow defaults to true — zero-config spawns cast cascaded shadow maps.\n * Set castShadow: false to opt out (shadow fields are still stored but their\n * validation is skipped).\n *\n * Shadow fields (migrated from DirectionalLightShadow, feat-20260621 M1):\n * cascadeCount ∈ {1,2,3,4} — number of cascades (default 4)\n * splitLambda ∈ [0,1] — PSSM split weight (default 0.75)\n * cascadeBlend ∈ [0,0.5] — blend width between cascades (default 0.2)\n * mapSize >= 1 — shadow map resolution (default 2048)\n * depthBias — shadow acne bias (default 0.005)\n * normalBias — shadow acne normal offset (default 0.05)\n * shadowDistance > 0 — how far shadows reach in front of the camera,\n * in world units (default 200). This is the sole\n * coverage knob: the CSM cascades are PSSM-split\n * across [camera near, shadowDistance] and each\n * cascade's orthographic bounds are fit to the\n * camera frustum slice automatically. The near\n * end is derived from the active camera's near\n * plane (no separate near knob — any value other\n * than the camera near either drops near shadows\n * or wastes cascade-0 resolution).\n * pcfKernelSize odd >= 1 — PCF kernel width (default 3)\n *\n * @example Spawn a single directional light with default shadows:\n * world.spawn({ component: DirectionalLight, data: {\n * direction: [-0.5, -1, -0.3], // [x, y, z]\n * color: [1, 1, 1], // [r, g, b]\n * intensity: 1,\n * } });\n *\n * @example Opt out of shadows:\n * world.spawn({ component: DirectionalLight, data: {\n * direction: [0, -1, 0], // [x, y, z]\n * castShadow: false,\n * } });\n *\n * @example Explicit shadow config (single-component spawn):\n * world.spawn({ component: DirectionalLight, data: {\n * direction: [0.2, -0.98, 0], // [x, y, z]\n * color: [1, 1, 1], intensity: 1, // color is [r, g, b]\n * cascadeCount: 4, splitLambda: 0.75, cascadeBlend: 0.2,\n * mapSize: 2048, shadowDistance: 200,\n * } });\n *\n * @example 0-light scene must use an unlit shader (standard 0 light = physically correct black):\n * const world = new World();\n * // ... spawn cube + camera, no light ...\n * await renderer.ready;\n * renderer.draw(world); // standard material renders black; switch to an unlit shader (Materials.unlit(...)) for an unlit display\n */\nexport const DirectionalLight = defineComponent('DirectionalLight', {\n // direction is the ONLY field with no default (D-5): omitting it lands the\n // array layer-3 all-zero [0,0,0], which the renderer owner rejects -- there is no\n // universal default direction, so \"default is illegal\" forces an explicit\n // non-zero value. color carries an explicit layer-2 default [1,1,1] (white);\n // the array layer-3 fallback is all-zero, so the default MUST be explicit.\n direction: { type: 'array<f32, 3>' },\n color: { type: 'array<f32, 3>', default: new Float32Array([1, 1, 1]) },\n intensity: { type: 'f32', default: 1 },\n // Shadow opt-out gate: defaults to true so zero-config spawns get shadows.\n castShadow: { type: 'bool', default: true },\n // 9 shadow fields migrated from DirectionalLightShadow (feat-20260621 M1).\n cascadeCount: { type: 'f32', default: 4 },\n splitLambda: { type: 'f32', default: 0.75 },\n cascadeBlend: { type: 'f32', default: 0.2 },\n mapSize: { type: 'f32', default: 2048 },\n depthBias: { type: 'f32', default: 0.005 },\n normalBias: { type: 'f32', default: 0.05 },\n // Sole shadow coverage knob (feat replaces nearPlane/farPlane). The PSSM\n // near end derives from the active camera near; shadowDistance is the far\n // reach. Default 200 world units (matches UE-style \"dynamic shadow\n // distance\"; the old farPlane default was 50).\n shadowDistance: { type: 'f32', default: 200 },\n pcfKernelSize: { type: 'f32', default: 3 },\n});\n","// @forgeax/engine-runtime - Skylight (ambient environment light).\n//\n// Schema: 4 fields -- equirect (Handle<EquirectAsset>, u32-stored handle,\n// OPTIONAL) + color (array<f32,3>, default [1,1,1] = white) + intensity (f32,\n// default 1.0) + rotation (quaternion xyzw, default identity). feat-20260709 M2 collapsed colorR/G/B into one inline\n// array<f32,3> column. Naming convention follows the DirectionalLight / PointLight /\n// SpotLight family: no Component suffix (AGENTS.md rule #1).\n//\n// Plan-strategy D-6: Skylight component schema is registered but no\n// independent ECS system is created. All Skylight processing happens inside\n// RenderSystem's extract/record phases.\n//\n// AI user minimum spawn (AC-13, charter P4):\n// world.spawn({ component: Skylight, data: {} }); // instant white ambient\n//\n// A single Skylight activates ambient lighting transparently. The `equirect`\n// field is OPTIONAL: omit it for a constant solid-color ambient that needs NO\n// async GPU precompute -- the engine binds a 1x1 white irradiance cube, so\n// ambient = color * intensity * albedo is live on the very first frame (this\n// is the fix for the downstream \"scene is black until the async IBL cubemap\n// finishes uploading\" gap). Supply an equirect to upgrade to full image-based\n// lighting (diffuse irradiance + specular prefilter); `color` * `intensity`\n// still scales the IBL result, so both are live dynamic dials either way.\n//\n// feat-20260630-equirect-kind-internalized-ibl-declarative-skyligh M3 / w16:\n// the field is `equirect: shared<EquirectAsset>` (the retired\n// `cubemap: shared<CubeTextureAsset>` is gone). AI users declare the equirect\n// source directly; the render-system record arm projects the cubemap + IBL\n// chain internally and lazily (no user upload call) -- there is no\n// uploadCubemapFromEquirect on the public surface.\n//\n// Edge cases handled by w18 / w19:\n// - Multi-Skylight: first archetype hit wins, console.warn in dev+prod\n// - intensity=0: ambient term = 0, mathematically valid, no warn\n// - No equirect: solid-color ambient via the white fallback cube (no async)\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Skylight ambient environment light.\n *\n * A single Skylight entity provides ambient lighting for all StandardMaterial\n * surfaces. Two modes share one component:\n *\n * - **Solid-color ambient (no equirect).** Omit `equirect` for a constant\n * ambient = `color` * `intensity` applied immediately, with no async GPU\n * precompute. The engine samples a built-in 1x1 white irradiance cube, so a\n * freshly-loaded scene is lit on its first frame instead of being black\n * until an IBL upload finishes.\n * - **Image-based lighting (with equirect).** Supply `equirect` to upgrade to\n * diffuse irradiance + specular prefilter IBL. The engine runs the full\n * precompute (equirect->cubemap, irradiance convolution, prefilter mip\n * chain, BRDF LUT) transparently inside the render-system record arm;\n * `color` * `intensity` then scale the IBL ambient.\n *\n * `equirect` is an OPTIONAL `Handle<EquirectAsset>` resolved from a vite\n * pack-index GUID via `assets.load(guid, equirectAssetKind)`. The\n * cubemap projection is internal and idempotent: the same equirect source\n * always resolves to the same GPU cubemap (no user upload call).\n *\n * `color` is the linear-space ambient tint (default white [1, 1, 1]).\n * `intensity` is a linear multiplier (default 1.0; 0 disables ambient). Both\n * are read every frame, so they are live dynamic dials.\n *\n * `rotation` is an environment-space quaternion in `[x, y, z, w]` order.\n * The default identity quaternion leaves the source orientation unchanged;\n * changing it rotates the IBL at sample time without rebaking the source.\n *\n * @example Instant white ambient (no asset, no async):\n * world.spawn({ component: Skylight, data: {} });\n *\n * @example Dim warm ambient:\n * world.spawn({ component: Skylight, data: { color: [1, 0.9, 0.8], intensity: 0.3 } }); // color is [r, g, b]\n *\n * @example Full IBL from an HDR equirect (declarative -- no upload call):\n * // 1. resolve GUID from vite pack-index (see forgeax-engine-vite-plugin-pack)\n * import { AssetGuid } from '@forgeax/engine-pack/guid';\n * const guidRes = AssetGuid.parse('019e4a26-3c29-7420-af5d-20f2724a16b0');\n * if (!guidRes.ok) throw guidRes.error;\n * // 2. load the HDR equirect via the GUID-addressed pack route\n * const hdrRes = await assets.load(guidRes.value, equirectAssetKind);\n * if (!hdrRes.ok) throw hdrRes.error;\n * // 3. spawn the Skylight — the equirect handle activates the full IBL path;\n * // the cubemap + IBL precompute happen lazily inside the record arm.\n * world.spawn({ component: Skylight, data: { equirect: hdrRes.value } });\n */\nexport const Skylight = defineComponent('Skylight', {\n // The GPU equirect-to-cubemap projection is render-owned presentation\n // state. Record/restore preserves the portable lighting controls while the\n // render owner resolves this asset again on the target world.\n equirect: { type: 'shared<EquirectAsset>', simulationTransient: true },\n // color carries an explicit layer-2 default [1,1,1] (white); the array\n // layer-3 fallback is all-zero, so the default MUST be explicit (D-5).\n color: { type: 'array<f32, 3>', default: new Float32Array([1, 1, 1]) },\n intensity: { type: 'f32', default: 1.0 },\n rotation: { type: 'array<f32, 4>', default: new Float32Array([0, 0, 0, 1]) },\n});\n\nexport const Fog = defineComponent('Fog', {\n color: { type: 'array<f32, 3>', default: new Float32Array([0.5, 0.5, 0.5]) },\n density: { type: 'f32', default: 0.01 },\n heightFalloff: { type: 'f32', default: 0 },\n maxOpacity: { type: 'f32', default: 1 },\n});\n\n// @forgeax/engine-runtime - SkyboxBackground (environment cubemap render background).\n//\n// Schema: 3 fields -- equirect (Handle<EquirectAsset>, u32-stored handle)\n// + mode (f32 enum column, discriminator) + rotation (quaternion xyzw,\n// default identity). Naming convention follows the\n// single-semantic component rule: no Component suffix (AGENTS.md rule #1).\n//\n// feat-20260630-equirect-kind-internalized-ibl-declarative-skyligh M3 / w16:\n// the field is `equirect: shared<EquirectAsset>` (the retired\n// `cubemap: shared<CubeTextureAsset>` is gone). The skybox reuses the same\n// equirect handle as the Skylight; the cubemap projection is internal and\n// driven by the render-system record arm (no user upload call).\n//\n// Plan-strategy D-5: mode is a f32 enum column (ECS columns are POD, no\n// string unions in archetype storage). Consumer-facing type safety is\n// provided by the `SkyboxMode` literal union + `skyboxModeFromF32` mapper\n// (same pattern as cameraProjectionFromF32 in camera.ts:51,105,145,221-237).\n//\n// OOS-1: `mode: 'atmosphere'` implementation is deferred -- the union\n// shape leaves room for additive growth without breaking the f32 enum\n// encoding.\n//\n// AI user minimum spawn (charter P4):\n// world.spawn({ component: SkyboxBackground, data: { equirect, mode: 0 } });\n//\n// Single component activates the skybox render pass transparently when a\n// Skylight + tonemap active camera is present (skybox reuses the same\n// equirect handle as Skylight).\n\n/**\n * Skybox mode literal union (AC-02 narrowing surface).\n * Currently only 'cubemap' -- future 'atmosphere' deferred per OOS-1.\n */\nexport type SkyboxMode = 'cubemap';\n\n/** Numeric encoding of cubemap skybox mode (schema value for `mode`). */\nexport const SKYBOX_MODE_CUBEMAP = 0;\n\n/**\n * Map a `SkyboxBackground.mode` numeric value to the closed `SkyboxMode`\n * string-literal union. Only member currently is 'cubemap'; the exhaustive\n * switch is ready for future mode additions (e.g. 'atmosphere', OOS-1).\n */\nexport function skyboxModeFromF32(value: number): SkyboxMode {\n switch (value) {\n case SKYBOX_MODE_CUBEMAP:\n return 'cubemap';\n // Future: case SKYBOX_MODE_ATMOSPHERE: return 'atmosphere';\n }\n // Unrecognised value: fall back to 'cubemap' (charter P3 -- no silent\n // exception; the fallback preserves rendering on stale numerics while the\n // exhaustive switch shape ensures AI users catch new members at compile\n // time when a mode is added).\n return 'cubemap';\n}\n\n/**\n * SkyboxBackground: full-screen environment cubemap background.\n *\n * Renders a fullscreen triangle that reconstructs world-space view\n * direction from the camera's inverseViewProj matrix (View UBO),\n * samples a cubemap with the view direction, and writes an HDR color\n * to the hdrColor render target (before the main geometry pass).\n *\n * The skybox pass is automatically activated when a SkyboxBackground\n * entity exists, a Skylight entity provides the equirect source, and the\n * active Camera has tonemap active. The skybox reuses the same equirect\n * handle as the Skylight entity -- two independent components sharing the\n * same GPU resource (the internally-projected cubemap).\n *\n * `equirect` is resolved from a Vite pack-index GUID through the App-owned\n * AssetRegistry (`AssetRegistry.load(guid, 'equirect')`). The cubemap\n * projection is internal and driven by the render-system record arm; there\n * is no user upload call.\n *\n * `mode` is a numeric discriminator column (`f32`). Use\n * `SKYBOX_MODE_CUBEMAP` for the cubemap render path.\n *\n * `rotation` is an environment-space quaternion in `[x, y, z, w]` order.\n * It rotates the sampled cubemap without changing the camera or rebaking the\n * source equirectangular asset.\n *\n * @example Minimum spawn (defaults mode=0):\n * // Resolve the equirect payload through the App AssetRegistry.\n * world.spawn({ component: SkyboxBackground, data: { equirect: equirectHandle } });\n *\n * @example Single handle shared between Skylight (IBL) and SkyboxBackground:\n * const hdrRes = await assets.load(guid, 'equirect');\n * if (!hdrRes.ok) throw hdrRes.error;\n * world.spawn({ component: Skylight, data: { equirect: hdrRes.value } });\n * world.spawn({ component: SkyboxBackground, data: { equirect: hdrRes.value } });\n */\nexport const SkyboxBackground = defineComponent('SkyboxBackground', {\n // The GPU skybox projection is render-owned presentation state; restore\n // keeps the portable mode/rotation controls and lets the owner re-resolve\n // the environment asset on the target world.\n equirect: { type: 'shared<EquirectAsset>', simulationTransient: true },\n mode: { type: 'f32', default: SKYBOX_MODE_CUBEMAP },\n rotation: { type: 'array<f32, 4>', default: new Float32Array([0, 0, 0, 1]) },\n});\n","// @forgeax/engine-render - Instances component (per-entity instanced-draw transforms).\n//\n// Two sources, one component (feat-20260622-chunk-gpu-instancing-sprite-tilemap\n// / AC-09; charter P4 consistent abstraction + charter P1 progressive disclosure).\n// The `Instances` ECS component has exactly TWO sources of `transforms` data, and\n// AI users should hold the boundary explicitly to avoid misreading the ECS view:\n//\n// Source 1 (EXPLICIT, the only source that lands in ECS) — AI user opt-in.\n// The AI user hand-attaches `Instances { transforms }` onto an entity at\n// spawn / set time for high-performance instanced draw. `world.get(e,\n// Instances)` returns the AI user's payload verbatim (a `Float32Array`\n// snapshot of column-major mat4 instances; stride = 16). This is the sole\n// code path through which `Instances` ever appears on an entity.\n//\n// Source 2 (TRANSPARENT, never written back into ECS) — engine record-stage\n// fold. When the AI user spawns N independent sprite / tilemap-cell\n// entities sharing the same (Layer.value, posZ, materialHandle) sort\n// equivalence class, the engine record stage transparently folds the\n// equivalent run into ONE `drawIndexed(indexCount, count)` using an\n// INTERNAL transient buffer (see `render-system-record.ts` fold operator\n// + `render.instancing.foldedDraws` metric, and the `RhiError\n// 'instancing-exceeds-uniform-cap'` fallback). The fold operator does\n// NOT auto-inject `Instances` onto those entities — `world.get(e,\n// Instances)` on a folded entity returns `Result.err` exactly as before.\n// The ECS view is preserved bit-for-bit (per-cell / per-sprite entity\n// retained, query / despawn / picking unchanged); the optimisation is\n// invisible at the component layer (charter P4: consistent abstraction —\n// the high-performance path is opt-in via Source 1, the default spawn\n// shape stays untouched).\n//\n// AI user reading this header: do NOT expect engine-side fold to materialise\n// as an `Instances` row on your entity. Read the metric (foldedDraws) or the\n// RhiError code to observe fold behaviour; never gate logic on a runtime\n// `world.get(e, Instances)` lookup after spawn.\n//\n// Schema: 1 array<f32> field `transforms` carrying packed column-major mat4\n// instance transforms (16 f32 per instance, stride = 16). Stride is enforced\n// through a TWO-LAYER contract:\n//\n// 1. AI user set-site: spawn / `world.set` / `world.push` callers pass a\n// `Float32Array` (or numeric array) whose `length` is a non-zero\n// multiple of 16. The set site is the AI user's responsibility -- the\n// engine cannot prove the column-major mat4 packing without the\n// caller's intent.\n// 2. RenderSystem extract entry: `render-system-extract.ts` performs a\n// defensive `transforms.length % 16 === 0` check on every\n// `world.get(e, Instances).transforms` snapshot at frame extract time;\n// violations route a structured `InstanceTransformsStrideMismatchError`\n// (`code: 'instance-transforms-stride-mismatch'`,\n// `detail: { actualLength, expectedStride: 16 }`) through the World\n// Layer-3 ErrorHandler and the renderable is skipped (fail-fast: the\n// malformed length never reaches the GPU upload path).\n//\n// feat-20260515-buffer-array-vocab-collapse M3 / w16 (decision §2.3 stride\n// responsibility migration): the legacy component-level\n// stride-declaration option (`{ transforms: 16 }` keyed on the retired\n// per-component stride defineComponent option key) was retired because:\n// - The ECS layer no longer carries any per-component stride schema (M2 /\n// w9 dropped the option from `DefineComponentOptions` -- the SSOT\n// moved to the RenderSystem entry + AI user set site).\n// - Centralising the check at the consumer (RenderSystem extract) rather\n// than the producer (ECS write paths) lets the GPU upload path stay\n// trust-the-snapshot; AI users get one structured error per offending\n// frame rather than one per write.\n//\n// feat-20260514-ecs-children-instances-managed-buffer-array M3 / w14:\n// migrated from the legacy `{ buffer: 'ref', count: 'u32' }` pair (which\n// cross-coupled with the now-deleted `AssetRegistry.createInstancedBuffer`\n// pipeline + the `InstancedBufferAsset` POD) to the ECS-managed array path.\n// Resize is a `world.push(e, Instances, 'transforms', value)` away (one f32\n// at a time) plus a future `world.grow` if a bulk-resize affordance is\n// added.\n//\n// Storage buffer cap-gate (D-5 OOS-08 follow-up):\n// - The runtime RenderSystem consumer (`render-system-record.ts`) checks\n// `device.caps.storageBuffer` before binding the per-entity transforms;\n// `caps.storageBuffer === false` (backend lacking storage buffer support,\n// e.g. rhi-wgpu webgl backend) routes a `RhiError` ('feature-not-enabled').\n// A future loop owns the per-draw fallback path.\n//\n// Group transform chained semantics (charter proposition 5 mental migration):\n// - When the same entity carries both `Transform` (entity_world) and\n// `Instances` (per-instance local transforms), the vertex shader\n// composes per instance:\n//\n// world_position[i] = entity_world * instances_local[i] * vertex_position\n//\n// - `Instances.transforms[i*16..i*16+15]` is interpreted as a local-space\n// transform under the entity, exactly like a child entity's `Transform`\n// under `ChildOf { parent }` in the hierarchy system. AI users reuse\n// the `parent x local` intuition without a new concept. Set the\n// entity's `Transform` to identity to make `instances_local[i]`\n// directly world-space.\n//\n// 4-segment minimum contract (read this header before reaching for\n// the source body):\n//\n// ===== (a) single-component import + spawn example =====\n//\n// import {\n// createRenderer,\n// createPrimitiveMesh,\n// MeshFilter, MeshRenderer, Transform,\n// Instances, type InstancesData,\n// } from '@forgeax/engine-render';\n//\n// // 1 entity rendering N instanced cubes (16N packed f32, column-major mat4):\n// const transforms = new Float32Array(N * 16);\n// // ... fill column-major mat4 columns per instance ...\n// world.spawn(\n// { component: MeshFilter, data: { assetHandle: cubeMesh } },\n// { component: MeshRenderer, data: {} },\n// { component: Instances, data: { transforms } },\n// );\n//\n// ===== (b) packed mat4 layout =====\n//\n// const transforms = new Float32Array(N * 16); // column-major mat4 per instance\n// // instance i occupies floats [i*16 .. i*16+15]:\n// // [m00 m10 m20 m30 <- column 0\n// // m01 m11 m21 m31 <- column 1\n// // m02 m12 m22 m32 <- column 2\n// // m03 m13 m23 m33] <- column 3 (translation in m03/m13/m23)\n//\n// `transforms.length` MUST be a non-zero multiple of 16. AI users gate at\n// the set / push site; the RenderSystem extract entry holds the second\n// defensive (AC-06: detail carries `{ expectedStride: 16, actualLength }`).\n// The instance count is the live snapshot length / 16.\n//\n// ===== (c) error code consumption (typed property access, no message regex) =====\n//\n// // Stride violation surfaces through the engine-ecs Layer-3 ErrorHandler\n// // when extract reads a malformed snapshot:\n// // on('error', (err) => {\n// // if (err.code === 'instance-transforms-stride-mismatch') {\n// // // err.detail.expectedStride === 16\n// // // err.detail.actualLength === <user-supplied length>\n// // }\n// // });\n// //\n// // RenderSystem cap-gate (D-5) -> RhiError 'feature-not-enabled' on the\n// // RhiErrorListenerRegistry channel:\n// // on('error', (err) => {\n// // if (err.code === 'feature-not-enabled') {\n// // console.warn(err.expected, err.hint);\n// // }\n// // });\n//\n// charter mapping: proposition 1 (single import surface\n// `import { Instances, type InstancesData } from '@forgeax/engine-render'`);\n// proposition 3 (machine-readable schema > prose:\n// `{ transforms: 'array<f32>' }` is the SSOT, stride 16 documented here +\n// enforced at the RenderSystem entry);\n// proposition 4 (explicit failure: stride violation routes a structured\n// EcsError, not a silent half-row); proposition 5 (consistent abstraction:\n// Instances mirrors Children -- both ride the array-vocab path).\n//\n// Anchors: requirements §AC-06 (stride 16 + RenderSystem upload path);\n// plan-strategy §2.3 (stride responsibility migration to RenderSystem entry\n// defensive + AI user set site) + §3.3 stride error path; plan-decisions\n// D-1 / D-5.\n// OOS-09 (no addChild Commands API) does not apply here; OOS-01 (no\n// dangling-entity sweep) does not apply (Instances stores f32 not entity).\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Per-entity instanced-draw transforms (ECS component).\n *\n * Carries a variable-length `array<f32>` of column-major mat4 instance\n * transforms (16 f32 per instance, stride = 16; documented above and\n * enforced at the RenderSystem extract entry, NOT at the ECS write paths).\n *\n * The runtime RenderSystem consumer materialises a fresh `Float32Array`\n * snapshot on every `world.get(e, Instances).transforms` access (D-4\n * no-cache), reads the live count from the snapshot's `length`, and\n * uploads the bytes to a per-entity GPU storage buffer in the record stage\n * (`render-system-record.ts`).\n *\n * @example Spawn an entity rendering 10000 instanced cubes:\n * const transforms = new Float32Array(10000 * 16);\n * // ... fill column-major mat4 columns ...\n * world.spawn(\n * { component: MeshFilter, data: { assetHandle: cubeMesh } },\n * { component: MeshRenderer, data: { ... } },\n * { component: Instances, data: { transforms } },\n * );\n */\nexport const Instances = defineComponent('Instances', {\n transforms: { type: 'array<f32>' },\n});\n\n/**\n * Type-level hint for `data` at the `Instances` spawn site.\n *\n * The runtime ECS column shape for `array<f32>` accepts a `Float32Array`\n * payload at spawn / set time (the bytes are copied into the BufferPool\n * slot). The `transforms` field is documented as `Float32Array` here so\n * AI-user IDE autocomplete picks up the typed-array shape.\n *\n * @example\n * import type { InstancesData } from '@forgeax/engine-render';\n * const data: InstancesData = { transforms: new Float32Array(N * 16) };\n */\nexport type InstancesData = {\n readonly transforms: Float32Array;\n};\n","// @forgeax/engine-render - Layer (render-order layer index, signed 32-bit).\n//\n// Schema: 1 i32 column (value). Signed two's complement so negatives travel\n// through the spawn payload unchanged — background sprites live at negative\n// values (e.g. -100), the default game layer at 0, foreground at 100, UI at\n// 1000. Layer is consumed at sort time by `transparent-sort.ts` (M-3 w23)\n// as the primary key in the (layer asc, sortValue asc) composite ordering.\n//\n// Naming convention: bare entity name (no Component suffix; single-semantic\n// component idiom aligned with Bevy ECS conventions — Transform / Camera /\n// DirectionalLight follow the same shape, see AGENTS.md §Component naming).\n//\n// Layer is a generic ECS renderer component — NOT a 2D-only special. 3D\n// entities may also carry Layer to bias their bucket placement (charter\n// P4 consistent abstraction: same component drives both pipelines).\n//\n// AC-18 path (1): an entity spawned without an explicit Layer reads back\n// 0 via the existing 4-layer spawn fallback chain\n// (feat-20260517-spawn-default-fallback). This feat does NOT introduce a\n// fifth fallback layer; the silent default flows through layer-3\n// `typeDefault('i32') === 0`.\n//\n// @derives defineComponent factory (packages/ecs/src/component.ts) — i32\n// is a legacy scalar type; its intrinsic properties (byteSize / viewCtor\n// / storage) live in TYPE_METADATA['i32'] (feat-20260602 M1).\n// @reuses spawn 4-layer fallback chain (feat-20260517-spawn-default-fallback)\n// — layer-3 typeDefault('i32') returns 0, no fifth layer.\n//\n// charter mapping: F1 (single-import barrel discovery — Layer joins\n// Transform / MeshFilter / MeshRenderer / Camera / DirectionalLight)\n// + P3 (explicit default — 0 surfaces as a read-back value, not undefined)\n// + P4 (consistent abstraction — Layer is a generic render component, not\n// a 2D-only special).\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Render-order layer index.\n *\n * Convention (non-binding; conveys intent, not enforced):\n * - negative (e.g. -100): background layers (sky / parallax tiles).\n * - 0: default game layer.\n * - positive (e.g. 100): foreground layers (overlays, FX).\n * - 1000+: UI / HUD.\n *\n * Signed i32 (two's complement, range \\u00b12\\u00b3\\u00b9). Negatives round-trip\n * through the spawn payload unchanged — no schema-layer mutate. i32 lives in\n * the CPU sort path (transparent-sort.ts M-3 w23); no GPU-side stride\n * compatibility risk.\n *\n * @example Minimal spawn (defaults to game layer 0):\n * world.spawn({ component: Layer, data: {} }); // yields value=0\n *\n * @example Spawn 4 sprites across the conventional layer band:\n * world.spawn({ component: Layer, data: { value: -100 } }); // background\n * world.spawn({ component: Layer, data: { value: 0 } }); // default\n * world.spawn({ component: Layer, data: { value: 100 } }); // foreground\n * world.spawn({ component: Layer, data: { value: 1000 } }); // UI\n *\n * @example Spawn payload omitting Layer — the 4-layer fallback fills 0:\n * const e = world.spawn(\n * { component: Transform, data: { pos: [0, 0, 0],\n * quat: [0, 0, 0, 1], scale: [1, 1, 1] } },\n * );\n * // Layer is not on the entity; query joins must check membership.\n */\nexport const Layer = defineComponent('Layer', {\n value: { type: 'i32', default: 0 },\n});\n","// @forgeax/engine-render - MeshFilter (mesh asset reference).\n//\n// Schema: `{ assetHandle: 'shared<MeshAsset>' }`. The schema-vocab\n// `'shared<T>'` keyword stores a u32 column and type-derives to\n// `Handle<'MeshAsset', 'shared'>` (engine-ecs Handle<T,M> twoParam\n// phantom; `'shared'` mode = ref-counted retain on set / release on\n// clear, lifecycle owned by `SharedRefStore` per feat-20260614).\n// The brand prevents cross-asset assignment at compile time (e.g.\n// `Handle<'TextureAsset','shared'>` is not assignable to `assetHandle`).\n//\n// AI users create one `MeshAsset` payload through geometry's primitive\n// factory and intern it in the owning World; the returned shared reference\n// matches the schema-derived `Handle<'MeshAsset', 'shared'>` shape.\n//\n// Naming flavor: unity-style \"MeshFilter / MeshRenderer\" pair, but the forgeax\n// pair does NOT mirror Unity's filter-toggle semantics - MeshFilter only\n// carries the geometry ref, MeshRenderer only carries the material handle;\n// the pair is independently composable. D-Q7 default-material policy\n// (feat-20260517-merge-mesh-renderer-material-renderer plan-strategy §2.2):\n// case A (entity carries MeshFilter without MeshRenderer) -> archetype\n// query never matches -> entity is silently absent from the\n// RenderableSnapshot[] (NO default-material fallback, NO onError fire);\n// case B (MeshRenderer.material omitted at spawn) -> mid-grey\n// defaultMaterialSnapshot fallback (no onError); case C (material handle\n// unresolved) -> RhiError 'asset-not-registered' (mirrors the\n// MeshFilter.assetHandle dangling-ref path).\n//\n// charter mapping: proposition 1 (single import) + proposition 4 (explicit\n// failure: missing or unregistered handle fires onError 'asset-not-registered'\n// with .detail = { assetHandle } + cross-asset brand mismatch is a TS\n// compile-time error) + proposition 5 (consistent abstraction: the schema\n// vocab `'shared<T>'` is the SSOT for AssetRegistry-owned handles across\n// the engine).\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Mesh filter (geometry asset reference).\n *\n * `assetHandle` carries a `Handle<'MeshAsset', 'shared'>` (u32-stored)\n * pointing to a mesh interned by the owning World. Create that reference\n * with `world.internSharedRef(createPrimitiveMesh('cube').unwrap())` or\n * with a payload loaded from the App asset registry.\n *\n * Error path: if the handle is not registered at draw time, RenderSystem\n * fires `Renderer.onError` with\n * `RhiError({ code: 'asset-not-registered', detail: { assetHandle } })`\n * and skips this entity (other entities continue rendering; charter\n * proposition 9 graceful degradation).\n *\n * @example Spawn an entity referencing a geometry-owned cube mesh:\n * import { MeshFilter } from '@forgeax/engine-render';\n * import { createPrimitiveMesh } from '@forgeax/engine-geometry';\n * const cube = world.internSharedRef(createPrimitiveMesh('cube').unwrap());\n * world.spawn({ component: MeshFilter, data: { assetHandle: cube } });\n */\nexport const MeshFilter = defineComponent('MeshFilter', {\n assetHandle: { type: 'shared<MeshAsset>' },\n});\n","// @forgeax/engine-render - MeshRenderer (multi-material array slot).\n//\n// feat-20260608-mesh-multi-section-primitive-multi-material-slot M2 / w7:\n// the single `material` field is replaced with `materials` — an\n// `array<shared<MaterialAsset>>` indexed by MeshAsset.materialSlots. Entries\n// are sparse positional overrides: a missing/zero entry inherits the Mesh\n// slot default, while a defaultless slot inherits the neutral engine material.\n//\n// The schema-vocab keyword `'array<shared<MaterialAsset>>'` (feat-20260614\n// M5 -- migrated from `'array<handle<MaterialAsset>>'`) stores as a u32\n// column slot array; the brand prevents cross-asset assignment at compile\n// time. The `'shared<T>'` arm routes element retain/release through\n// SharedRefStore (M4 / w13) on overwrite / archetype migration.\n//\n// charter mapping: proposition 1 (single import — `MeshRenderer` is the\n// only material-binding component AI users see); proposition 3\n// (machine-readable schema > prose); proposition 4 (explicit failure: the\n// TS brand on `Handle<'MaterialAsset','shared'>` rejects cross-variant\n// assignment at compile time); proposition 5 (consistent abstraction:\n// shading model classification (`'unlit'` / `'standard'`) lives ONLY on\n// the asset discriminant, NOT on the component name).\n//\n// RenderSystem consumption: `render-system-extract.ts` runs ONE archetype\n// query (`world.query(MeshRenderer)`) and routes per entity by\n// `mat.materialShaderId` (shader identity) to the unlit.wgsl or pbr.wgsl\n// pipeline tag.\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Mesh renderer (ECS component, multi-material array).\n *\n * Stores `materials: readonly Handle<'MaterialAsset','shared'>[]`\n * (u32-stored array, indexed by MeshAsset.materialSlots). Submeshes point to\n * those stable slots through `Submesh.materialSlot`. The asset's `passes[].shader`\n * identity is the SSOT for which pipeline RenderSystem routes the entity\n * to (record stage dispatches on `materialShaderId`).\n *\n * Defaults map carries `materials: []`: every slot inherits its Mesh-owned\n * default, or the neutral engine material when that slot is intentionally\n * defaultless.\n *\n * @example Spawn while inheriting every Mesh slot default:\n * world.spawn({ component: MeshRenderer, data: {} });\n *\n * @example Spawn an unlit-targeted entity:\n * import { MeshRenderer, Materials } from '@forgeax/engine-render';\n * const matPayload = engine.assets.catalog(matGuid, Materials.unlit([1, 0, 0, 1])).value;\n * const matHandle = world.allocSharedRef('MaterialAsset', matPayload);\n * world.spawn({ component: MeshRenderer, data: { materials: [matHandle] } });\n *\n * @example Spawn a standard (PBR) entity:\n * const matPayload = engine.assets.catalog(matGuid, Materials.standard({\n * baseColor: [0.5, 0.5, 0.5, 1], metallic: 0, roughness: 0.4,\n * })).value;\n * const matHandle = world.allocSharedRef('MaterialAsset', matPayload);\n * world.spawn({ component: MeshRenderer, data: { materials: [matHandle] } });\n */\nexport const MeshRenderer = defineComponent('MeshRenderer', {\n materials: { type: 'array<shared<MaterialAsset>>', default: [] },\n});\n","// @forgeax/engine-render - PointLight (omnidirectional point-light parameters).\n//\n// Schema: color array<f32,3> + intensity f32 + range f32 (feat-20260709 M2:\n// color collapsed from 3 per-axis scalar columns to one inline array<f32,3>).\n// `position` comes from the Transform component; PointLight requires a\n// companion Transform on the same entity (ECS query: `[Transform, PointLight]`).\n// `range` units are meters; defaults to `10.0`. Runtime finite-range\n// attenuation is the Three r184 squared window; the KHR unsquared curve is an\n// import/reference boundary only. See `light-helpers.ts` for the host-side\n// range projection.\n//\n// 0 light + standard material -> physically correct black render\n// (feat-20260518-pbr-direct-lighting-mvp). The runtime once-warn channel\n// (M5 / w25) collapses to \"directionalCount + pointCount + spotCount === 0\";\n// see packages/runtime/README.md section Common pitfalls for the AI-user\n// guidance after the M5 docs land.\n//\n// Naming convention: bare entity name aligned with Bevy ECS conventions\n// (feat-20260513-component-naming-bevy-align). DirectionalLight / SpotLight\n// follow the same single-semantic-entity rule (charter proposition 5).\n//\n// charter mapping: proposition 1 (single import + IDE autocomplete on\n// payload.range) + proposition 3 (silent failure -> explicit failure;\n// spawn-time fail-fast on range<0 / NaN with structured EcsError) +\n// proposition 5 (consistent abstraction: shared payload shape with\n// SpotLight; `range` semantics aligned with KHR_lights_punctual).\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Omnidirectional point light (KHR_lights_punctual `point` type).\n *\n * `position` source: the companion `Transform` component on the same entity.\n * Spawn via `world.spawn({ component: Transform, data: ... }, { component: PointLight, data: ... })`\n * so the render system extract path can join the two via the\n * `[Transform, PointLight]` ECS query.\n *\n * `color` is linear-space rgb in `[0, 1]` per channel; `intensity` is candela;\n * `range` is in meters and defaults to `10.0`\n * (KHR convention; `+Infinity` is the KHR no-truncation value, retained\n * for KHR_lights_punctual `range: 0` bridging via `light-helpers.ts`).\n * The runtime window is `clamp(1 - (d / range)^4, 0, 1)^2`; its no-cutoff\n * boundary uses inverse-square decay with the shader safety floor. Exposure is\n * applied after lighting and never multiplied into intensity.\n *\n * @example Spawn a single point light at (5, 3, 5):\n * world.spawn(\n * { component: Transform, data: { pos: [5, 3, 5] } },\n * { component: PointLight, data: { intensity: 8, range: 25 } },\n * );\n *\n * @example Minimal spawn -- defaults give neutral white at full strength, range 10m:\n * world.spawn(\n * { component: Transform, data: { pos: [0, 1, 0] } },\n * { component: PointLight, data: {} },\n * );\n * // resolves to color=[1, 1, 1], intensity=1, range=10.0.\n */\nexport const PointLight = defineComponent('PointLight', {\n // color carries an explicit layer-2 default [1,1,1] (white); the array\n // layer-3 fallback is all-zero, so the default MUST be explicit (D-5).\n color: { type: 'array<f32, 3>', default: new Float32Array([1, 1, 1]) },\n intensity: { type: 'f32', default: 1 },\n range: { type: 'f32', default: 10.0 },\n});\n","// @forgeax/engine-runtime — PointLightShadow (omnidirectional point-light\n// shadow mapping parameters; cube-array atlas variant).\n//\n// Schema: 6 f32 columns — mapSize (u32, stored as f32), depthBias, normalBias,\n// nearPlane, farPlane, pcfKernelSize (u32, stored as f32). No fixed-extent\n// field — cube map uses fov=90 perspective, not ortho.\n//\n// Atlas capacity is a renderer policy; ECS does not enforce a component\n// cardinality bound.\n// Co-located with DirectionalLight in components/ (research L1.2).\n//\n// Naming convention: bare entity name (AGENTS.md §Component naming), no\n// Component suffix. Same defineComponent pattern and ShadowInvalidConfigError\n// surface as the shadow fields merged into DirectionalLight (feat-20260621 M1).\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Omnidirectional point-light shadow mapping parameters.\n *\n * The renderer may batch this component into a bounded atlas, but the ECS\n * component remains a plain storage schema and carries no cardinality policy.\n *\n * @example Spawn a point light with default shadow config:\n * world.spawn(\n * { component: Transform, data: { pos: [0, 4, 0] } },\n * { component: PointLight, data: { range: 25 } },\n * { component: PointLightShadow, data: {} }, // 6 fields filled from defaults\n * );\n *\n * @example Spawn with explicit map size and bias:\n * world.spawn(\n * { component: PointLightShadow, data: { mapSize: 1024, depthBias: 0.01 } },\n * );\n */\nexport const PointLightShadow = defineComponent('PointLightShadow', {\n mapSize: { type: 'f32', default: 512 },\n depthBias: { type: 'f32', default: 0.005 },\n normalBias: { type: 'f32', default: 0.05 },\n nearPlane: { type: 'f32', default: 0.1 },\n farPlane: { type: 'f32', default: 25 },\n pcfKernelSize: { type: 'f32', default: 3 },\n});\n","// @forgeax/engine-render - PostProcessParams component.\n//\n// Schema: { shader: 'string', data: 'buffer' }.\n//\n// `shader` identifies the fullscreen post-process shader (the same id as passed to\n// `renderer.postProcess.register(id, entry)`). `data` carries the per-frame params\n// bytes as a variable-byte ECS managed buffer slot. The write side (world.spawn /\n// world.set) accepts any AllowSharedBufferSource (Float32Array / ArrayBuffer /\n// Uint8Array / any TypedArray) and the ECS normalizes it to Uint8Array bytes\n// (feat-20260621 V2 / AC-A4); the read side (world.get) returns Uint8Array, which\n// satisfies AllowSharedBufferSource for GPU queue.writeBuffer ingestion.\n//\n// Single-semantic component — drops the `Component` suffix\n// (AGENTS.md §Component naming rule #1). The `data` field uses the ECS 'buffer'\n// vocab keyword (plan-strategy D-7) for variable-byte storage.\n//\n// Data flow (plan-strategy D-1):\n// extract -> iterate PostProcessParams-bearing entities ->\n// collect into Map<shaderId, AllowSharedBufferSource> snapshot ->\n// dispatchFullscreenPass picks up per-shader data -> writeBuffer to eager UBO.\n//\n// Decision anchors:\n// - requirements AC-A2 (data-driven, no imperative renderer.setParams mutator)\n// - requirements AC-A4 (AllowSharedBufferSource type on the data field)\n// - plan-strategy D-1 (new single-semantic ECS component for params)\n// - plan-strategy D-7 (ECS 'buffer' vocab keyword for variable-byte storage)\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\nconst schema = {\n shader: 'string',\n data: 'buffer',\n} as const;\n\nexport const PostProcessParams = defineComponent('PostProcessParams', schema);\n","// @forgeax/engine-runtime - SceneInstance component (feat-20260608-\n// scene-nesting-ecs-fication M2 / w16).\n//\n// Single ECS fat component carrying everything that used to live on the\n// old `SceneInstance` + `SceneInstanceContainer` pair (deleted\n// in M3). Schema fits the ECS schema vocab (3 single-identifier fields):\n//\n// { source: 'shared<SceneAsset>',\n// mapping: 'array<entity>',\n// state: 'unique<SceneInstanceState>' }\n//\n// `source` carries the SceneAsset handle the synthetic root entity was\n// instantiated from (Tier-A AssetUnion handle, AGENTS.md §Assets submodule).\n// `mapping` is the LocalEntityId -> Entity table indexed positionally\n// (mapping[localId] = spawned Entity); the ECS variable-array column gives\n// us a SoA-friendly read path for query<SceneInstance> scans without\n// touching the dynamic Map/Set state.\n// `state` is a `ref<SceneInstanceState>` slot — World holds the live\n// SceneInstanceState payload in its UniqueRefStore and World despawn\n// auto-releases the ref u32 (the same path used by audio / physics\n// payloads, plan-strategy §D-2). Each instantiateScene call calls\n// `world.allocUniqueRef('SceneInstanceState', state)` once and stores the\n// returned u32 in this column.\n//\n// Decision anchors:\n// - plan-strategy §D-2 (single ref wraps SceneInstanceState dynamic\n// structure; ECS schema vocab `\\w+` rejects `ref<Map<...>>`)\n// - plan-strategy §3.2 sequence (sequence diagram step 'set ... state:\n// {entityToLocalId, detached, overrides, rootEntities}')\n// - AGENTS.md §Component naming rule #1 (single-semantic component drops\n// `Component` suffix)\n// - charter F1 (single-import barrel: SceneInstance lives in\n// `@forgeax/engine-render` next to Transform / Camera / DirectionalLight)\n// - charter P3 (machine-readable schema: 3 closed fields)\n// - charter P4 (consistent abstraction: instance == entity carrying\n// SceneInstance — same `world.query({ read: [SceneInstance] })` /\n// `world.get(root, SceneInstance)` path as any other component)\n\nimport { defineComponent, type EntityHandle } from '@forgeax/engine-ecs';\nimport type { LocalEntityId, MountOverride } from '@forgeax/engine-types';\n\n/**\n * Per-component, per-field override record carried in `SceneInstanceState`.\n *\n * Composite key `<componentName>:<fieldName>` keeps the override map flat\n * (single Map nesting level) so AI users walking `state.overrides` see one\n * iteration depth — D-2 prefers a single SSOT over multi-Map nesting that\n * would make iteration order ambiguous (charter F1: single mental model).\n *\n * The value is `unknown` because the per-component schema vocab lives in the\n * ECS layer; runtime fail-fast via `EcsErrorCode = 'scene-override-type-\n * mismatch'` (plan-strategy §D-9) catches type drift on the apply path.\n *\n * @internal Surface from `state.overrides` only; AI users never construct a\n * record directly. Use `worldSetSceneOverride(world, root, member, comp,\n * field, value)` to write and `worldRemoveSceneOverride(world, root, member,\n * comp, field)` to roll back to the source SceneAsset value.\n */\nexport interface SceneInstanceOverrideRecord {\n readonly comp: string;\n /**\n * Component-granular add-or-patch discriminant (feat-20260713 M1 / w4):\n * present -> this record patches a single field; absent -> it adds/upserts\n * the whole `comp` (M2 apply semantics). Mirrors `MountOverride.field`.\n */\n readonly field?: string;\n readonly value: unknown;\n}\n\n/**\n * Dynamic state payload for one SceneInstance — held in the World's\n * UniqueRefStore behind a `ref<SceneInstanceState>` slot on the synthetic\n * root entity. Mirrors the old class-based layout (plan-strategy §D-2 +\n * design doc §11.2 internal-state-table) but flattened into plain JS Maps/Sets so\n * AI users can iterate without indirection.\n *\n * Lifecycle:\n * - allocated by `worldInstantiateScene(world, handle, parent?)` — the W in\n * `world.allocUniqueRef('SceneInstanceState', state)` returns the u32\n * slot id stored in the SceneInstance.state column;\n * - released by `world.despawn(root)` (the standard `ref<T>` release loop)\n * or explicitly via `worldDespawnScene(world, root)` / `worldDespawnDescendants(world, root)`.\n *\n * AI users typically reach this struct only through the read path\n * `world.get(root, SceneInstance).state.overrides.get(<comp>:<field>)` for\n * inspection; mutation happens through the 8 World methods.\n */\nexport interface SceneInstanceState {\n /**\n * SceneAsset handle the instance was instantiated from. Mirrors the\n * SceneInstance.source column for AI users who already have a\n * SceneInstanceState in hand and want the source handle without a second\n * `world.get` round-trip.\n */\n readonly source: import('@forgeax/engine-types').Handle<'SceneAsset', 'shared'>;\n\n /**\n * Reverse mapping (live `Entity` -> source `LocalEntityId`). Used by\n * `worldSetSceneOverride` to validate the member entity belongs to this\n * instance + by `worldDetachSceneMember` / `worldReattachSceneMember`\n * to translate caller-side Entity values back to their authored localId.\n */\n readonly entityToLocalId: Map<EntityHandle, LocalEntityId>;\n\n /**\n * LocalEntityIds of members the AI user marked detached via\n * `worldDetachSceneMember(world, root, member)`. The member entities stay\n * alive in the World; only the bookkeeping marker moves so\n * `worldDespawnDescendants(world, root, { keepDetached: true })` can skip them.\n * Detach is idempotent (set semantics).\n */\n readonly detachedLocalIds: Set<LocalEntityId>;\n\n /**\n * Per-member runtime overrides keyed by `<localId>` -> `<comp>:<field>`\n * -> override record. mount-time overrides (authored on the SceneAsset's\n * `mounts[].overrides`) populate this map at instantiate-time so AI\n * users see them via the same read path as runtime\n * `setSceneOverride` writes (single SSOT).\n */\n readonly overrides: Map<LocalEntityId, Map<string, SceneInstanceOverrideRecord>>;\n\n /**\n * Top-level root entities of the materialised tree (members without a\n * ChildOf parent at instantiate time). The synthetic root entity that\n * carries the SceneInstance component itself is NOT in this list — it is\n * the parent of every member entity (plan-strategy §3.2 sequence step 7).\n */\n readonly rootEntities: EntityHandle[];\n\n /** Synthetic roots of recursively mounted SceneAssets owned by this instance. */\n readonly mountRoots: EntityHandle[];\n\n /**\n * Total slot count `entities.length + sum(mounts[].memberCount)` —\n * captured at instantiate-time so cycle / count consistency checks\n * (e.g. `worldGetSceneAssetForInstance(world, root)` symmetry) can compare\n * against the live SceneInstance.mapping column without re-reading the\n * SceneAsset.\n */\n readonly totalSlots: number;\n\n /**\n * Mount-time override authored on the parent SceneAsset's `mounts[]`\n * record. Captured at instantiate-time so `worldRemoveSceneOverride`\n * can fall back to the mount-time value before going to the source\n * SceneAsset value (plan-strategy §D-2).\n */\n readonly mountTimeOverrides: readonly MountOverride[];\n}\n\n/**\n * SceneInstance ECS component — synthetic root entity payload for one\n * materialised SceneAsset (instance == entity carrying SceneInstance,\n * charter P4).\n *\n * AI users discover the component via IDE autocomplete on\n * `@forgeax/engine-render` (single-import barrel; AGENTS.md §Components):\n *\n * ```ts\n * import { SceneInstance } from '@forgeax/engine-render';\n * for (const row of world.query({ read: [SceneInstance] }).unwrap()) {\n * console.log(`root=${row.entity} source=${row.get(SceneInstance).source}`);\n * }\n *\n * const inst = world.get(root, SceneInstance).value;\n * const memberEntity = inst.mapping[localId]; // Uint32Array snapshot\n * for (const detached of inst.state.detachedLocalIds) { /* ... *\\/ }\n * ```\n *\n * The component does not register a relationship — synthetic root +\n * members are wired through the standard `ChildOf` (member -> root) so\n * the existing `world.iterDescendants(root)` / Children mirror code paths\n * apply unchanged (plan-strategy §D-5).\n *\n * @example Materialise + inspect a SceneAsset:\n * const { root, diagnostics } = worldInstantiateScene(world, handle).value;\n * const inst = world.get(root, SceneInstance).value;\n * // inst.source === handle, inst.mapping is Uint32Array(totalSlots)\n * // inst.state holds entityToLocalId / detachedLocalIds / overrides /\n * // rootEntities / mountRoots / totalSlots / mountTimeOverrides.\n */\nexport const SceneInstance = defineComponent(\n 'SceneInstance',\n {\n source: { type: 'shared<SceneAsset>' },\n mapping: { type: 'array<entity>' },\n // The unique slot is the ECS storage seam for the instance's structured\n // runtime payload; keep the nested semantic visible to schema consumers.\n state: { type: 'unique<SceneInstanceState>', shape: 'nested' },\n },\n { transient: true },\n);\n","// @forgeax/engine-render - SortKey (per-entity transparent sort override, f32).\n//\n// Schema: 1 f32 column (value). Entity-level sort override consumed by\n// `transparent-sort.ts` (M-3 w23): when present, SortKey.value REPLACES\n// the mode-formula result for this entity in the (layer, sortValue)\n// composite ordering. Override priority is higher than every\n// TransparentSortConfig mode computation (horizontal-z / Y-sort /\n// Y-Z-blend) so AI users can pin a single entity above / below the\n// procedural ordering without reshaping the entire scene.\n//\n// Like Layer, SortKey is a generic ECS renderer component — NOT a\n// 2D-only special. 3D entities may also carry SortKey to bias their\n// position inside the transparent bucket (charter P4 consistent\n// abstraction: same component drives both pipelines).\n//\n// AC-19 derivation audit row (4) names this file as the\n// `defineComponent` factory derivation. JSDoc surfaces the override\n// priority via @derives (ECS factory) annotation; the consumer side\n// of the override behaviour is implemented + verified in M-3 w16 +\n// w23, not here.\n//\n// @derives defineComponent factory (packages/ecs/src/component.ts) —\n// f32 is a legacy scalar type; its intrinsic properties (byteSize / viewCtor\n// / storage) live in TYPE_METADATA['f32'] (feat-20260602 M1).\n//\n// charter mapping: F1 (single-import barrel - joins Layer / Transform\n// / MeshFilter / MeshRenderer / Camera / DirectionalLight) +\n// P3 (explicit default 0.0 surfaces via the 4-layer fallback chain) +\n// P4 (consistent abstraction — generic render component, not 2D-only).\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Per-entity transparent-sort override.\n *\n * When attached to an entity inside the transparent bucket (M-3 w22),\n * `SortKey.value` REPLACES the result of `TransparentSortConfig.mode`\n * formula evaluation for this entity. Sort key range is the host's\n * choice — typical use is small (e.g. -10 ... +10) to keep the\n * composite (layer asc, sortValue asc) ordering predictable; large\n * magnitudes work but cross-layer biasing should usually go through\n * `Layer` instead.\n *\n * Override priority (M-3 w23 transparent-sort algorithm):\n *\n * if (world.has(entity, SortKey)) {\n * sortValue = world.get(entity, SortKey).value;\n * } else {\n * sortValue = modeFormula(mode, transform, sprite);\n * }\n *\n * SortKey lives alongside Layer in the (layer, sortValue) composite\n * key — Layer remains the primary key, SortKey replaces the secondary\n * key. This means a `Layer { value: 100 }` foreground entity with\n * `SortKey { value: -99 }` still draws AFTER a `Layer { value: 0 }`\n * background entity; SortKey biases WITHIN a layer, not ACROSS layers.\n *\n * @example Minimal spawn (no override, use mode formula):\n * world.spawn({ component: SortKey, data: {} }); // yields value=0\n *\n * @example Bias one sprite above the JRPG Y-sort formula:\n * world.spawn(\n * { component: Transform, data: { pos: [0, 1, 0],\n * quat: [0, 0, 0, 1], scale: [1, 1, 1] } },\n * { component: Layer, data: { value: 0 } },\n * { component: SortKey, data: { value: -100 } },\n * );\n *\n * @example Spawn payload omitting SortKey — the 4-layer fallback fills 0:\n * // entity reads back SortKey only if explicitly attached;\n * // otherwise the mode-formula path is taken by transparent-sort.ts.\n */\nexport const SortKey = defineComponent('SortKey', {\n value: { type: 'f32', default: 0 },\n});\n","// @forgeax/engine-render - SpotLight (cone-restricted spot-light parameters).\n//\n// Schema: direction array<f32,3> + color array<f32,3> + intensity + range +\n// innerConeDeg + outerConeDeg (feat-20260709 M2: direction/color collapsed from\n// 6 per-axis scalar columns to two inline array<f32,3> columns). `position`\n// comes from the\n// Transform component; SpotLight requires a companion Transform on the same\n// entity (ECS query: `[Transform, SpotLight]`). Cone units are degrees on\n// the Component API surface (charter F1 prior-knowledge alignment with\n// Three.js); the host-side extract step pre-converts to `cosInner` /\n// `cosOuter` before GPU upload (plan-strategy section 8.2 naming convention\n// + D-3 host-side cone conversion).\n//\n// `range` units are meters; defaults to `10.0`. Runtime finite-range\n// attenuation is the Three r184 squared window; the KHR unsquared curve is an\n// import/reference boundary only. The cone falloff is layered on top with\n// `smoothstep(cosOuter, cosInner, dot(L, -direction))` (plan-strategy D-S4).\n//\n// 0 light + standard material -> physically correct black render. The\n// once-warn channel collapses to \"directionalCount + pointCount +\n// spotCount === 0\" (M5 / w25).\n//\n// feat-20260625-spot-light-shadow-mapping M1 w4: embedded castShadow (default true)\n// + 6 shadow fields (mapSize / depthBias / normalBias / nearPlane / farPlane /\n// pcfKernelSize) aligned with DirectionalLight vocabulary (plan-strategy D-6;\n// charter P4 consistent abstraction). Zero-config spawns cast spot shadows;\n// set castShadow:false to opt out (validate short-circuits on false, AC-03).\n// Shadow atlas cap of 4 is enforced at extract stage, not component layer (OOS-5).\n//\n// charter mapping: proposition 1 (single import + IDE autocomplete on\n// payload.outerConeDeg with no `as` cast) + proposition 3 (silent failure\n// -> explicit failure; spawn-time fail-fast on three bound violations) +\n// proposition 5 (consistent abstraction: outgoing direction semantics\n// shared with DirectionalLight; cone deg API + cos shader uniform\n// pre-conversion mirrors directional path's host-side `lightDir x intensity`\n// pre-multiplication).\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Cone-restricted spot light (KHR_lights_punctual `spot` type). Casts shadows\n * by default (castShadow defaults to true) — zero-config spawns project hard\n * PCF shadows through an independent spot depth atlas.\n *\n * `direction` @semantics outgoing -- points FROM light source TO the\n * scene (consistent with `DirectionalLight`; the shader internally negates\n * this vector to obtain the L vector for BRDF evaluation:\n * `let l = normalize(-light.direction)`). Extract owns the single\n * normalization step for the snapshot; URP and HDRP consume that normalized\n * value without re-normalizing. `position` source: the companion\n * `Transform` component on the same entity.\n *\n * `innerConeDeg` is the half-angle of the saturated bright region (cone\n * fully bright at the axis); `outerConeDeg` is the half-angle of the\n * falloff edge (cone fully dark beyond). Unit is **degrees**;\n * `outerConeDeg in (innerConeDeg, 90]` (KHR upper bound; spawn-time\n * validation rejects `outer > 90` and `outer <= inner`). The host-side\n * extract step converts both to `cos*` before GPU upload so the shader\n * only sees pre-computed cosines (plan-strategy D-S2 byte freeze; charter\n * P4 host pre-multiplication parity).\n *\n * `color` is linear-space rgb in `[0, 1]` per channel; `intensity` is candela;\n * `range` is in meters and defaults to `10.0`. Exposure is a camera output\n * operation and does not change the stored intensity.\n *\n * Shadow fields (embedded, aligned with DirectionalLight):\n * castShadow ∈ {true, false} — shadow opt-out gate (default true)\n * mapSize >= 1 — shadow map resolution per tile (default 2048)\n * depthBias — shadow acne bias (default 0.005)\n * normalBias — shadow acne normal offset (default 0.05)\n * nearPlane — shadow-camera near (default 0.1)\n * farPlane — shadow-camera far (default 50)\n * pcfKernelSize odd >= 1 — PCF kernel width (default 3)\n *\n * Atlas capacity is capped at 4 castShadow spot lights by the extract stage;\n * the 5th light onward keeps direct illumination but shadowAtlasTile = -1\n * (AC-05: clip is programmatically detectable, light stays visible).\n *\n * @example Spawn a single spot light casting shadows (zero-config):\n * world.spawn(\n * { component: Transform, data: { pos: [0, 5, 0] } },\n * { component: SpotLight, data: { direction: [0, -1, 0] } }, // [x, y, z]\n * );\n *\n * @example Opt out of shadows:\n * world.spawn(\n * { component: Transform, data: { pos: [0, 5, 0] } },\n * { component: SpotLight, data: { direction: [0, -1, 0], castShadow: false } },\n * );\n *\n * @example Explicit shadow config:\n * world.spawn(\n * { component: Transform, data: { pos: [0, 5, 0] } },\n * { component: SpotLight, data: { direction: [0, -1, 0], depthBias: 0.01, normalBias: 0.08, mapSize: 1024 } },\n * );\n *\n * @example Minimal spawn -- defaults give neutral white at full strength, range 10m, KHR pi/4 cone:\n * world.spawn(\n * { component: Transform, data: { pos: [0, 5, 0] } },\n * { component: SpotLight, data: { direction: [0, -1, 0] } }, // [x, y, z]\n * );\n * // resolves to color=[1,1,1], intensity=1, range=10.0,\n * // innerConeDeg=0, outerConeDeg=45 (KHR pi/4 equivalent).\n */\nexport const SpotLight = defineComponent('SpotLight', {\n // direction has no default (D-5): omitting it lands the array layer-3\n // all-zero, which validate() rejects. color carries an explicit layer-2\n // default [1,1,1] (white); the array layer-3 fallback is all-zero.\n direction: { type: 'array<f32, 3>' },\n color: { type: 'array<f32, 3>', default: new Float32Array([1, 1, 1]) },\n intensity: { type: 'f32', default: 1 },\n range: { type: 'f32', default: 10.0 },\n innerConeDeg: { type: 'f32', default: 0 },\n outerConeDeg: { type: 'f32', default: 45 },\n // Shadow opt-out gate: defaults to true so zero-config spawns cast shadows.\n castShadow: { type: 'bool', default: true },\n // 6 shadow fields aligned with DirectionalLight (plan-strategy D-6).\n mapSize: { type: 'f32', default: 2048 },\n depthBias: { type: 'f32', default: 0.005 },\n normalBias: { type: 'f32', default: 0.05 },\n nearPlane: { type: 'f32', default: 0.1 },\n farPlane: { type: 'f32', default: 50 },\n pcfKernelSize: { type: 'f32', default: 3 },\n});\n","import { defineComponent } from '@forgeax/engine-ecs';\n\n/** Numeric labels stored by the public Visibility enum field. */\nexport const VisibilityStateValue = Object.freeze({\n inherited: 0,\n hidden: 1,\n visible: 2,\n} as const);\n\n/** Author visibility intent accepted by the Visibility component. */\nexport type VisibilityState = keyof typeof VisibilityStateValue;\n\n/**\n * Decode the stored u32 without treating an unknown value as a valid state.\n * Invalid values are rejected at ECS write boundaries; undefined remains an\n * explicit signal for readers that inspect externally corrupted columns.\n */\nexport function visibilityStateFromU32(value: number): VisibilityState | undefined {\n switch (value) {\n case VisibilityStateValue.inherited:\n return 'inherited';\n case VisibilityStateValue.hidden:\n return 'hidden';\n case VisibilityStateValue.visible:\n return 'visible';\n default:\n return undefined;\n }\n}\n\n/**\n * Author intent for render participation. Omitted state is inherited and is\n * therefore visible when no valid parent intent is available.\n */\nexport const Visibility = defineComponent(\n 'Visibility',\n {\n state: {\n type: 'enum',\n default: VisibilityStateValue.inherited,\n labels: VisibilityStateValue,\n },\n },\n {\n meta: {\n quickStart: 'Attach Visibility to author render participation intent.',\n diagnostics: 'Compare the ECS state with resolveVisibility and renderer.visibilityStats.',\n recovery: 'Use structured ECS write errors and repair the owning scene relation.',\n boundaries:\n 'Visibility does not own camera, picking, lifecycle, assets, or VFX shadow policy.',\n },\n },\n);\n","import type {\n MaterialAsset,\n MaterialColorSpace,\n MaterialParameter,\n MaterialPass,\n MaterialRenderState,\n MaterialTextureValue,\n MaterialValue,\n} from '@forgeax/engine-types';\n\nexport const SPRITE_PREMULTIPLIED_ALPHA_BLEND: GPUBlendState = {\n color: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha', operation: 'add' },\n alpha: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha', operation: 'add' },\n};\n\nconst STANDARD_MODULE = 'forgeax_material::standard';\nconst UNLIT_MODULE = 'forgeax_material::unlit';\nconst SPRITE_MODULE = 'forgeax_material::sprite';\n\nexport function materialTextureValue(value: MaterialValue): MaterialValue;\nexport function materialTextureValue(value: string): MaterialValue;\nexport function materialTextureValue(value: undefined): undefined;\nexport function materialTextureValue(\n value: MaterialValue | string | undefined,\n): MaterialValue | undefined {\n if (value === undefined) return undefined;\n if (typeof value === 'string') return value;\n if (typeof value === 'number') {\n return { texture: value as unknown as MaterialTextureValue['texture'] };\n }\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return value;\n return value;\n}\n\nfunction authoredColorParameter(\n name: string,\n type: 'color' | 'vec3',\n colorSpace: MaterialColorSpace,\n optional = false,\n): MaterialParameter {\n return {\n name,\n type,\n ...(type === 'color' && colorSpace === 'srgb' ? {} : { colorSpace }),\n ...(optional ? { optional: true } : {}),\n };\n}\n\nfunction standardParameters(colorSpace: MaterialColorSpace): readonly MaterialParameter[] {\n return [\n authoredColorParameter('baseColor', 'color', colorSpace),\n { name: 'metallic', type: 'f32' },\n { name: 'roughness', type: 'f32' },\n { name: 'metallicChannel', type: 'f32', optional: true },\n { name: 'roughnessChannel', type: 'f32', optional: true },\n { name: 'aoChannel', type: 'f32', optional: true },\n { name: 'extraChannel', type: 'f32', optional: true },\n authoredColorParameter('emissive', 'vec3', colorSpace, true),\n { name: 'emissiveIntensity', type: 'f32', optional: true },\n { name: 'occlusionStrength', type: 'f32', optional: true },\n { name: 'alphaCutoff', type: 'f32', optional: true },\n { name: 'clearcoat', type: 'f32', optional: true },\n { name: 'clearcoatRoughness', type: 'f32', optional: true },\n authoredColorParameter('specularTint', 'vec3', colorSpace, true),\n { name: 'baseColorTexture', type: 'texture', optional: true },\n { name: 'metallicRoughnessTexture', type: 'texture', optional: true },\n { name: 'normalTexture', type: 'texture', optional: true },\n { name: 'specularTintTexture', type: 'texture', optional: true },\n { name: 'emissiveTexture', type: 'texture', optional: true },\n { name: 'occlusionTexture', type: 'texture', optional: true },\n ];\n}\n\nfunction unlitParameters(colorSpace: MaterialColorSpace): readonly MaterialParameter[] {\n return [\n authoredColorParameter('baseColor', 'color', colorSpace),\n { name: 'alphaCutoff', type: 'f32', optional: true },\n { name: 'baseColorTexture', type: 'texture', optional: true },\n ];\n}\n\nfunction pass(\n name: string,\n module: string,\n renderState: MaterialRenderState | undefined,\n fragmentEntry?: string,\n queue?: number,\n): MaterialPass {\n const lightMode =\n name === 'shadow-caster' ? 'ShadowCaster' : name === 'deferred' ? 'Deferred' : 'Forward';\n const authoredState = (renderState ?? {}) as Readonly<Record<string, unknown>>;\n const authoredTags = authoredState.tags as Readonly<Record<string, string>> | undefined;\n return {\n name,\n program: {\n module,\n ...(fragmentEntry === undefined ? {} : { fragmentEntry }),\n },\n renderState: {\n ...authoredState,\n tags: { LightMode: lightMode, ...authoredTags },\n ...(queue === undefined ? {} : { queue }),\n },\n };\n}\n\ninterface UnlitOpts {\n /** Asset-side authored color space. Defaults to sRGB. */\n readonly colorSpace?: MaterialColorSpace;\n readonly castShadow?: boolean;\n readonly baseColorTexture?: MaterialValue;\n readonly alphaCutoff?: number;\n readonly renderState?: MaterialRenderState;\n readonly queue?: number;\n}\n\nfunction unlit(rgba: readonly [number, number, number, number], opts?: UnlitOpts): MaterialAsset {\n if (opts?.alphaCutoff !== undefined && (opts.alphaCutoff < 0 || opts.alphaCutoff > 1)) {\n throw new Error(`Materials.unlit: alphaCutoff must be in [0, 1], got ${opts.alphaCutoff}`);\n }\n const values: Record<string, MaterialValue> = { baseColor: rgba };\n if (opts?.baseColorTexture !== undefined) {\n values.baseColorTexture = materialTextureValue(opts.baseColorTexture);\n }\n if (opts?.alphaCutoff !== undefined) values.alphaCutoff = opts.alphaCutoff;\n const passes: [MaterialPass, ...MaterialPass[]] = [\n pass('forward', UNLIT_MODULE, opts?.renderState, undefined, opts?.queue),\n ];\n if (opts?.castShadow !== false) passes.push(pass('shadow-caster', UNLIT_MODULE, undefined));\n return {\n kind: 'material',\n ...(opts?.colorSpace === undefined || opts.colorSpace === 'srgb'\n ? {}\n : { colorSpace: opts.colorSpace }),\n passes,\n parameters: unlitParameters(opts?.colorSpace ?? 'srgb'),\n values,\n };\n}\n\ninterface StandardOpts {\n /** Asset-side authored color space for baseColor/emissive/specularTint. Defaults to sRGB. */\n readonly colorSpace?: MaterialColorSpace;\n readonly baseColor: readonly [number, number, number, number];\n readonly metallic?: number;\n readonly roughness?: number;\n /** Texture channel used for the metallic factor; glTF defaults to B (2). */\n readonly metallicChannel?: number;\n /** Texture channel used for the roughness factor; glTF defaults to G (1). */\n readonly roughnessChannel?: number;\n readonly clearcoat?: number;\n readonly clearcoatRoughness?: number;\n readonly specularTint?: readonly [number, number, number];\n readonly specularTintTexture?: MaterialValue;\n readonly emissive?: readonly [number, number, number];\n readonly emissiveIntensity?: number;\n readonly emissiveTexture?: MaterialValue;\n readonly baseColorTexture?: MaterialValue;\n readonly metallicRoughnessTexture?: MaterialValue;\n readonly normalTexture?: MaterialValue;\n readonly occlusionTexture?: MaterialValue;\n readonly occlusionStrength?: number;\n readonly alphaCutoff?: number;\n readonly renderState?: MaterialRenderState;\n readonly castShadow?: boolean;\n readonly queue?: number;\n}\n\nfunction validateChannel(\n name: 'metallicChannel' | 'roughnessChannel',\n value: number | undefined,\n): void {\n if (value !== undefined && (!Number.isInteger(value) || value < 0 || value > 3)) {\n throw new Error(`Materials.standard: ${name} must be an integer in [0, 3], got ${value}`);\n }\n}\n\nfunction standard(opts: StandardOpts): MaterialAsset {\n const occlusionStrength = opts.occlusionStrength ?? 1;\n if (occlusionStrength < 0 || occlusionStrength > 1) {\n throw new Error(\n `Materials.standard: occlusionStrength must be in [0, 1], got ${occlusionStrength}`,\n );\n }\n if (opts.alphaCutoff !== undefined && (opts.alphaCutoff < 0 || opts.alphaCutoff > 1)) {\n throw new Error(`Materials.standard: alphaCutoff must be in [0, 1], got ${opts.alphaCutoff}`);\n }\n validateChannel('metallicChannel', opts.metallicChannel);\n validateChannel('roughnessChannel', opts.roughnessChannel);\n const values: Record<string, MaterialValue> = {\n baseColor: opts.baseColor,\n metallic: opts.metallic ?? 0,\n roughness: opts.roughness ?? 0.5,\n occlusionStrength,\n specularTint: opts.specularTint ?? [1, 1, 1],\n };\n if (opts.metallicChannel !== undefined) values.metallicChannel = opts.metallicChannel;\n if (opts.roughnessChannel !== undefined) values.roughnessChannel = opts.roughnessChannel;\n if (opts.clearcoat !== undefined) values.clearcoat = opts.clearcoat;\n if (opts.clearcoatRoughness !== undefined) values.clearcoatRoughness = opts.clearcoatRoughness;\n if (opts.emissive !== undefined) values.emissive = opts.emissive;\n if (opts.emissiveIntensity !== undefined) values.emissiveIntensity = opts.emissiveIntensity;\n if (opts.emissiveTexture !== undefined)\n values.emissiveTexture = materialTextureValue(opts.emissiveTexture);\n if (opts.baseColorTexture !== undefined)\n values.baseColorTexture = materialTextureValue(opts.baseColorTexture);\n if (opts.metallicRoughnessTexture !== undefined) {\n values.metallicRoughnessTexture = materialTextureValue(opts.metallicRoughnessTexture);\n }\n if (opts.normalTexture !== undefined)\n values.normalTexture = materialTextureValue(opts.normalTexture);\n if (opts.occlusionTexture !== undefined)\n values.occlusionTexture = materialTextureValue(opts.occlusionTexture);\n if (opts.specularTintTexture !== undefined) {\n values.specularTintTexture = materialTextureValue(opts.specularTintTexture);\n }\n if (opts.alphaCutoff !== undefined) values.alphaCutoff = opts.alphaCutoff;\n const passes: [MaterialPass, ...MaterialPass[]] = [\n pass('forward', STANDARD_MODULE, opts.renderState, 'fs_main', opts.queue),\n pass('deferred', STANDARD_MODULE, opts.renderState, 'fs_gbuffer', opts.queue),\n ];\n if (opts.castShadow !== false) passes.push(pass('shadow-caster', STANDARD_MODULE, undefined));\n return {\n kind: 'material',\n ...(opts.colorSpace === undefined || opts.colorSpace === 'srgb'\n ? {}\n : { colorSpace: opts.colorSpace }),\n passes,\n parameters: standardParameters(opts.colorSpace ?? 'srgb'),\n values,\n };\n}\n\nexport const Materials = { unlit, standard } as const;\n\nexport { SPRITE_MODULE };\n","import type { World } from '@forgeax/engine-ecs';\nimport type { Asset, Handle, Result } from '@forgeax/engine-types';\n\nexport type RenderAssetResolutionError =\n ReturnType<World['sharedRefs']['resolve']> extends Result<unknown, infer E> ? E : never;\n\n/** Resolve a render handle through the World that owns its shared-reference lifetime. */\nexport function resolveRenderAsset<T extends Asset>(\n world: World,\n handle: Handle<string, 'shared'>,\n): Result<T, RenderAssetResolutionError> {\n return world.sharedRefs.resolve<string, T>(handle) as Result<T, RenderAssetResolutionError>;\n}\n","// @forgeax/engine-runtime - glyphTextLayoutSystem\n// (feat-20260531-world-space-msdf-text-rendering M4 / w18).\n//\n// The named ECS system that turns `GlyphText` authoring data into a rendered\n// world-space label (plan-strategy D-2). A Renderer attaches it to World's\n// internal render-derived phase,\n// so a freshly-spawned `GlyphText` entity gains its `MeshFilter` +\n// `MeshRenderer` before final publication resolves transforms and the same frame's\n// read-only render walk reaches it. Per `GlyphText` entity:\n//\n// 1. First observation (entity has no `MeshFilter`): resolve the FontAsset,\n// run `layoutGlyphText` (w15) + `bakeGlyphMesh` (w17), then attach\n// `MeshFilter` + `MeshRenderer` (AC-07). The attach uses the same\n// immediate `world.addComponent` path as `spriteAnimationTickSystem`'s\n// auto-add (the system runs ahead of the render walk in the same frame).\n// 2. Dirty (text / fontSize / color changed since last bake): re-layout and\n// `updateMesh` IN PLACE (plan-strategy D-1) -- never re-`register`, never\n// re-attach. The AssetRegistry size stays constant (AC-08; avoids the\n// unbounded growth R-1 would otherwise cause).\n//\n// D-8 concurrency: at most 8 distinct FontAsset handles may be active in one\n// frame. The system resets the per-frame tracker (resetFontConcurrency) at the\n// top and tracks each distinct font; the 9th distinct font surfaces a\n// structured `TextError('font-concurrency-exceeded')` (it does NOT silently\n// evict the oldest font).\n//\n// The system does NOT modify `pick.ts` (D-5): the baked mesh carries a local\n// AABB and the entity carries MeshFilter + MeshRenderer + Transform, so the\n// existing `pick()` raycast walk catches it for free.\n\nimport type { EntityHandle, World } from '@forgeax/engine-ecs';\nimport { PROCEDURAL_FLOATS_PER_VERTEX } from '@forgeax/engine-geometry';\nimport {\n bakeGlyphMesh,\n conservativeCubeAabb,\n layoutGlyphText,\n resetFontConcurrency,\n trackFontConcurrency,\n} from '@forgeax/engine-graphics-extras';\nimport type { FontAsset, Handle, MaterialAsset, MeshAsset, Submesh } from '@forgeax/engine-types';\nimport { err, ok, type Result, TextError, unpackSlot } from '@forgeax/engine-types';\nimport { resolveRenderAsset } from './assets/resolve-render-asset';\nimport { MeshFilter, MeshRenderer } from './components';\nimport { GlyphText } from './components/glyph-text';\nimport type { GpuResourceStore } from './gpu-resource-store';\nimport { materialTextureValue } from './materials';\n\n// Per-entity bake bookkeeping: the baked mesh handle id + the authoring\n// signature it was baked from. A WeakMap owns one cache per World and each\n// entry is bounded by entity slot while retaining the full generation-bearing\n// EntityHandle, so slot reuse replaces stale state instead of aliasing it or\n// growing one historical entry per generation.\ninterface BakeRecord {\n readonly meshHandleId: number;\n signature: string;\n /** The MeshRenderer.material handle assigned on first observation. */\n readonly materialHandleId: number;\n}\ninterface BakeCacheEntry {\n readonly handle: EntityHandle;\n readonly record: BakeRecord;\n}\nlet bakeCache = new WeakMap<World, Map<number, BakeCacheEntry>>();\n\n// One current material producer handle per GlyphText entity slot. Continuous\n// tint edits replace and release the previous producer instead of growing a\n// historical color-key cache.\nlet materialCache = new WeakMap<World, Map<number, number>>();\nlet liveGlyphHandles = new WeakMap<World, Set<number>>();\n\n/** Clear the per-entity bake + per-font material caches (test isolation). */\nexport function resetGlyphBakeCache(): void {\n bakeCache = new WeakMap();\n materialCache = new WeakMap();\n liveGlyphHandles = new WeakMap();\n}\n\nfunction worldBakeCache(world: World): Map<number, BakeCacheEntry> {\n let cache = bakeCache.get(world);\n if (cache === undefined) {\n cache = new Map();\n bakeCache.set(world, cache);\n }\n return cache;\n}\n\nfunction worldMaterialCache(world: World): Map<number, number> {\n let cache = materialCache.get(world);\n if (cache === undefined) {\n cache = new Map();\n materialCache.set(world, cache);\n }\n return cache;\n}\n\n/** Release renderer-derived producer refs at GlyphText removal time. */\nfunction releaseGlyphProducers(world: World, entity: EntityHandle): void {\n const slot = unpackSlot(entity as unknown as number);\n const bake = bakeCache.get(world)?.get(slot);\n if (bake?.handle === entity) {\n world.sharedRefs.release(asMeshHandle(bake.record.meshHandleId));\n bakeCache.get(world)?.delete(slot);\n }\n const material = materialCache.get(world)?.get(slot);\n if (material !== undefined) {\n world.sharedRefs.release(asMaterialHandle(material));\n materialCache.get(world)?.delete(slot);\n }\n}\n\n/** Remove stale renderer-derived state when a previously baked font is rejected. */\nfunction clearRejectedGlyphState(world: World, entity: EntityHandle): void {\n const slot = unpackSlot(entity as unknown as number);\n const bake = bakeCache.get(world)?.get(slot);\n if (bake?.handle !== entity) return;\n\n // These components are owned by this system only when the matching bake\n // record exists. Removing them before releasing the producer refs leaves no\n // stale draw/material handles and lets the next valid frame take the normal\n // first-observation path.\n if (world.get(entity, MeshFilter).ok) world.removeComponent(entity, MeshFilter);\n if (world.get(entity, MeshRenderer).ok) world.removeComponent(entity, MeshRenderer);\n releaseGlyphProducers(world, entity);\n}\n\n// Premultiplied-alpha blend (mirrors the sprite path, plan D-7). The\n// `forgeax::msdf-text` fragment emits premultiplied RGB so the over-composite\n// math (`dst' = src + dst * (1 - src.a)`) is direct. The pass rides the\n// Transparent queue (3000) so text composites after opaque geometry while\n// honoring depth occlusion (depthCompare less-equal, depthWrite off via the\n// material-shader pipeline render state).\nconst MSDF_TEXT_BLEND = {\n color: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha', operation: 'add' },\n alpha: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha', operation: 'add' },\n} as const;\n\ninterface GlyphTextData {\n readonly fontHandle: number;\n readonly text: string;\n readonly fontSize: number;\n // feat-20260709 M3: color collapsed into one inline array<f32,4>; the\n // world.get read path materialises it as a Float32Array (color[0..3] = rgba).\n readonly color: ArrayLike<number>;\n}\n\n/**\n * Lay out + bake every `GlyphText` entity, attaching MeshFilter + MeshRenderer\n * on first observation and re-baking in place on a text / size / color change.\n *\n * @param world The ECS world holding the GlyphText entities.\n * @returns `ok(void)` on a clean pass, or `err(TextError)` carrying the FIRST\n * structured failure (currently only `font-concurrency-exceeded`). Healthy\n * entities observed before the failing one are still baked.\n */\nexport function glyphTextLayoutSystem(\n world: World,\n gpuStore: GpuResourceStore,\n): Result<void, TextError> {\n resetFontConcurrency();\n\n // No GlyphText entity in this World -> empty collection -> no-op pass. The\n // former per-World `_getComponentByName(GlyphText.name)` registration probe\n // is gone (feat-20260602 dropped the registered concept); column presence is\n // read directly from the archetype graph by `collectGlyphEntities`.\n const entities = collectGlyphEntities(world);\n const live = liveGlyphHandles.get(world) ?? new Set<number>();\n live.clear();\n for (const entity of entities) live.add(entity as unknown as number);\n liveGlyphHandles.set(world, live);\n for (const entry of worldBakeCache(world).values()) {\n if (!live.has(entry.handle as unknown as number)) releaseGlyphProducers(world, entry.handle);\n }\n\n let firstError: TextError | null = null;\n for (const entity of entities) {\n const error = processEntity(world, gpuStore, entity);\n if (error !== null && firstError === null) firstError = error;\n }\n\n if (firstError !== null) return err(firstError);\n return ok(undefined);\n}\n\n/** Collect every Entity handle carrying GlyphText (single archetype walk). */\nfunction collectGlyphEntities(world: World): EntityHandle[] {\n const query = world.query({ read: [GlyphText] });\n if (!query.ok) return [];\n const entities: EntityHandle[] = [];\n for (const row of query.value) entities.push(row.entity);\n return entities;\n}\n\n/**\n * Process one GlyphText entity. Returns a TextError when the concurrency limit\n * is exceeded after clearing any stale derived state; returns null otherwise.\n */\nfunction processEntity(\n world: World,\n gpuStore: GpuResourceStore,\n entity: EntityHandle,\n): TextError | null {\n const gtRes = world.get(entity, GlyphText);\n if (!gtRes.ok) return null;\n const gt = gtRes.value as unknown as GlyphTextData;\n\n // Unresolved font handle (zero sentinel) -> skip (entity not yet wired).\n if (gt.fontHandle === 0) return null;\n\n // D-8 concurrency: track this distinct font; the 9th throws a TextError.\n try {\n trackFontConcurrency(gt.fontHandle);\n } catch (e) {\n if (e instanceof TextError) {\n clearRejectedGlyphState(world, entity);\n return e;\n }\n throw e;\n }\n\n const fontRes = resolveRenderAsset<FontAsset>(world, asFontHandle(gt.fontHandle));\n if (!fontRes.ok) return null; // font not registered yet -> skip silently\n const font = fontRes.value;\n\n const signature = signatureOf(gt);\n const entityCache = worldBakeCache(world);\n const slot = unpackSlot(entity as unknown as number);\n const cachedEntry = entityCache.get(slot);\n if (cachedEntry !== undefined && cachedEntry.handle !== entity) {\n world.sharedRefs.release(asMeshHandle(cachedEntry.record.meshHandleId));\n const staleMaterial = worldMaterialCache(world).get(slot);\n if (staleMaterial !== undefined) {\n world.sharedRefs.release(asMaterialHandle(staleMaterial));\n worldMaterialCache(world).delete(slot);\n }\n entityCache.delete(slot);\n }\n const cached = cachedEntry?.handle === entity ? cachedEntry.record : undefined;\n\n // Dirty path: same entity already baked, but the authoring signature changed.\n if (cached !== undefined) {\n ensureGlyphMeshMaterialSlots(world, asMeshHandle(cached.meshHandleId));\n if (cached.signature === signature) return null; // clean -> nothing to do\n const layout = layoutGlyphText(font, gt.text, gt.fontSize);\n // feat-20260601-gpu-resource-store-extraction M1: in-place GPU mesh update\n // moved to the store. The mesh became GPU-resident on the first render\n // frame's `ensureResident` pull; the dirty re-layout overwrites those\n // buffers in place (a no-op if not yet resident -- the next render's\n // ensureResident then uploads the latest registered POD).\n const meshHandle = asMeshHandle(cached.meshHandleId);\n const submeshes = [\n {\n indexOffset: 0,\n indexCount: layout.indices.length,\n vertexCount: layout.vertices.length / PROCEDURAL_FLOATS_PER_VERTEX,\n topology: 'triangle-list',\n materialSlot: 0,\n },\n ] satisfies readonly Submesh[];\n // A dynamic label can begin empty, so its first bake has a degenerate AABB.\n // Keep the shared MeshAsset's culling/picking bounds in lockstep with the\n // dirty layout; otherwise the GPU buffers update but the render walk still\n // rejects the label as an empty mesh.\n const mesh = world.sharedRefs.resolve<'MeshAsset', MeshAsset>(meshHandle);\n if (!mesh.ok) return null;\n // Consume the Result before publishing the new CPU POD. A resident shape\n // change takes the explicit transactional replacement path; a nonresident\n // mesh can publish directly because ensureResident will pull this POD.\n if (!updateGlyphMesh(gpuStore, meshHandle, layout.vertices, layout.indices, submeshes)) {\n return null;\n }\n const aabb = conservativeCubeAabb(layout.radius);\n Object.assign(mesh.value, {\n vertices: layout.vertices,\n indices: layout.indices,\n submeshes,\n materialSlots: [{ slotName: 'Default' }],\n aabb,\n });\n // A color change replaces the material payload at this entity's stable\n // derived slot and re-binds the new producer handle in place.\n const materialId = resolveTextMaterial(world, gt, font, slot);\n if (materialId !== cached.materialHandleId) {\n world.set(entity, MeshRenderer, {\n materials: [materialId] as unknown as never,\n });\n }\n entityCache.set(slot, {\n handle: entity,\n record: {\n meshHandleId: cached.meshHandleId,\n signature,\n materialHandleId: materialId,\n },\n });\n return null;\n }\n\n // First-observation path. If this entity already carries a MeshFilter (e.g.\n // the bake cache was reset between frames), skip without re-baking. `world.get`\n // returns err(component-not-present) (never throws) when the column is absent,\n // so the column probe needs no registration guard (feat-20260602).\n const existingFilter = world.get(entity, MeshFilter);\n if (existingFilter.ok) {\n ensureGlyphMeshMaterialSlots(\n world,\n asMeshHandle((existingFilter.value as { assetHandle: number }).assetHandle),\n );\n return null;\n }\n\n const layout = layoutGlyphText(font, gt.text, gt.fontSize);\n const bake = bakeGlyphMesh(world, layout);\n if (!bake.ok) return null; // register fail-fast (should not happen for w15 output)\n\n // F-1: resolve the entity-owned MSDF MaterialAsset so the\n // `forgeax::msdf-text` shader + atlas texture + sampler are bound to this\n // text entity (plan D-7). Without this the MeshRenderer would carry material\n // handle 0 -> default mid-grey unlit, and the atlas would never be sampled.\n const materialId = resolveTextMaterial(world, gt, font, slot);\n\n world.addComponent(entity, { component: MeshFilter, data: { assetHandle: bake.value.handle } });\n world.addComponent(entity, {\n component: MeshRenderer,\n data: { materials: [materialId] as unknown as never },\n });\n entityCache.set(slot, {\n handle: entity,\n record: {\n meshHandleId: handleId(bake.value.handle),\n signature,\n materialHandleId: materialId,\n },\n });\n return null;\n}\n\n/** Apply a dirty glyph mesh atomically across the GPU residency boundary. */\nfunction updateGlyphMesh(\n gpuStore: GpuResourceStore,\n meshHandle: Handle<'MeshAsset', 'shared'>,\n vertices: Float32Array,\n indices: Uint16Array | Uint32Array,\n submeshes: readonly Submesh[],\n): boolean {\n const updated = gpuStore.updateMesh(meshHandle, vertices, indices, 0, submeshes);\n if (updated.ok) return true;\n if (updated.error.code === 'mesh-shape-mismatch') {\n const replaced = gpuStore.replaceMesh(meshHandle, vertices, indices, 0, submeshes);\n if (replaced.ok) return true;\n return (\n replaced.error.code === 'mesh-not-resident' || replaced.error.code === 'rhi-not-available'\n );\n }\n return updated.error.code === 'mesh-not-resident' || updated.error.code === 'rhi-not-available';\n}\n\nexport function ensureGlyphMeshMaterialSlots(\n world: World,\n meshHandle: Handle<'MeshAsset', 'shared'>,\n): void {\n const mesh = world.sharedRefs.resolve<'MeshAsset', MeshAsset>(meshHandle);\n if (mesh.ok && !Array.isArray(mesh.value.materialSlots)) {\n Object.assign(mesh.value, { materialSlots: [{ slotName: 'Default' }] });\n }\n}\n\n/**\n * Build the MSDF text MaterialAsset for one World/entity slot and\n * return its raw unmanaged handle id. The material carries a single\n * Transparent-queue pass on the `forgeax::msdf-text` shader with premultiplied\n * blend, and values binding the tint color, packed atlas distance data, and an\n * embedded atlas texture reference (the record stage supplies the sampler).\n * HDR tint components (>1) flow through unchanged so bloom-enabled cameras\n * pick up bright text (AC-12).\n */\nfunction resolveTextMaterial(\n world: World,\n gt: GlyphTextData,\n font: FontAsset,\n slot: number,\n): number {\n const cache = worldMaterialCache(world);\n const material = {\n kind: 'material',\n passes: [\n {\n name: 'text',\n program: { module: 'forgeax::msdf-text' },\n renderState: {\n ...{\n blend: MSDF_TEXT_BLEND as never,\n cullMode: 'none',\n depthWriteEnabled: false,\n depthCompare: 'less-equal',\n },\n tags: { LightMode: 'Forward' },\n queue: 3000,\n },\n },\n ],\n values: {\n tintColor: [gt.color[0] ?? 1, gt.color[1] ?? 1, gt.color[2] ?? 1, gt.color[3] ?? 1],\n distanceRange: [\n font.common.distanceRange,\n font.common.atlasWidth,\n font.common.atlasHeight,\n 0,\n ],\n baseColorTexture: materialTextureValue({ texture: font.atlas }),\n },\n parameters: [\n { name: 'tintColor', type: 'color', default: [1, 1, 1, 1] },\n { name: 'distanceRange', type: 'vec4', default: [4, 512, 512, 0] },\n { name: 'baseColorTexture', type: 'texture' },\n { name: 'metallicRoughnessTexture', type: 'texture', optional: true },\n { name: 'normalTexture', type: 'texture', optional: true },\n ],\n } satisfies MaterialAsset;\n const id = world.allocSharedRef('MaterialAsset', material) as unknown as number;\n const previous = cache.get(slot);\n cache.set(slot, id);\n if (previous !== undefined && previous !== id) {\n world.sharedRefs.release(asMaterialHandle(previous));\n }\n return id;\n}\n\nfunction signatureOf(gt: GlyphTextData): string {\n return `${gt.fontHandle}|${gt.fontSize}|${gt.text}|${gt.color[0]},${gt.color[1]},${gt.color[2]},${gt.color[3]}`;\n}\n\n// Handle bridges: GlyphText.fontHandle / cached mesh ids are packed u32 values;\n// AssetRegistry expects branded Handles. The brand is a compile-time phantom\n// (runtime value is the raw number), so a cast is the canonical bridge\n// (mirrors pick.ts toShared).\nfunction asFontHandle(raw: number): Handle<'FontAsset', 'shared'> {\n return raw as unknown as Handle<'FontAsset', 'shared'>;\n}\nfunction asMeshHandle(id: number): Handle<'MeshAsset', 'shared'> {\n return id as unknown as Handle<'MeshAsset', 'shared'>;\n}\nfunction asMaterialHandle(id: number): Handle<'MaterialAsset', 'shared'> {\n return id as unknown as Handle<'MaterialAsset', 'shared'>;\n}\nfunction handleId(handle: Handle<'MeshAsset', 'shared'>): number {\n return handle as unknown as number;\n}\n","// @forgeax/engine-runtime - TransparentSortConfig KV resource + helpers.\n//\n// feat-20260520-2d-sprite-layer-mvp M-2 w14 / requirements AC-08 + AC-18\n// path (2)/(3) + AC-19 derivation audit (5).\n//\n// Surface:\n// - interface TransparentSortConfig { mode: number; yzAlpha: number }\n// - constant TRANSPARENT_SORT_CONFIG_KEY = 'TransparentSortConfig'\n// - constants TRANSPARENT_SORT_MODE_LAYER_Z = 0 (horizontal-z)\n// TRANSPARENT_SORT_MODE_LAYER_Y = 1 (Y-sort)\n// TRANSPARENT_SORT_MODE_LAYER_YZ = 2 (Y-Z blend)\n// - helper getTransparentSortConfig(world): TransparentSortConfig\n// - helper setTransparentSortConfig(world, cfg):\n// Result<void, ResourceInvalidValueError>\n//\n// 5-view selection table (charter F1 progressive disclosure for AI users\n// reading IDE hover on this header; same SSOT mirrored in\n// apps/hello/sprite/README.md M-4 w33):\n//\n// | view | mode | yzAlpha | sortValue formula |\n// |:------------------|:----:|:-------:|:--------------------------------|\n// | horizontal (side) | 0 | --- | posZ |\n// | top-down | 1 | --- | -(posY - pivot.y * size.y) |\n// | Don't Starve | 2 | 1.0 | (posY - pivot.y * size.y) + posZ|\n// | isometric | 2 | 0.5 | (posY - pivot.y * size.y) + 0.5*posZ |\n// | JRPG (foot pivot) | 1 | --- | -(posY - pivot.y * size.y) |\n//\n// AC-18 path (2): @fallback getTransparentSortConfig KV missing returns\n// default; no warn; no throw (legal default state, not an error state).\n// AC-18 path (3): @fallback setTransparentSortConfig mode out-of-range\n// does NOT silently coerce to mode=0 — returns Result.err with the\n// 4 SSOT fields locked by plan-strategy D-4 so AI users can self-repair\n// via .code / .expected / .hint / .detail property access (charter P3).\n// AC-18 path (3) carve-out: yzAlpha range is intentionally NOT validated;\n// mode=0 / mode=1 ignore the field entirely, mode=2 reads it, mode=3\n// (distance) also reads it for compat but ignores it (squared-distance\n// formula does not use yzAlpha). The silent-ignore is the documented\n// charter P3 \"legal default\" boundary.\n//\n// @new-surface KV resource: ECS has no defineResource factory at this\n// feat's commit time; the TS POD interface + string KV key form is the\n// minimum-new-surface route. The world resource store\n// (insertResource / getResource / hasResource) is reused unchanged\n// (requirements §2.2.G derivation row 5).\n// @derives world.hasResource / world.insertResource / world.getResource\n// KV API (packages/ecs/src/resource.ts + world.ts: insertResource l.490,\n// getResource l.498, hasResource l.503).\n// @fallback getTransparentSortConfig KV missing returns\n// { mode: 0, yzAlpha: 1.0 }; no warn; no throw.\n// @fallback setTransparentSortConfig mode out-of-range returns Result.err\n// with code='resource-invalid-value'; never silently coerced.\n//\n// charter mapping: F1 (single-import barrel + 5-view JSDoc table on\n// hover) + P3 (structured failure on mode out-of-range; legal-default\n// fallback distinguished from error fallback) + P4 (consistent\n// abstraction — same world.{has,get,insert}Resource KV API as every\n// other engine resource consumer).\n\nimport type { World } from '@forgeax/engine-ecs';\nimport type { Result } from '@forgeax/engine-types';\nimport { err, ok } from '@forgeax/engine-types';\nimport { ResourceInvalidValueError } from '../errors';\n\n// ────────────────────────────────────────────────────────────────────────────\n// POD interface + KV key + 3 named mode constants\n// ────────────────────────────────────────────────────────────────────────────\n\n/**\n * Transparent-bucket sort configuration (plain-data POD). Lives as a\n * world-level resource keyed by `TRANSPARENT_SORT_CONFIG_KEY`.\n *\n * Fields:\n * - `mode \\u2208 {0, 1, 2, 3}` selects the sort formula\n * (`TRANSPARENT_SORT_MODE_LAYER_Z` / `_LAYER_Y` / `_LAYER_YZ` / `_DISTANCE`).\n * - `yzAlpha` (mode=2 only) blends Y-axis into Z-axis: 1.0 weights\n * posZ equally with `posY - pivot.y * size.y` (Don't-Starve style),\n * 0.5 weights posZ at half (isometric). mode=0 / mode=1 ignore the\n * field (documented charter P3 legal-default boundary).\n */\nexport interface TransparentSortConfig {\n readonly mode: number;\n readonly yzAlpha: number;\n}\n\n/** World resource key for `TransparentSortConfig` KV entry. */\nexport const TRANSPARENT_SORT_CONFIG_KEY = 'TransparentSortConfig' as const;\n\n/** horizontal / side-scroller: sortValue = posZ. */\nexport const TRANSPARENT_SORT_MODE_LAYER_Z = 0;\n\n/** top-down / JRPG: sortValue = -(posY - pivot.y * size.y) (foot pivot Y-sort). */\nexport const TRANSPARENT_SORT_MODE_LAYER_Y = 1;\n\n/** Don't-Starve / isometric: sortValue = (posY - pivot.y * size.y) + yzAlpha * posZ. */\nexport const TRANSPARENT_SORT_MODE_LAYER_YZ = 2;\n\n/** 3D distance: sortValue = -(dist^2) to cameraPos, back-to-front (far first). */\nexport const TRANSPARENT_SORT_MODE_DISTANCE = 3;\n\n// ────────────────────────────────────────────────────────────────────────────\n// Internal: silent default + mode validity check\n// ────────────────────────────────────────────────────────────────────────────\n\nconst DEFAULT_CONFIG: TransparentSortConfig = Object.freeze({\n mode: TRANSPARENT_SORT_MODE_LAYER_Z,\n yzAlpha: 1.0,\n});\n\nconst VALID_MODES: ReadonlySet<number> = new Set<number>([\n TRANSPARENT_SORT_MODE_LAYER_Z,\n TRANSPARENT_SORT_MODE_LAYER_Y,\n TRANSPARENT_SORT_MODE_LAYER_YZ,\n TRANSPARENT_SORT_MODE_DISTANCE,\n]);\n\n// The expected / hint literals are the SSOT locked by plan-strategy D-4.\n// They MUST round-trip byte-for-byte into ResourceInvalidValueError so AI\n// users can read err.expected / err.hint for self-repair (charter P3).\n// `\\u2208` is the math \"is-element-of\" symbol; the ASCII source escape\n// keeps the file English-only per AGENTS.md §Conventions.\nconst EXPECTED_MODE = 'mode \\u2208 {0, 1, 2, 3}';\nconst HINT_MODE = '0=layer-z, 1=layer-y, 2=layer-yz, 3=distance';\n\n// ────────────────────────────────────────────────────────────────────────────\n// Helpers\n// ────────────────────────────────────────────────────────────────────────────\n\n/**\n * Read the world's `TransparentSortConfig` resource.\n *\n * @fallback KV missing returns `{ mode: 0, yzAlpha: 1.0 }`\n * (`TRANSPARENT_SORT_MODE_LAYER_Z`, horizontal-z safe default).\n * NO warn, NO throw — KV missing is a legal state (not an error state),\n * mirroring how a sprite-free scene is a legal state for the renderer\n * even though render-system has a transparent bucket. plan-strategy D-2:\n * `hasResource` guard precedes the read so this helper never trips\n * `ResourceNotFoundError` from `world.getResource`.\n *\n * @example\n * const cfg = getTransparentSortConfig(world);\n * // cfg.mode === 0, cfg.yzAlpha === 1.0 when no resource inserted.\n *\n * @example\n * world.insertResource(TRANSPARENT_SORT_CONFIG_KEY,\n * { mode: TRANSPARENT_SORT_MODE_LAYER_Y, yzAlpha: 1.0 });\n * const cfg = getTransparentSortConfig(world);\n * // cfg.mode === 1, cfg.yzAlpha === 1.0 (yzAlpha ignored by mode=1).\n */\nexport function getTransparentSortConfig(world: World): TransparentSortConfig {\n if (!world.hasResource(TRANSPARENT_SORT_CONFIG_KEY)) {\n return DEFAULT_CONFIG;\n }\n return world.getResource<TransparentSortConfig>(TRANSPARENT_SORT_CONFIG_KEY);\n}\n\n/**\n * Write the world's `TransparentSortConfig` resource, validating `mode`.\n *\n * Returns `Result<void, ResourceInvalidValueError>`:\n *\n * - `ok` — mode is in `{0, 1, 2, 3}`; the resource is inserted /\n * overwritten via `world.insertResource`.\n * - `err` — mode is out of range; the resource is NOT mutated;\n * `err.error` is a `ResourceInvalidValueError` instance carrying:\n * `.code === 'resource-invalid-value'`\n * `.expected === 'mode \\u2208 {0, 1, 2, 3}'`\n * `.hint === '0=layer-z, 1=layer-y, 2=layer-yz, 3=distance'`\n * `.detail.receivedMode === <the rejected mode>`\n *\n * @fallback mode out-of-range is NEVER silently coerced to mode=0 —\n * `Result.err` is the only fail-mode (charter P3 structured failure).\n * AI users read `.code / .expected / .hint / .detail` properties to\n * self-repair, NOT the human-readable `.message` string.\n *\n * @fallback yzAlpha range is intentionally not validated; mode=0 / mode=1\n * ignore the field, mode=2 reads it. The silent-ignore is the\n * documented charter P3 \"legal default\" boundary (plan-strategy D-4 +\n * AC-18 path (3) carve-out).\n *\n * @example success path:\n * const r = setTransparentSortConfig(world,\n * { mode: TRANSPARENT_SORT_MODE_LAYER_YZ, yzAlpha: 0.5 });\n * if (!r.ok) return r;\n *\n * @example failure path:\n * const r = setTransparentSortConfig(world, { mode: 99, yzAlpha: 1.0 });\n * if (!r.ok) {\n * // r.error.code === 'resource-invalid-value'\n * // r.error.expected === 'mode \\u2208 {0, 1, 2, 3}'\n * // r.error.hint === '0=layer-z, 1=layer-y, 2=layer-yz, 3=distance'\n * // r.error.detail.receivedMode === 99\n * }\n */\nexport function setTransparentSortConfig(\n world: World,\n cfg: TransparentSortConfig,\n): Result<void, ResourceInvalidValueError> {\n if (!VALID_MODES.has(cfg.mode)) {\n return err(\n new ResourceInvalidValueError(EXPECTED_MODE, HINT_MODE, {\n receivedMode: cfg.mode,\n receivedKey: TRANSPARENT_SORT_CONFIG_KEY,\n }),\n );\n }\n world.insertResource<TransparentSortConfig>(TRANSPARENT_SORT_CONFIG_KEY, {\n mode: cfg.mode,\n yzAlpha: cfg.yzAlpha,\n });\n return ok(undefined);\n}\n"]}
|