@aura3d/engine 1.0.3 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. package/README.md +338 -14
  2. package/dist/animation/AnimationClipEvents.d.ts +57 -0
  3. package/dist/animation/AnimationClipEvents.d.ts.map +1 -0
  4. package/dist/animation/AnimationClipEvents.js +171 -0
  5. package/dist/animation/AnimationClipEvents.js.map +1 -0
  6. package/dist/animation/AnimationClipRegistry.d.ts +76 -0
  7. package/dist/animation/AnimationClipRegistry.d.ts.map +1 -0
  8. package/dist/animation/AnimationClipRegistry.js +130 -0
  9. package/dist/animation/AnimationClipRegistry.js.map +1 -0
  10. package/dist/animation/AnimationController.d.ts +168 -0
  11. package/dist/animation/AnimationController.d.ts.map +1 -0
  12. package/dist/animation/AnimationController.js +619 -0
  13. package/dist/animation/AnimationController.js.map +1 -0
  14. package/dist/animation/AnimationStateGraph.d.ts +2 -0
  15. package/dist/animation/AnimationStateGraph.d.ts.map +1 -0
  16. package/dist/animation/AnimationStateGraph.js +2 -0
  17. package/dist/animation/AnimationStateGraph.js.map +1 -0
  18. package/dist/animation/AnimationStateMachine.d.ts +16 -0
  19. package/dist/animation/AnimationStateMachine.d.ts.map +1 -1
  20. package/dist/animation/AnimationStateMachine.js +69 -7
  21. package/dist/animation/AnimationStateMachine.js.map +1 -1
  22. package/dist/animation/HumanoidRetargeting.d.ts +76 -0
  23. package/dist/animation/HumanoidRetargeting.d.ts.map +1 -0
  24. package/dist/animation/HumanoidRetargeting.js +331 -0
  25. package/dist/animation/HumanoidRetargeting.js.map +1 -0
  26. package/dist/animation/browser-index.d.ts +18 -0
  27. package/dist/animation/browser-index.d.ts.map +1 -1
  28. package/dist/animation/browser-index.js +13 -0
  29. package/dist/animation/browser-index.js.map +1 -1
  30. package/dist/animation/index.d.ts +17 -1
  31. package/dist/animation/index.d.ts.map +1 -1
  32. package/dist/animation/index.js +12 -1
  33. package/dist/animation/index.js.map +1 -1
  34. package/dist/animation/threejs-compatibility/AnimationDiagnostics.d.ts.map +1 -1
  35. package/dist/animation/threejs-compatibility/AnimationDiagnostics.js +3 -5
  36. package/dist/animation/threejs-compatibility/AnimationDiagnostics.js.map +1 -1
  37. package/dist/assets/GLTFAnimationRuntime.js +1 -1
  38. package/dist/assets/GLTFLoader.js +1 -1
  39. package/dist/aura3d-cli/cli.js +225 -8
  40. package/dist/aura3d-cli/cli.js.map +1 -1
  41. package/dist/aura3d-cli/index.d.ts +283 -3
  42. package/dist/aura3d-cli/index.d.ts.map +1 -1
  43. package/dist/aura3d-cli/index.js +1028 -4
  44. package/dist/aura3d-cli/index.js.map +1 -1
  45. package/dist/aura3d-cli/pull-bridge.d.ts +108 -0
  46. package/dist/aura3d-cli/pull-bridge.d.ts.map +1 -0
  47. package/dist/aura3d-cli/pull-bridge.js +333 -0
  48. package/dist/aura3d-cli/pull-bridge.js.map +1 -0
  49. package/dist/create-aura3d/index.d.ts +1 -1
  50. package/dist/create-aura3d/index.d.ts.map +1 -1
  51. package/dist/create-aura3d/index.js +9 -2
  52. package/dist/create-aura3d/index.js.map +1 -1
  53. package/dist/editor-runtime/ProjectSerializer.d.ts +74 -1
  54. package/dist/editor-runtime/ProjectSerializer.d.ts.map +1 -1
  55. package/dist/editor-runtime/ProjectSerializer.js +123 -6
  56. package/dist/editor-runtime/ProjectSerializer.js.map +1 -1
  57. package/dist/editor-runtime/TimelineModel.d.ts +18 -0
  58. package/dist/editor-runtime/TimelineModel.d.ts.map +1 -1
  59. package/dist/editor-runtime/TimelineModel.js +67 -3
  60. package/dist/editor-runtime/TimelineModel.js.map +1 -1
  61. package/dist/editor-runtime/TimelineRuntimeBridge.d.ts +98 -0
  62. package/dist/editor-runtime/TimelineRuntimeBridge.d.ts.map +1 -0
  63. package/dist/editor-runtime/TimelineRuntimeBridge.js +186 -0
  64. package/dist/editor-runtime/TimelineRuntimeBridge.js.map +1 -0
  65. package/dist/editor-runtime/index.d.ts +3 -1
  66. package/dist/editor-runtime/index.d.ts.map +1 -1
  67. package/dist/editor-runtime/index.js +1 -0
  68. package/dist/editor-runtime/index.js.map +1 -1
  69. package/dist/engine/agent-api/AnimationController.d.ts +607 -0
  70. package/dist/engine/agent-api/AnimationController.d.ts.map +1 -0
  71. package/dist/engine/agent-api/AnimationController.js +2192 -0
  72. package/dist/engine/agent-api/AnimationController.js.map +1 -0
  73. package/dist/engine/agent-api/AssetEvidence.d.ts +88 -0
  74. package/dist/engine/agent-api/AssetEvidence.d.ts.map +1 -0
  75. package/dist/engine/agent-api/AssetEvidence.js +157 -0
  76. package/dist/engine/agent-api/AssetEvidence.js.map +1 -0
  77. package/dist/engine/agent-api/AuraAppHandle.d.ts +55 -0
  78. package/dist/engine/agent-api/AuraAppHandle.d.ts.map +1 -0
  79. package/dist/engine/agent-api/AuraAppHandle.js +15 -0
  80. package/dist/engine/agent-api/AuraAppHandle.js.map +1 -0
  81. package/dist/engine/agent-api/AuraVoiceBridge.d.ts +96 -0
  82. package/dist/engine/agent-api/AuraVoiceBridge.d.ts.map +1 -0
  83. package/dist/engine/agent-api/AuraVoiceBridge.js +370 -0
  84. package/dist/engine/agent-api/AuraVoiceBridge.js.map +1 -0
  85. package/dist/engine/agent-api/CartoonDirector.d.ts +95 -0
  86. package/dist/engine/agent-api/CartoonDirector.d.ts.map +1 -0
  87. package/dist/engine/agent-api/CartoonDirector.js +342 -0
  88. package/dist/engine/agent-api/CartoonDirector.js.map +1 -0
  89. package/dist/engine/agent-api/CartoonPerformance.d.ts +149 -0
  90. package/dist/engine/agent-api/CartoonPerformance.d.ts.map +1 -0
  91. package/dist/engine/agent-api/CartoonPerformance.js +317 -0
  92. package/dist/engine/agent-api/CartoonPerformance.js.map +1 -0
  93. package/dist/engine/agent-api/CartoonRenderQueue.d.ts +132 -0
  94. package/dist/engine/agent-api/CartoonRenderQueue.d.ts.map +1 -0
  95. package/dist/engine/agent-api/CartoonRenderQueue.js +385 -0
  96. package/dist/engine/agent-api/CartoonRenderQueue.js.map +1 -0
  97. package/dist/engine/agent-api/CharacterAssembly.d.ts +126 -0
  98. package/dist/engine/agent-api/CharacterAssembly.d.ts.map +1 -0
  99. package/dist/engine/agent-api/CharacterAssembly.js +280 -0
  100. package/dist/engine/agent-api/CharacterAssembly.js.map +1 -0
  101. package/dist/engine/agent-api/DialoguePerformance.d.ts +150 -0
  102. package/dist/engine/agent-api/DialoguePerformance.d.ts.map +1 -0
  103. package/dist/engine/agent-api/DialoguePerformance.js +335 -0
  104. package/dist/engine/agent-api/DialoguePerformance.js.map +1 -0
  105. package/dist/engine/agent-api/FrameLoop.d.ts +70 -0
  106. package/dist/engine/agent-api/FrameLoop.d.ts.map +1 -0
  107. package/dist/engine/agent-api/FrameLoop.js +165 -0
  108. package/dist/engine/agent-api/FrameLoop.js.map +1 -0
  109. package/dist/engine/agent-api/GameAppRuntime.d.ts +62 -0
  110. package/dist/engine/agent-api/GameAppRuntime.d.ts.map +1 -0
  111. package/dist/engine/agent-api/GameAppRuntime.js +189 -0
  112. package/dist/engine/agent-api/GameAppRuntime.js.map +1 -0
  113. package/dist/engine/agent-api/GameAssetValidation.d.ts +279 -0
  114. package/dist/engine/agent-api/GameAssetValidation.d.ts.map +1 -0
  115. package/dist/engine/agent-api/GameAssetValidation.js +719 -0
  116. package/dist/engine/agent-api/GameAssetValidation.js.map +1 -0
  117. package/dist/engine/agent-api/GameEvidence.d.ts +148 -0
  118. package/dist/engine/agent-api/GameEvidence.d.ts.map +1 -0
  119. package/dist/engine/agent-api/GameEvidence.js +269 -0
  120. package/dist/engine/agent-api/GameEvidence.js.map +1 -0
  121. package/dist/engine/agent-api/GameRuntime.d.ts +931 -0
  122. package/dist/engine/agent-api/GameRuntime.d.ts.map +1 -0
  123. package/dist/engine/agent-api/GameRuntime.js +2229 -0
  124. package/dist/engine/agent-api/GameRuntime.js.map +1 -0
  125. package/dist/engine/agent-api/GameSceneBridge.d.ts +54 -0
  126. package/dist/engine/agent-api/GameSceneBridge.d.ts.map +1 -0
  127. package/dist/engine/agent-api/GameSceneBridge.js +110 -0
  128. package/dist/engine/agent-api/GameSceneBridge.js.map +1 -0
  129. package/dist/engine/agent-api/PromptAnimationContract.d.ts +278 -0
  130. package/dist/engine/agent-api/PromptAnimationContract.d.ts.map +1 -0
  131. package/dist/engine/agent-api/PromptAnimationContract.js +238 -0
  132. package/dist/engine/agent-api/PromptAnimationContract.js.map +1 -0
  133. package/dist/engine/agent-api/PromptAnimationEvidence.d.ts +183 -0
  134. package/dist/engine/agent-api/PromptAnimationEvidence.d.ts.map +1 -0
  135. package/dist/engine/agent-api/PromptAnimationEvidence.js +454 -0
  136. package/dist/engine/agent-api/PromptAnimationEvidence.js.map +1 -0
  137. package/dist/engine/agent-api/RuntimeNodeHandle.d.ts +100 -0
  138. package/dist/engine/agent-api/RuntimeNodeHandle.d.ts.map +1 -0
  139. package/dist/engine/agent-api/RuntimeNodeHandle.js +36 -0
  140. package/dist/engine/agent-api/RuntimeNodeHandle.js.map +1 -0
  141. package/dist/engine/agent-api/ShotTimeline.d.ts +179 -0
  142. package/dist/engine/agent-api/ShotTimeline.d.ts.map +1 -0
  143. package/dist/engine/agent-api/ShotTimeline.js +264 -0
  144. package/dist/engine/agent-api/ShotTimeline.js.map +1 -0
  145. package/dist/engine/agent-api/VisemeController.d.ts +89 -0
  146. package/dist/engine/agent-api/VisemeController.d.ts.map +1 -0
  147. package/dist/engine/agent-api/VisemeController.js +207 -0
  148. package/dist/engine/agent-api/VisemeController.js.map +1 -0
  149. package/dist/engine/agent-api/game-kits/fighting.d.ts +123 -0
  150. package/dist/engine/agent-api/game-kits/fighting.d.ts.map +1 -0
  151. package/dist/engine/agent-api/game-kits/fighting.js +483 -0
  152. package/dist/engine/agent-api/game-kits/fighting.js.map +1 -0
  153. package/dist/engine/agent-api/game-kits/index.d.ts +15 -0
  154. package/dist/engine/agent-api/game-kits/index.d.ts.map +1 -0
  155. package/dist/engine/agent-api/game-kits/index.js +6 -0
  156. package/dist/engine/agent-api/game-kits/index.js.map +1 -0
  157. package/dist/engine/agent-api/humanoid-walk-runtime.d.ts +1 -0
  158. package/dist/engine/agent-api/humanoid-walk-runtime.d.ts.map +1 -1
  159. package/dist/engine/agent-api/index.d.ts +495 -1
  160. package/dist/engine/agent-api/index.d.ts.map +1 -1
  161. package/dist/engine/agent-api/index.js +752 -6
  162. package/dist/engine/agent-api/index.js.map +1 -1
  163. package/dist/engine/agent-api/product-viewer-runtime.d.ts.map +1 -1
  164. package/dist/index.d.ts +1 -0
  165. package/dist/index.js +1 -0
  166. package/dist/physics/CollisionVolumes.d.ts +57 -0
  167. package/dist/physics/CollisionVolumes.d.ts.map +1 -0
  168. package/dist/physics/CollisionVolumes.js +159 -0
  169. package/dist/physics/CollisionVolumes.js.map +1 -0
  170. package/dist/physics/HitboxWorld.d.ts +250 -0
  171. package/dist/physics/HitboxWorld.d.ts.map +1 -0
  172. package/dist/physics/HitboxWorld.js +771 -0
  173. package/dist/physics/HitboxWorld.js.map +1 -0
  174. package/dist/physics/KinematicBody.d.ts +157 -0
  175. package/dist/physics/KinematicBody.d.ts.map +1 -0
  176. package/dist/physics/KinematicBody.js +405 -0
  177. package/dist/physics/KinematicBody.js.map +1 -0
  178. package/dist/physics/KinematicWorld.d.ts +58 -0
  179. package/dist/physics/KinematicWorld.d.ts.map +1 -0
  180. package/dist/physics/KinematicWorld.js +246 -0
  181. package/dist/physics/KinematicWorld.js.map +1 -0
  182. package/dist/physics/index.d.ts +4 -0
  183. package/dist/physics/index.d.ts.map +1 -1
  184. package/dist/physics/index.js +4 -0
  185. package/dist/physics/index.js.map +1 -1
  186. package/dist/rendering/ForwardPass.js +2 -2
  187. package/dist/rendering/ShaderLibrary.js +2 -2
  188. package/dist/rendering/SkinnedLitMaterial.js +3 -3
  189. package/dist/rendering/SkinnedUnlitMaterial.js +3 -3
  190. package/dist/scene/Renderable.js +2 -2
  191. package/dist/scripting/VisualGraph.d.ts +2 -1
  192. package/dist/scripting/VisualGraph.d.ts.map +1 -1
  193. package/dist/scripting/VisualGraph.js +118 -1
  194. package/dist/scripting/VisualGraph.js.map +1 -1
  195. package/dist/scripting/VisualGraphContext.d.ts +123 -0
  196. package/dist/scripting/VisualGraphContext.d.ts.map +1 -0
  197. package/dist/scripting/VisualGraphContext.js +2 -0
  198. package/dist/scripting/VisualGraphContext.js.map +1 -0
  199. package/dist/scripting/VisualGraphExecutor.d.ts +6 -1
  200. package/dist/scripting/VisualGraphExecutor.d.ts.map +1 -1
  201. package/dist/scripting/VisualGraphExecutor.js +364 -7
  202. package/dist/scripting/VisualGraphExecutor.js.map +1 -1
  203. package/dist/scripting/VisualNodeCatalog.d.ts +1 -1
  204. package/dist/scripting/VisualNodeCatalog.d.ts.map +1 -1
  205. package/dist/scripting/VisualNodeCatalog.js +61 -1
  206. package/dist/scripting/VisualNodeCatalog.js.map +1 -1
  207. package/dist/scripting/index.d.ts +1 -0
  208. package/dist/scripting/index.d.ts.map +1 -1
  209. package/dist/scripting/index.js.map +1 -1
  210. package/package.json +203 -118
@@ -1,5 +1,44 @@
1
1
  import { PhysicsDebugDraw, PhysicsStepper, PhysicsWorld, ScenePhysicsBridge, Shape as PhysicsShapeFactory } from "../../physics/index.js";
2
+ import { createFrameLoop } from "./FrameLoop.js";
3
+ import { createCombatWorld, createGameCameraDirector, createGameEffects, applyGameCombatEventsToRuntime, createGameAccessibilityFocus, createGameAccessibilityLabel, createGameAccessibilityRuntimeSettings, createGameHighContrastSource, createGameHudBindings, createGameHudComboBinding, createGameHudDebugToggleBinding, createGameHudHealthBinding, createGameHudMeterBinding, createGameHudRoundBinding, createGameHudSnapshot, createGameHudTimerBinding, createGameBoxCollider, createGameCapsuleCollider, createGameColliderDebugGeometry, createGameCombatDebugGeometry, createGameDebugOverlayData, createGameDebugSceneNodes, createGameHitboxDebugGeometry, createGameFighting2DRules, createGameInput, createGameInputReplay, createGameInputReplayDriver, createGameJumpAssist, createGameKinematicBody, createGamePauseControlsSource, createGameRectCollider, createGameReducedFlashSource, createGameReducedMotionSource, createGameSphereCollider, createGameTouchControlLayout, gameColliderAabb, gameColliders, gameEffectPresets, gameGuardboxes, gameHitboxes, gameHurtboxes, gameInputReplayEventsAt, gamePushboxes, gameTriggerVolumes } from "./GameRuntime.js";
4
+ import { collectGameRuntimeEvidence as collectGameRuntimeEvidenceV105 } from "./GameEvidence.js";
5
+ import { calculateRuntimeNodeBounds } from "./RuntimeNodeHandle.js";
6
+ import { createRuntimeNodeSpec } from "./GameSceneBridge.js";
7
+ import { createFightingGameKit, fighting as fightingGameKit } from "./game-kits/fighting.js";
8
+ import { createPromptAnimationEpisodePlan, createPromptAnimationStoryBible, definePromptAnimationStoryboard } from "./PromptAnimationContract.js";
9
+ import { applyShotPlaybackFrame, createShotPlaybackPlan, createShotTimeline, installShotPlayback, sampleShotPlaybackPlan } from "./ShotTimeline.js";
10
+ import { captionCueAtTime, createCaptionTimingProof, deriveCaptionTrackFromDialogue } from "./DialoguePerformance.js";
11
+ import { createAuraVoiceVisemeTrack, createGlbBlendshapeVisemeCue, createPrimitiveMouthVisemeCues, sampleVisemeTrack } from "./VisemeController.js";
12
+ import { createAuraVoiceBridgePackage, createAuraVoiceDubRerenderProof, createAuraVoiceRerenderPlan, sampleAuraVoiceBridgeAtTime } from "./AuraVoiceBridge.js";
13
+ import { createCartoonDirectorPlan } from "./CartoonDirector.js";
14
+ import { createCartoonPerformance } from "./CartoonPerformance.js";
15
+ import { createCartoonRenderOutputPackageMetadata, createCartoonRenderQueue } from "./CartoonRenderQueue.js";
16
+ import { collectPromptAnimationEvidence } from "./PromptAnimationEvidence.js";
17
+ import { createGameAppRuntime } from "./GameAppRuntime.js";
2
18
  export { Engine } from "../../core/index.js";
19
+ export { asAuraAppHandle, isAuraAppHandle } from "./AuraAppHandle.js";
20
+ export { createGameAppRuntime } from "./GameAppRuntime.js";
21
+ export { FrameLoop, createFrameLoop } from "./FrameLoop.js";
22
+ export { createCombatWorld, createGameCameraDirector, createGameEffects, applyGameCombatEventsToRuntime, createGameAccessibilityFocus, createGameAccessibilityLabel, createGameAccessibilityRuntimeSettings, createGameHighContrastSource, createGameHudBindings, createGameHudComboBinding, createGameHudDebugToggleBinding, createGameHudHealthBinding, createGameHudMeterBinding, createGameHudRoundBinding, createGameHudSnapshot, createGameHudTimerBinding, createGameBoxCollider, createGameCapsuleCollider, createGameColliderDebugGeometry, createGameCombatDebugGeometry, createGameDebugOverlayData, createGameDebugSceneNodes, createGameHitboxDebugGeometry, createGameInput, createGameInputReplay, createGameInputReplayDriver, createGameJumpAssist, createGameKinematicBody, createGamePauseControlsSource, createGameRectCollider, createGameReducedFlashSource, createGameReducedMotionSource, createGameSphereCollider, createGameTouchControlLayout, gameColliderAabb, gameColliders, gameInputReplayEventsAt, createGameLoopPlan } from "./GameRuntime.js";
23
+ export { collectGameSceneRuntimeNodes, createGameSceneBridge, createRuntimeNodeSpec } from "./GameSceneBridge.js";
24
+ export { calculateRuntimeNodeBounds, createRuntimeNodeEffectAttachment, runtimeNodeHasTag } from "./RuntimeNodeHandle.js";
25
+ export { createFightingGameKit, fighting, fighterRuntimeNode } from "./game-kits/fighting.js";
26
+ export { gameKits } from "./game-kits/index.js";
27
+ export * from "./GameAssetValidation.js";
28
+ export * from "./CharacterAssembly.js";
29
+ export * from "./AssetEvidence.js";
30
+ export * from "./AnimationController.js";
31
+ export { gameAssetValidation, quaterniusGameReadyFighterValidationContract, validateQuaterniusGameReadyFighterAsset } from "./GameAssetValidation.js";
32
+ export { createAnimationController } from "./AnimationController.js";
33
+ export * from "./PromptAnimationContract.js";
34
+ export * from "./AuraVoiceBridge.js";
35
+ export * from "./ShotTimeline.js";
36
+ export * from "./DialoguePerformance.js";
37
+ export * from "./VisemeController.js";
38
+ export * from "./PromptAnimationEvidence.js";
39
+ export * from "./CartoonDirector.js";
40
+ export * from "./CartoonPerformance.js";
41
+ export * from "./CartoonRenderQueue.js";
3
42
  const auraAssetRefBrand = Symbol("AuraAssetRef");
4
43
  export function defineAuraAssets(definitions) {
5
44
  const refs = {};
@@ -45,6 +84,9 @@ export class AuraNodeBuilder {
45
84
  physics(spec) {
46
85
  return this.with({ physics: spec });
47
86
  }
87
+ runtime(spec) {
88
+ return this.with({ runtime: { mutable: true, ...spec } });
89
+ }
48
90
  toJSON() {
49
91
  return this.value;
50
92
  }
@@ -2876,6 +2918,8 @@ export const games = {
2876
2918
  miniGolfCourse: () => prefabs.miniGolfCourse(),
2877
2919
  createMiniGolfState: () => createMiniGolfStateController(),
2878
2920
  miniGolfPointerShot: miniGolfPointerShotFromDrag,
2921
+ fighting: fightingGameKit,
2922
+ createFightingGameKit,
2879
2923
  miniGolfScene: () => scene()
2880
2924
  .background("#12321d")
2881
2925
  .addMany(prefabs.miniGolfHole())
@@ -2883,6 +2927,321 @@ export const games = {
2883
2927
  .camera(camera.follow({ targetNode: "white physics golf ball", distance: 4.2 }))
2884
2928
  .timeline(timeline.loop({ seconds: 8 }))
2885
2929
  };
2930
+ export function collectGameRuntimeEvidence(app, options = {}) {
2931
+ return collectGameRuntimeEvidenceV105(app, options);
2932
+ }
2933
+ function createGameInputController(options) {
2934
+ const actions = options.actions;
2935
+ const axes = options.axes ?? {};
2936
+ const bufferMs = options.bufferMs ?? 120;
2937
+ const activeBindings = new Set();
2938
+ const activeActionOverrides = new Set();
2939
+ const previousHeld = new Map();
2940
+ const currentHeld = new Map();
2941
+ const pressedEdges = new Set();
2942
+ const releasedEdges = new Set();
2943
+ const lastPressedAt = new Map();
2944
+ const replayEvents = [];
2945
+ let frame = 0;
2946
+ let time = 0;
2947
+ let latestSnapshot = {
2948
+ kind: "aura-game-input-snapshot",
2949
+ frame,
2950
+ time,
2951
+ activeBindings: [],
2952
+ actions: {}
2953
+ };
2954
+ const resolveHeld = (action) => {
2955
+ if (activeActionOverrides.has(action))
2956
+ return true;
2957
+ const bindings = actions[action] ?? [];
2958
+ return bindings.some((binding) => activeBindings.has(binding));
2959
+ };
2960
+ const record = (type, binding) => {
2961
+ replayEvents.push({ frame, time, type, binding });
2962
+ };
2963
+ const pressBinding = (binding, shouldRecord = true) => {
2964
+ activeBindings.add(binding);
2965
+ if (actions[binding])
2966
+ activeActionOverrides.add(binding);
2967
+ if (shouldRecord)
2968
+ record("press", binding);
2969
+ };
2970
+ const releaseBinding = (binding, shouldRecord = true) => {
2971
+ activeBindings.delete(binding);
2972
+ activeActionOverrides.delete(binding);
2973
+ if (shouldRecord)
2974
+ record("release", binding);
2975
+ };
2976
+ const toSnapshot = () => {
2977
+ const actionStates = {};
2978
+ const nowMs = time * 1000;
2979
+ for (const action of Object.keys(actions)) {
2980
+ const held = currentHeld.get(action) ?? false;
2981
+ actionStates[action] = {
2982
+ pressed: pressedEdges.has(action),
2983
+ held,
2984
+ released: releasedEdges.has(action),
2985
+ buffered: pressedEdges.has(action) || nowMs - (lastPressedAt.get(action) ?? Number.NEGATIVE_INFINITY) <= bufferMs,
2986
+ value: held ? 1 : 0
2987
+ };
2988
+ }
2989
+ return {
2990
+ kind: "aura-game-input-snapshot",
2991
+ frame,
2992
+ time,
2993
+ activeBindings: [...activeBindings].sort(),
2994
+ actions: actionStates
2995
+ };
2996
+ };
2997
+ const update = (dt = 1 / 60) => {
2998
+ frame += 1;
2999
+ time += Math.max(0, dt);
3000
+ pressedEdges.clear();
3001
+ releasedEdges.clear();
3002
+ for (const action of Object.keys(actions)) {
3003
+ const held = resolveHeld(action);
3004
+ const wasHeld = previousHeld.get(action) ?? false;
3005
+ currentHeld.set(action, held);
3006
+ if (held && !wasHeld) {
3007
+ pressedEdges.add(action);
3008
+ lastPressedAt.set(action, time * 1000);
3009
+ }
3010
+ if (!held && wasHeld)
3011
+ releasedEdges.add(action);
3012
+ previousHeld.set(action, held);
3013
+ }
3014
+ latestSnapshot = toSnapshot();
3015
+ return latestSnapshot;
3016
+ };
3017
+ const target = options.target ?? (typeof window !== "undefined" ? window : undefined);
3018
+ const onKeyDown = (event) => {
3019
+ const keyboard = event;
3020
+ if (keyboard.repeat)
3021
+ return;
3022
+ if (keyboard.code)
3023
+ pressBinding(keyboard.code);
3024
+ if (keyboard.key && keyboard.key !== keyboard.code)
3025
+ pressBinding(keyboard.key);
3026
+ };
3027
+ const onKeyUp = (event) => {
3028
+ const keyboard = event;
3029
+ if (keyboard.code)
3030
+ releaseBinding(keyboard.code);
3031
+ if (keyboard.key && keyboard.key !== keyboard.code)
3032
+ releaseBinding(keyboard.key);
3033
+ };
3034
+ if (options.autoListen !== false && target?.addEventListener) {
3035
+ target.addEventListener("keydown", onKeyDown);
3036
+ target.addEventListener("keyup", onKeyUp);
3037
+ }
3038
+ return {
3039
+ kind: "aura-game-input-plan",
3040
+ actions,
3041
+ axes,
3042
+ bufferMs,
3043
+ update,
3044
+ snapshot() {
3045
+ return latestSnapshot;
3046
+ },
3047
+ pressed(action) {
3048
+ return pressedEdges.has(action);
3049
+ },
3050
+ held(action) {
3051
+ return currentHeld.get(action) ?? resolveHeld(action);
3052
+ },
3053
+ released(action) {
3054
+ return releasedEdges.has(action);
3055
+ },
3056
+ buffered(action, windowMs = bufferMs) {
3057
+ return pressedEdges.has(action) || time * 1000 - (lastPressedAt.get(action) ?? Number.NEGATIVE_INFINITY) <= windowMs;
3058
+ },
3059
+ axis(name, negativeAction, positiveAction) {
3060
+ const binding = axes[name];
3061
+ const negative = negativeAction ?? binding?.negative;
3062
+ const positive = positiveAction ?? binding?.positive;
3063
+ if (!negative && !positive)
3064
+ return this.held(name) ? 1 : 0;
3065
+ return (positive && this.held(positive) ? 1 : 0) - (negative && this.held(negative) ? 1 : 0);
3066
+ },
3067
+ press(binding) {
3068
+ pressBinding(binding);
3069
+ },
3070
+ release(binding) {
3071
+ releaseBinding(binding);
3072
+ },
3073
+ setAction(action, held) {
3074
+ if (held) {
3075
+ activeActionOverrides.add(action);
3076
+ record("press", action);
3077
+ }
3078
+ else {
3079
+ activeActionOverrides.delete(action);
3080
+ record("release", action);
3081
+ }
3082
+ },
3083
+ recorded() {
3084
+ return [...replayEvents];
3085
+ },
3086
+ replay(events) {
3087
+ activeBindings.clear();
3088
+ activeActionOverrides.clear();
3089
+ for (const event of events) {
3090
+ if (event.type === "press")
3091
+ pressBinding(event.binding, false);
3092
+ else
3093
+ releaseBinding(event.binding, false);
3094
+ }
3095
+ return update(0);
3096
+ },
3097
+ clearReplay() {
3098
+ replayEvents.length = 0;
3099
+ },
3100
+ dispose() {
3101
+ if (target?.removeEventListener) {
3102
+ target.removeEventListener("keydown", onKeyDown);
3103
+ target.removeEventListener("keyup", onKeyUp);
3104
+ }
3105
+ activeBindings.clear();
3106
+ activeActionOverrides.clear();
3107
+ previousHeld.clear();
3108
+ currentHeld.clear();
3109
+ pressedEdges.clear();
3110
+ releasedEdges.clear();
3111
+ }
3112
+ };
3113
+ }
3114
+ export function createAuraGameRules(options = {}) {
3115
+ return {
3116
+ kind: "aura-game-rules",
3117
+ gravity: options.gravity ?? 24,
3118
+ roundSeconds: options.roundSeconds ?? 90,
3119
+ maxHealth: options.maxHealth ?? 100,
3120
+ maxGuard: options.maxGuard ?? 100,
3121
+ maxMeter: options.maxMeter ?? 100,
3122
+ stageBounds: options.stageBounds ?? {
3123
+ minX: -4.5,
3124
+ maxX: 4.5
3125
+ }
3126
+ };
3127
+ }
3128
+ export const gameRules = Object.assign(createAuraGameRules, {
3129
+ fighting2D: createGameFighting2DRules
3130
+ });
3131
+ export function createAuraGameRuntime(options = {}) {
3132
+ return {
3133
+ kind: "aura-game-runtime",
3134
+ loop: {
3135
+ kind: "aura-game-loop-plan",
3136
+ fixedDt: options.loop?.fixedDt ?? 1 / 60,
3137
+ maxSubSteps: options.loop?.maxSubSteps ?? 5,
3138
+ timeScale: options.loop?.timeScale ?? 1
3139
+ },
3140
+ rules: createAuraGameRules(options.rules),
3141
+ input: options.input ? createGameInput(options.input) : undefined,
3142
+ combat: createCombatWorld(),
3143
+ camera: createGameCameraDirector({
3144
+ stageBounds: {
3145
+ minX: options.rules?.stageBounds?.minX ?? -4.5,
3146
+ maxX: options.rules?.stageBounds?.maxX ?? 4.5
3147
+ }
3148
+ }),
3149
+ effects: createGameEffects({ poolSize: options.effectPoolSize }),
3150
+ bodies: []
3151
+ };
3152
+ }
3153
+ export const game = {
3154
+ createRuntime: createAuraGameRuntime,
3155
+ rules: gameRules,
3156
+ loop: (options = {}) => ({
3157
+ kind: "aura-game-loop-plan",
3158
+ fixedDt: options.fixedDt ?? 1 / 60,
3159
+ maxSubSteps: options.maxSubSteps ?? 5,
3160
+ timeScale: options.timeScale ?? 1
3161
+ }),
3162
+ frameLoop: createFrameLoop,
3163
+ runtimeNode: createRuntimeNodeSpec,
3164
+ input: createGameInput,
3165
+ inputReplay: createGameInputReplay,
3166
+ inputReplayDriver: createGameInputReplayDriver,
3167
+ inputReplayEventsAt: gameInputReplayEventsAt,
3168
+ touchControls: createGameTouchControlLayout,
3169
+ kinematicBody: createGameKinematicBody,
3170
+ jumpAssist: createGameJumpAssist,
3171
+ collider: {
3172
+ box: createGameBoxCollider,
3173
+ sphere: createGameSphereCollider,
3174
+ capsule: createGameCapsuleCollider,
3175
+ rect: createGameRectCollider,
3176
+ aabb: gameColliderAabb,
3177
+ factories: gameColliders
3178
+ },
3179
+ hitbox: gameHitboxes,
3180
+ hurtbox: gameHurtboxes,
3181
+ guardbox: gameGuardboxes,
3182
+ pushbox: gamePushboxes,
3183
+ trigger: gameTriggerVolumes,
3184
+ combatWorld: createCombatWorld,
3185
+ combatEvents: applyGameCombatEventsToRuntime,
3186
+ cameraDirector: createGameCameraDirector,
3187
+ effects: createGameEffects,
3188
+ effectPresets: gameEffectPresets,
3189
+ debug: {
3190
+ colliders: createGameColliderDebugGeometry,
3191
+ hitboxes: createGameHitboxDebugGeometry,
3192
+ combat: createGameCombatDebugGeometry,
3193
+ overlay: createGameDebugOverlayData,
3194
+ sceneNodes: createGameDebugSceneNodes
3195
+ },
3196
+ hud: {
3197
+ health: createGameHudHealthBinding,
3198
+ meter: createGameHudMeterBinding,
3199
+ timer: createGameHudTimerBinding,
3200
+ combo: createGameHudComboBinding,
3201
+ round: createGameHudRoundBinding,
3202
+ debugToggle: createGameHudDebugToggleBinding,
3203
+ bindings: createGameHudBindings,
3204
+ snapshot: createGameHudSnapshot
3205
+ },
3206
+ accessibility: {
3207
+ label: createGameAccessibilityLabel,
3208
+ focus: createGameAccessibilityFocus,
3209
+ reducedMotion: createGameReducedMotionSource,
3210
+ reducedFlash: createGameReducedFlashSource,
3211
+ highContrast: createGameHighContrastSource,
3212
+ pauseControls: createGamePauseControlsSource,
3213
+ settings: createGameAccessibilityRuntimeSettings
3214
+ },
3215
+ fighting: createFightingGameKit,
3216
+ evidence: collectGameRuntimeEvidence
3217
+ };
3218
+ export const cartoon = {
3219
+ episodePlan: createPromptAnimationEpisodePlan,
3220
+ storyBible: createPromptAnimationStoryBible,
3221
+ storyboard: definePromptAnimationStoryboard,
3222
+ shotTimeline: createShotTimeline,
3223
+ shotPlaybackPlan: createShotPlaybackPlan,
3224
+ sampleShotPlaybackPlan,
3225
+ applyShotPlaybackFrame,
3226
+ installShotPlayback,
3227
+ captionsFromDialogue: deriveCaptionTrackFromDialogue,
3228
+ captionCueAtTime,
3229
+ captionTimingProof: createCaptionTimingProof,
3230
+ visemeTrack: createAuraVoiceVisemeTrack,
3231
+ primitiveMouthVisemes: createPrimitiveMouthVisemeCues,
3232
+ glbBlendshapeViseme: createGlbBlendshapeVisemeCue,
3233
+ sampleVisemeTrack,
3234
+ auraVoiceBridgePackage: createAuraVoiceBridgePackage,
3235
+ sampleAuraVoiceBridgeAtTime,
3236
+ auraVoiceRerenderPlan: createAuraVoiceRerenderPlan,
3237
+ auraVoiceDubRerenderProof: createAuraVoiceDubRerenderProof,
3238
+ director: createCartoonDirectorPlan,
3239
+ performance: createCartoonPerformance,
3240
+ renderQueue: createCartoonRenderQueue,
3241
+ renderOutputPackage: createCartoonRenderOutputPackageMetadata,
3242
+ evidence: collectPromptAnimationEvidence
3243
+ };
3244
+ export const animationStudio = cartoon;
2886
3245
  function collectParticleBudgetDiagnostics(nodes) {
2887
3246
  const flattened = groups.flatten(nodes);
2888
3247
  const particleEffects = flattened.filter((node) => node.kind === "effect" && node.effect === "particles");
@@ -3500,6 +3859,7 @@ export const character = {
3500
3859
  lowPolyHumanoid: (options = {}) => createLowPolyHumanoid(options),
3501
3860
  authoredHumanoid: (options = {}) => createAuthoredLowPolyHumanoid(options),
3502
3861
  primitiveHumanoid: (options = {}) => createHierarchicalPrimitiveHumanoid(options),
3862
+ performance: createCartoonPerformance,
3503
3863
  importedRigRuntime: async (options) => {
3504
3864
  markAuraLazySystemRequested("character-rig", "character.importedRigRuntime");
3505
3865
  const started = performanceNow();
@@ -4278,17 +4638,46 @@ export const sceneKits = {
4278
4638
  humanoidWalk: (options = {}) => makeSceneKit("humanoidWalk", options),
4279
4639
  productViewer: (asset, options = {}) => makeSceneKit("productViewer", { ...options, asset })
4280
4640
  };
4641
+ export function promptSubjectIsResolved(s) {
4642
+ return "asset" in s;
4643
+ }
4644
+ export async function resolvePromptPlanSubject(plan, resolver) {
4645
+ if (promptSubjectIsResolved(plan.subject)) {
4646
+ return plan;
4647
+ }
4648
+ const intent = plan.subject;
4649
+ const result = await resolver.resolve({ text: intent.intent, constraints: intent.constraints });
4650
+ if (!result) {
4651
+ throw new Error(`No auto-pullable asset matched the prompt-plan intent "${intent.intent}". ` +
4652
+ "Refine the intent or constraints (maxTriangles/license/animated), or provide a concrete typed asset " +
4653
+ "(e.g. a file via `assets add` / a typed asset ref) before compiling.");
4654
+ }
4655
+ const resolvedSubject = {
4656
+ asset: result.asset,
4657
+ ...(intent.label !== undefined ? { label: intent.label } : {})
4658
+ };
4659
+ return { ...plan, subject: resolvedSubject };
4660
+ }
4281
4661
  export function definePromptPlan(plan) {
4282
4662
  return plan;
4283
4663
  }
4664
+ function requireResolvedPromptSubject(plan) {
4665
+ if (!promptSubjectIsResolved(plan.subject)) {
4666
+ throw new Error(`Cannot compile a prompt plan whose subject is still an unresolved intent ("${plan.subject.intent}"). ` +
4667
+ "Resolve the prompt-plan subject first via resolvePromptPlanSubject(...) or the CLI `assets search`; " +
4668
+ "compile needs a concrete typed asset.");
4669
+ }
4670
+ return plan.subject;
4671
+ }
4284
4672
  export function compilePromptPlan(plan) {
4285
- const sceneBuilder = promptRecipes[plan.sceneType](plan.subject.asset, plan);
4673
+ const subject = requireResolvedPromptSubject(plan);
4674
+ const sceneBuilder = promptRecipes[plan.sceneType](subject.asset, plan);
4286
4675
  return {
4287
4676
  scene: sceneBuilder,
4288
4677
  report: {
4289
4678
  schema: "aura3d-prompt-plan-report/1.0",
4290
4679
  sceneType: plan.sceneType,
4291
- subjectAssetId: plan.subject.asset.id,
4680
+ subjectAssetId: subject.asset.id,
4292
4681
  recipe: plan.sceneType,
4293
4682
  cameraPreset: plan.camera?.preset ?? defaultCameraPreset(plan.sceneType),
4294
4683
  lightingPreset: plan.lighting?.preset ?? defaultLightingPreset(plan.sceneType),
@@ -4485,6 +4874,10 @@ function repairHintsForPromptPlan(plan) {
4485
4874
  function promptPlanWarnings(plan) {
4486
4875
  const warnings = [];
4487
4876
  const acceptanceCriteria = plan.acceptanceCriteria.map((item) => item.trim()).filter(Boolean);
4877
+ if (!promptSubjectIsResolved(plan.subject)) {
4878
+ warnings.push(`PromptPlan subject is still an unresolved intent ("${plan.subject.intent}"); resolve it via resolvePromptPlanSubject(...) ` +
4879
+ "or the CLI `assets search` to a concrete typed asset before compiling.");
4880
+ }
4488
4881
  if (!plan.subject.label?.trim()) {
4489
4882
  warnings.push("PromptPlan subject is missing a human-readable label; add one so reports and diagnostics describe the visible subject.");
4490
4883
  }
@@ -4522,6 +4915,217 @@ export class AuraRuntimeError extends Error {
4522
4915
  this.code = code;
4523
4916
  }
4524
4917
  }
4918
+ function createAuraRuntimeNodeRegistry(snapshot) {
4919
+ let handles = new Map();
4920
+ const registry = {
4921
+ get(id) {
4922
+ return handles.get(id);
4923
+ },
4924
+ require(id) {
4925
+ const handle = handles.get(id);
4926
+ if (!handle) {
4927
+ throw new AuraRuntimeError("missing-asset", `Aura3D runtime node "${id}" was not found. Suggested fix: add .runtime({ id: "${id}" }) to the model, primitive, group, or label you want to mutate.`);
4928
+ }
4929
+ return handle;
4930
+ },
4931
+ has(id) {
4932
+ return handles.has(id);
4933
+ },
4934
+ ids() {
4935
+ return [...handles.keys()];
4936
+ },
4937
+ all() {
4938
+ return [...handles.values()];
4939
+ },
4940
+ reset(nextSnapshot) {
4941
+ handles = collectRuntimeNodeHandles(nextSnapshot);
4942
+ }
4943
+ };
4944
+ registry.reset(snapshot);
4945
+ return registry;
4946
+ }
4947
+ function collectRuntimeNodeHandles(snapshot) {
4948
+ const next = new Map();
4949
+ for (const node of snapshot.nodes) {
4950
+ const runtime = "runtime" in node ? node.runtime : undefined;
4951
+ if (!runtime?.id)
4952
+ continue;
4953
+ next.set(runtime.id, createRuntimeNodeHandle(node, runtime));
4954
+ }
4955
+ return next;
4956
+ }
4957
+ function createRuntimeNodeHandle(node, runtime) {
4958
+ const tags = runtime.tags ?? [];
4959
+ const attachedEffects = [];
4960
+ const morphTargetWeights = new Map();
4961
+ let animationBinding;
4962
+ let animationPose;
4963
+ let animationPoseBinding;
4964
+ const getVisible = () => node.kind === "model" ? node.visible !== false : node.visible !== false;
4965
+ const getBounds = () => calculateRuntimeNodeBounds({
4966
+ position: node.position,
4967
+ scale: node.scale,
4968
+ size: "size" in node ? node.size : undefined
4969
+ });
4970
+ return {
4971
+ id: runtime.id,
4972
+ kind: node.kind,
4973
+ name: "name" in node ? node.name : undefined,
4974
+ tags,
4975
+ get position() {
4976
+ return node.position ?? [0, 0, 0];
4977
+ },
4978
+ set position(next) {
4979
+ node.position = next;
4980
+ },
4981
+ get rotation() {
4982
+ return node.rotation ?? [0, 0, 0];
4983
+ },
4984
+ set rotation(next) {
4985
+ node.rotation = next;
4986
+ },
4987
+ get scale() {
4988
+ return node.scale ?? 1;
4989
+ },
4990
+ set scale(next) {
4991
+ node.scale = next;
4992
+ },
4993
+ get visible() {
4994
+ return getVisible();
4995
+ },
4996
+ set visible(next) {
4997
+ node.visible = next;
4998
+ },
4999
+ setPosition(x, y, z) {
5000
+ node.position = [x, y, z];
5001
+ return this;
5002
+ },
5003
+ translate(x, y, z) {
5004
+ const current = node.position ?? [0, 0, 0];
5005
+ node.position = [current[0] + x, current[1] + y, current[2] + z];
5006
+ return this;
5007
+ },
5008
+ setRotation(x, y, z) {
5009
+ node.rotation = [x, y, z];
5010
+ return this;
5011
+ },
5012
+ setScale(scale) {
5013
+ node.scale = scale;
5014
+ return this;
5015
+ },
5016
+ setVisible(visible) {
5017
+ node.visible = visible;
5018
+ return this;
5019
+ },
5020
+ setMaterial(nextMaterial) {
5021
+ node.material = nextMaterial;
5022
+ return this;
5023
+ },
5024
+ play(clip, options = {}) {
5025
+ node.animation = { ...options, clip };
5026
+ return this;
5027
+ },
5028
+ setAnimation(animation) {
5029
+ node.animation = animation;
5030
+ return this;
5031
+ },
5032
+ setAnimationBinding(binding) {
5033
+ animationBinding = binding;
5034
+ return this;
5035
+ },
5036
+ setAnimationPose(pose, metadata) {
5037
+ animationPose = pose ? cloneRuntimeAnimationPose(pose) : undefined;
5038
+ animationPoseBinding = pose ? metadata : undefined;
5039
+ if (pose?.morphTargets) {
5040
+ for (const [name, weight] of Object.entries(pose.morphTargets)) {
5041
+ const normalizedName = name.trim();
5042
+ if (normalizedName) {
5043
+ morphTargetWeights.set(normalizedName, sanitizeRuntimeMorphWeight(weight));
5044
+ }
5045
+ }
5046
+ }
5047
+ return this;
5048
+ },
5049
+ animationPose() {
5050
+ return animationPose ? cloneRuntimeAnimationPose(animationPose) : undefined;
5051
+ },
5052
+ setMorphTarget(name, weight) {
5053
+ const normalizedName = name.trim();
5054
+ if (!normalizedName) {
5055
+ throw new AuraRuntimeError("missing-asset", "Aura3D morph target name is required.");
5056
+ }
5057
+ morphTargetWeights.set(normalizedName, sanitizeRuntimeMorphWeight(weight));
5058
+ return this;
5059
+ },
5060
+ setMorphTargets(weights) {
5061
+ morphTargetWeights.clear();
5062
+ for (const [name, weight] of Object.entries(weights)) {
5063
+ const normalizedName = name.trim();
5064
+ if (normalizedName) {
5065
+ morphTargetWeights.set(normalizedName, sanitizeRuntimeMorphWeight(weight));
5066
+ }
5067
+ }
5068
+ return this;
5069
+ },
5070
+ morphTargets() {
5071
+ return Object.fromEntries(morphTargetWeights.entries());
5072
+ },
5073
+ bounds() {
5074
+ return getBounds();
5075
+ },
5076
+ attachEffect(effect) {
5077
+ attachedEffects.push(effect);
5078
+ return this;
5079
+ },
5080
+ effects() {
5081
+ return [...attachedEffects];
5082
+ },
5083
+ snapshot() {
5084
+ return {
5085
+ id: runtime.id,
5086
+ kind: node.kind,
5087
+ name: "name" in node ? node.name : undefined,
5088
+ tags,
5089
+ position: node.position ?? [0, 0, 0],
5090
+ rotation: node.rotation ?? [0, 0, 0],
5091
+ scale: node.scale ?? 1,
5092
+ visible: getVisible(),
5093
+ animation: node.animation,
5094
+ animationBinding,
5095
+ animationPose: animationPose ? cloneRuntimeAnimationPose(animationPose) : undefined,
5096
+ animationPoseBinding,
5097
+ morphTargets: Object.fromEntries(morphTargetWeights.entries()),
5098
+ bounds: getBounds(),
5099
+ effects: [...attachedEffects]
5100
+ };
5101
+ }
5102
+ };
5103
+ }
5104
+ function cloneRuntimeAnimationPose(pose) {
5105
+ return {
5106
+ bones: Object.fromEntries(Object.entries(pose.bones ?? {}).map(([bone, transform]) => [
5107
+ bone,
5108
+ {
5109
+ position: transform.position ? { ...transform.position } : undefined,
5110
+ rotation: transform.rotation ? { ...transform.rotation } : undefined,
5111
+ scale: transform.scale ? { ...transform.scale } : undefined
5112
+ }
5113
+ ])),
5114
+ morphTargets: pose.morphTargets ? { ...pose.morphTargets } : undefined,
5115
+ rootMotion: pose.rootMotion
5116
+ ? {
5117
+ translation: pose.rootMotion.translation ? { ...pose.rootMotion.translation } : undefined,
5118
+ rotation: pose.rootMotion.rotation ? { ...pose.rootMotion.rotation } : undefined
5119
+ }
5120
+ : undefined,
5121
+ metadata: pose.metadata ? { ...pose.metadata } : undefined
5122
+ };
5123
+ }
5124
+ function sanitizeRuntimeMorphWeight(weight) {
5125
+ if (!Number.isFinite(weight))
5126
+ return 0;
5127
+ return Math.max(0, Math.min(1, weight));
5128
+ }
4525
5129
  export function createAuraApp(target, options) {
4526
5130
  let snapshot = normalizeSceneSnapshot(options.scene);
4527
5131
  let renderSnapshot = flattenSceneSnapshot(snapshot);
@@ -4537,6 +5141,32 @@ export function createAuraApp(target, options) {
4537
5141
  let lastTime = 0;
4538
5142
  let mountRevision = 0;
4539
5143
  let canvasRuntimePhysics;
5144
+ const runtimeNodes = createAuraRuntimeNodeRegistry(renderSnapshot);
5145
+ const frameCallbacks = new Set();
5146
+ let runtimePaused = options.autoStart === false;
5147
+ let runtimeFrame = 0;
5148
+ let runtimeTime = 0;
5149
+ const runtimeFixedDt = 1 / 60;
5150
+ let runtimeAlpha = 0;
5151
+ const ownedInputControllers = new Set();
5152
+ const runRuntimeFrame = (dt, source) => {
5153
+ runtimeFrame += 1;
5154
+ runtimeTime += dt;
5155
+ runtimeAlpha = runtimeFixedDt > 0 ? Math.max(0, Math.min(1, (dt % runtimeFixedDt) / runtimeFixedDt)) : 0;
5156
+ const frame = {
5157
+ dt,
5158
+ fixedDt: runtimeFixedDt,
5159
+ time: runtimeTime,
5160
+ frame: runtimeFrame,
5161
+ alpha: runtimeAlpha,
5162
+ paused: runtimePaused,
5163
+ source,
5164
+ substep: 1,
5165
+ substeps: 1
5166
+ };
5167
+ for (const callback of [...frameCallbacks])
5168
+ callback(frame);
5169
+ };
4540
5170
  const shouldUseProductionRendererForCurrentScene = () => Boolean(canvas && renderSnapshot.nodes.some(isWebGLRenderableNode) && typeof window !== "undefined");
4541
5171
  const resetDiagnosticsForCurrentScene = (backend) => {
4542
5172
  const fresh = createInitialDiagnostics(renderSnapshot);
@@ -4557,7 +5187,11 @@ export function createAuraApp(target, options) {
4557
5187
  return;
4558
5188
  const delta = lastTime > 0 ? Math.max(1, time - lastTime) : 16.67;
4559
5189
  lastTime = time;
4560
- canvasRuntimePhysics?.step(delta / 1000);
5190
+ const dt = delta / 1000;
5191
+ if (!runtimePaused) {
5192
+ runRuntimeFrame(dt, "raf");
5193
+ canvasRuntimePhysics?.step(dt);
5194
+ }
4561
5195
  diagnosticsState.evidence = collectAuraSceneEvidence(renderSnapshot);
4562
5196
  diagnosticsState.fps = Math.round(1000 / delta);
4563
5197
  diagnosticsState.drawCalls = renderSceneToCanvas(canvas, renderSnapshot, time);
@@ -4584,7 +5218,7 @@ export function createAuraApp(target, options) {
4584
5218
  overlay?.update();
4585
5219
  const revision = ++mountRevision;
4586
5220
  if (shouldUseProductionRenderer && canvas) {
4587
- void startProductionRender(canvas, renderSnapshot, diagnosticsState, options, overlay)
5221
+ void startProductionRender(canvas, renderSnapshot, diagnosticsState, options, overlay, runRuntimeFrame, () => runtimePaused)
4588
5222
  .then((controller) => {
4589
5223
  if (disposed || revision !== mountRevision) {
4590
5224
  controller.dispose();
@@ -4618,11 +5252,71 @@ export function createAuraApp(target, options) {
4618
5252
  setScene(nextScene) {
4619
5253
  snapshot = normalizeSceneSnapshot(nextScene);
4620
5254
  renderSnapshot = flattenSceneSnapshot(snapshot);
5255
+ runtimeNodes.reset(renderSnapshot);
4621
5256
  mountCurrentScene();
4622
5257
  },
5258
+ nodes: runtimeNodes,
5259
+ get runtime() {
5260
+ return {
5261
+ paused: runtimePaused,
5262
+ frame: runtimeFrame,
5263
+ time: runtimeTime,
5264
+ fixedDt: runtimeFixedDt,
5265
+ alpha: runtimeAlpha
5266
+ };
5267
+ },
5268
+ onFrame(callback) {
5269
+ frameCallbacks.add(callback);
5270
+ return () => {
5271
+ frameCallbacks.delete(callback);
5272
+ };
5273
+ },
5274
+ offFrame(callback) {
5275
+ frameCallbacks.delete(callback);
5276
+ },
5277
+ input(inputOptions) {
5278
+ const controller = createGameInput(inputOptions);
5279
+ ownedInputControllers.add(controller);
5280
+ return controller;
5281
+ },
5282
+ pause() {
5283
+ runtimePaused = true;
5284
+ },
5285
+ resume() {
5286
+ runtimePaused = false;
5287
+ if (!animationHandle && !productionController && options.autoStart !== false && typeof requestAnimationFrame !== "undefined") {
5288
+ animationHandle = requestAnimationFrame(render);
5289
+ }
5290
+ },
5291
+ step(dt = 1 / 60) {
5292
+ const seconds = Math.max(0, dt);
5293
+ runRuntimeFrame(seconds, "manual");
5294
+ canvasRuntimePhysics?.step(seconds);
5295
+ const previousPaused = runtimePaused;
5296
+ runtimePaused = true;
5297
+ if (productionController) {
5298
+ productionController.render(performanceNow());
5299
+ }
5300
+ else {
5301
+ render(performanceNow());
5302
+ }
5303
+ runtimePaused = previousPaused;
5304
+ },
4623
5305
  diagnostics() {
4624
5306
  return snapshotDiagnostics(diagnosticsState);
4625
5307
  },
5308
+ evidence(evidenceOptions = {}) {
5309
+ return collectGameRuntimeEvidenceV105({
5310
+ runtime: {
5311
+ paused: runtimePaused,
5312
+ frame: runtimeFrame,
5313
+ time: runtimeTime,
5314
+ fixedDt: runtimeFixedDt,
5315
+ alpha: runtimeAlpha
5316
+ },
5317
+ nodes: runtimeNodes
5318
+ }, evidenceOptions);
5319
+ },
4626
5320
  screenshot() {
4627
5321
  return captureAuraScreenshot(canvas);
4628
5322
  },
@@ -4630,11 +5324,24 @@ export function createAuraApp(target, options) {
4630
5324
  disposed = true;
4631
5325
  if (animationHandle && typeof cancelAnimationFrame !== "undefined")
4632
5326
  cancelAnimationFrame(animationHandle);
5327
+ for (const controller of ownedInputControllers)
5328
+ controller.dispose();
5329
+ ownedInputControllers.clear();
4633
5330
  productionController?.dispose();
4634
5331
  overlay?.dispose();
4635
5332
  }
4636
5333
  };
4637
5334
  }
5335
+ export function createGameApp(target, options) {
5336
+ const { input, loop, runtimeEvidence, ...appOptions } = options;
5337
+ const app = createAuraApp(target, { ...appOptions, autoStart: false });
5338
+ return createGameAppRuntime(app, {
5339
+ autoStart: options.autoStart,
5340
+ loop,
5341
+ input,
5342
+ evidence: runtimeEvidence
5343
+ });
5344
+ }
4638
5345
  export function createAuraRouteHealthSnapshot(app) {
4639
5346
  const diagnostics = app.diagnostics();
4640
5347
  return {
@@ -4653,6 +5360,10 @@ export function collectAuraSceneEvidence(sceneValue) {
4653
5360
  const assetProvenance = snapshot.nodes
4654
5361
  .filter((node) => node.kind === "model")
4655
5362
  .map((node) => createAssetProvenance(node.asset));
5363
+ const runtimeNodeIds = snapshot.nodes
5364
+ .map((node) => "runtime" in node ? node.runtime?.id : undefined)
5365
+ .filter((id) => Boolean(id));
5366
+ const expectsGameRuntime = runtimeNodeIds.length > 0 || interactionNodes.some((node) => node.mode === "keyboard" || node.mode === "drag-vector" || node.mode === "click-impulse");
4656
5367
  return {
4657
5368
  physics: {
4658
5369
  worldAttached: Boolean(snapshot.physics),
@@ -4690,6 +5401,31 @@ export function collectAuraSceneEvidence(sceneValue) {
4690
5401
  collisionAvoidance: labelNodes.filter((node) => node.collisionAvoidance === true).length
4691
5402
  },
4692
5403
  performance: createPerformanceEvidence(snapshot),
5404
+ gameRuntime: collectGameRuntimeEvidenceV105({
5405
+ runtime: {
5406
+ frame: 0,
5407
+ time: 0,
5408
+ paused: true
5409
+ },
5410
+ nodes: {
5411
+ ids: () => runtimeNodeIds
5412
+ }
5413
+ }, {
5414
+ animation: {
5415
+ controllers: animatedNodes.length,
5416
+ activeClips: clips,
5417
+ eventCount: 0
5418
+ },
5419
+ assets: {
5420
+ typedAssets: assetProvenance.filter((asset) => asset.source === "typed-aura-assets-manifest").length,
5421
+ missingAssets: []
5422
+ },
5423
+ source: {
5424
+ mode: "scene-source",
5425
+ expectsGame: expectsGameRuntime,
5426
+ label: "collectAuraSceneEvidence"
5427
+ }
5428
+ }),
4693
5429
  rendering: createRendererDiagnosticReport(snapshot),
4694
5430
  assets: assetProvenance
4695
5431
  };
@@ -4810,7 +5546,7 @@ function isRenderableModelNode(node) {
4810
5546
  function isWebGLRenderableNode(node) {
4811
5547
  return isRenderableModelNode(node) || node.kind === "primitive";
4812
5548
  }
4813
- async function startProductionRender(canvas, snapshot, diagnosticsState, options, overlay) {
5549
+ async function startProductionRender(canvas, snapshot, diagnosticsState, options, overlay, beforeRender, isPaused = () => false) {
4814
5550
  const renderableNode = snapshot.nodes.find(isWebGLRenderableNode);
4815
5551
  if (!renderableNode) {
4816
5552
  throw new AuraRuntimeError("missing-asset", "Aura3D production rendering requires at least one typed model asset or primitive. Suggested fix: add model(assets.product), primitives.box(), primitives.sphere(), primitives.cylinder(), or primitives.plane().");
@@ -4820,9 +5556,14 @@ async function startProductionRender(canvas, snapshot, diagnosticsState, options
4820
5556
  const continuousRender = shouldContinuouslyRender(snapshot);
4821
5557
  let disposed = false;
4822
5558
  let animationHandle = 0;
5559
+ let lastTime = 0;
4823
5560
  const renderFrame = (time = performanceNow()) => {
4824
5561
  if (disposed)
4825
5562
  return;
5563
+ const delta = lastTime > 0 ? Math.max(1, time - lastTime) : 16.67;
5564
+ lastTime = time;
5565
+ if (!isPaused())
5566
+ beforeRender?.(delta / 1000, "raf");
4826
5567
  const drawCalls = renderer.render(time);
4827
5568
  diagnosticsState.backend = "webgl2";
4828
5569
  diagnosticsState.fps = diagnosticsState.fps || 60;
@@ -4837,6 +5578,9 @@ async function startProductionRender(canvas, snapshot, diagnosticsState, options
4837
5578
  };
4838
5579
  renderFrame();
4839
5580
  return {
5581
+ render(time = performanceNow()) {
5582
+ renderFrame(time);
5583
+ },
4840
5584
  dispose() {
4841
5585
  disposed = true;
4842
5586
  if (animationHandle && typeof cancelAnimationFrame !== "undefined")
@@ -4851,6 +5595,8 @@ function shouldContinuouslyRender(snapshot) {
4851
5595
  if (snapshot.camera.mode === "dolly" || snapshot.camera.mode === "follow" || snapshot.camera.mode === "path" || snapshot.camera.mode === "flythrough")
4852
5596
  return true;
4853
5597
  return snapshot.nodes.some((node) => {
5598
+ if ("runtime" in node && node.runtime?.mutable !== false)
5599
+ return true;
4854
5600
  if ((node.kind === "model" || node.kind === "primitive") && node.animation)
4855
5601
  return true;
4856
5602
  if (node.kind !== "effect")
@@ -6179,7 +6925,7 @@ function normalizeSceneSnapshot(value) {
6179
6925
  }
6180
6926
  function resolveCanvas(target) {
6181
6927
  if (!target) {
6182
- throw new AuraRuntimeError("missing-canvas", "Aura3D could not mount because the app target was null or undefined. Suggested fix: pass a selector like createAuraApp(\"#app\", ...) or check document.querySelector before mounting.");
6928
+ return undefined;
6183
6929
  }
6184
6930
  if (typeof target === "string") {
6185
6931
  if (typeof document === "undefined") {