@auraindustry/aurajs 0.0.6 → 0.1.0

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 (334) hide show
  1. package/README.md +103 -7
  2. package/benchmarks/perf-thresholds.json +54 -0
  3. package/package.json +4 -7
  4. package/src/asset-pack.mjs +5 -1
  5. package/src/authored-project.mjs +1449 -0
  6. package/src/authored-runtime.mjs +2016 -0
  7. package/src/authoring/avatar-animation-graph.mjs +648 -0
  8. package/src/bin-integrity.mjs +272 -0
  9. package/src/build-contract/assets.mjs +130 -0
  10. package/src/build-contract/capabilities.mjs +116 -0
  11. package/src/build-contract/constants.mjs +6 -0
  12. package/src/build-contract/helpers.mjs +44 -0
  13. package/src/build-contract/web-templates.mjs +5993 -0
  14. package/src/build-contract.mjs +27 -2910
  15. package/src/bundler.mjs +188 -55
  16. package/src/cli.mjs +4825 -1512
  17. package/src/commands/project-authoring.mjs +434 -0
  18. package/src/config.mjs +27 -0
  19. package/src/conformance/cases/app-and-ui-runtime-cases.mjs +3309 -0
  20. package/src/conformance/cases/core-runtime-cases.mjs +1431 -0
  21. package/src/conformance/cases/index.mjs +11 -0
  22. package/src/conformance/cases/scene3d-and-media-cases.mjs +2094 -0
  23. package/src/conformance/cases/systems-and-gameplay-cases.mjs +1776 -0
  24. package/src/conformance/shared.mjs +27 -0
  25. package/src/conformance-runner.mjs +25 -13
  26. package/src/conformance.mjs +619 -4020
  27. package/src/cutscene.mjs +362 -5
  28. package/src/dev-cli-action.mjs +249 -0
  29. package/src/dev-cli-inspect.mjs +92 -0
  30. package/src/dev-cli-state.mjs +80 -0
  31. package/src/external-asset-cache.mjs +587 -0
  32. package/src/external-asset-policy.mjs +217 -0
  33. package/src/external-package-surface.mjs +206 -0
  34. package/src/game-action-runtime.mjs +869 -0
  35. package/src/game-state-runtime.mjs +206 -6
  36. package/src/headless-action.mjs +186 -0
  37. package/src/headless-test/runtime-animation.mjs +1173 -0
  38. package/src/headless-test/runtime-coordinator.mjs +1514 -0
  39. package/src/headless-test/runtime-primitives.mjs +320 -0
  40. package/src/headless-test/runtime-world.mjs +2253 -0
  41. package/src/headless-test.mjs +392 -4298
  42. package/src/host-binary.mjs +342 -14
  43. package/src/icon-discovery.mjs +64 -0
  44. package/src/make-catalog.mjs +109 -0
  45. package/src/make.mjs +197 -0
  46. package/src/package-integrity.mjs +586 -0
  47. package/src/perf-benchmark.mjs +353 -0
  48. package/src/postinstall.mjs +5 -5
  49. package/src/prefabs/index.mjs +34 -0
  50. package/src/prefabs/scene-serialization.mjs +184 -0
  51. package/src/project-importer.mjs +620 -0
  52. package/src/project-registry.mjs +24 -0
  53. package/src/publish-command.mjs +195 -0
  54. package/src/publish-env-example.mjs +83 -0
  55. package/src/publish-validation.mjs +708 -0
  56. package/src/retro/assets/compile.mjs +232 -0
  57. package/src/retro/backend-gba/authoring.mjs +1029 -0
  58. package/src/retro/backend-gba/rom.mjs +363 -0
  59. package/src/retro/backend-gbc/rom.mjs +85 -0
  60. package/src/retro/build.mjs +278 -0
  61. package/src/retro/cli/commands.mjs +292 -0
  62. package/src/retro/cli/templates.mjs +84 -0
  63. package/src/retro/diagnostics/catalog.mjs +110 -0
  64. package/src/retro/diagnostics/emit.mjs +72 -0
  65. package/src/retro/emulator/case-overlay.mjs +64 -0
  66. package/src/retro/emulator/discovery.mjs +158 -0
  67. package/src/retro/emulator/macos-case-overlay.swift +220 -0
  68. package/src/retro/emulator/profiles.mjs +146 -0
  69. package/src/retro/emulator/runner.mjs +289 -0
  70. package/src/retro/frontend/load-project.mjs +98 -0
  71. package/src/retro/index.mjs +30 -0
  72. package/src/retro/ir/build-ir.mjs +108 -0
  73. package/src/retro/runtime-gba/contract.mjs +151 -0
  74. package/src/retro/runtime-gbc/contract.mjs +117 -0
  75. package/src/retro/shared/span.mjs +26 -0
  76. package/src/retro/shared/targets.mjs +64 -0
  77. package/src/retro/validator/check-project.mjs +114 -0
  78. package/src/runtime-hotspot-audit.mjs +707 -0
  79. package/src/scaffold/config.mjs +1000 -0
  80. package/src/scaffold/fs.mjs +56 -0
  81. package/src/scaffold/layout.mjs +318 -0
  82. package/src/scaffold/project-docs.mjs +438 -0
  83. package/src/scaffold.mjs +93 -596
  84. package/src/scene-composition/index.mjs +326 -0
  85. package/src/scene-composition/runtime.mjs +751 -0
  86. package/src/self-hosted-assets.mjs +604 -0
  87. package/src/session-client.mjs +750 -0
  88. package/src/session-native-launcher.mjs +74 -0
  89. package/src/session-protocol.mjs +75 -0
  90. package/src/session-runtime.mjs +321 -0
  91. package/src/session-server.mjs +360 -0
  92. package/src/shader-kits/index.mjs +773 -0
  93. package/src/starter-content-registry.mjs +292 -0
  94. package/src/state-artifacts.mjs +662 -24
  95. package/src/state-dev-reload.mjs +99 -2
  96. package/src/terminal-ui.mjs +245 -0
  97. package/src/web-conformance.mjs +219 -0
  98. package/templates/create/2d/config/gameplay/shooter.config.js +26 -0
  99. package/templates/create/2d/content/gameplay/waves.json +26 -0
  100. package/templates/create/2d/content/registries/.gitkeep +1 -0
  101. package/templates/create/2d/docs/design/.gitkeep +1 -0
  102. package/templates/create/2d/docs/design/loop.md +5 -0
  103. package/templates/create/2d/prefabs/enemies.prefab.js +90 -0
  104. package/templates/create/2d/prefabs/enemy-basic.prefab.js +18 -0
  105. package/templates/create/2d/prefabs/player.prefab.js +36 -0
  106. package/templates/create/2d/prefabs/projectiles.prefab.js +35 -0
  107. package/templates/create/2d/scenes/boot.scene.js +12 -0
  108. package/templates/create/2d/scenes/gameplay.scene.js +230 -0
  109. package/templates/create/2d/scenes/menu.scene.js +9 -0
  110. package/templates/create/2d/src/main.js +6 -185
  111. package/templates/create/2d/src/runtime/app.js +49 -0
  112. package/templates/create/2d/src/runtime/capabilities.js +35 -0
  113. package/templates/create/2d/ui/hud.screen.js +40 -0
  114. package/templates/create/2d/ui/pause.screen.js +149 -0
  115. package/templates/create/2d/ui/settings.screen.js +347 -0
  116. package/templates/create/2d/ui/title.screen.js +13 -0
  117. package/templates/create/2d-adventure/aura.config.json +28 -0
  118. package/templates/create/2d-adventure/config/gameplay/adventure.config.js +14 -0
  119. package/templates/create/2d-adventure/content/gameplay/world.js +46 -0
  120. package/templates/create/2d-adventure/content/registries/.gitkeep +1 -0
  121. package/templates/create/2d-adventure/docs/design/loop.md +5 -0
  122. package/templates/create/2d-adventure/prefabs/player.prefab.js +54 -0
  123. package/templates/create/2d-adventure/prefabs/relic.prefab.js +38 -0
  124. package/templates/create/2d-adventure/prefabs/world.prefab.js +125 -0
  125. package/templates/create/2d-adventure/scenes/gameplay.scene.js +256 -0
  126. package/templates/create/2d-adventure/src/runtime/capabilities.js +34 -0
  127. package/templates/create/2d-adventure/ui/hud.screen.js +60 -0
  128. package/templates/create/2d-survivor/config/gameplay/survivor.config.js +33 -0
  129. package/templates/create/2d-survivor/content/gameplay/spawn-zones.json +29 -0
  130. package/templates/create/2d-survivor/content/registries/.gitkeep +1 -0
  131. package/templates/create/2d-survivor/docs/design/.gitkeep +1 -0
  132. package/templates/create/2d-survivor/docs/design/loop.md +5 -0
  133. package/templates/create/2d-survivor/prefabs/enemies.prefab.js +178 -0
  134. package/templates/create/2d-survivor/prefabs/enemy-swarm.prefab.js +18 -0
  135. package/templates/create/2d-survivor/prefabs/player.prefab.js +42 -0
  136. package/templates/create/2d-survivor/prefabs/projectiles.prefab.js +56 -0
  137. package/templates/create/2d-survivor/scenes/boot.scene.js +12 -0
  138. package/templates/create/2d-survivor/scenes/gameplay.scene.js +314 -0
  139. package/templates/create/2d-survivor/scenes/menu.scene.js +9 -0
  140. package/templates/create/2d-survivor/src/main.js +5 -332
  141. package/templates/create/2d-survivor/src/runtime/app.js +49 -0
  142. package/templates/create/2d-survivor/src/runtime/capabilities.js +35 -0
  143. package/templates/create/2d-survivor/ui/hud.screen.js +45 -0
  144. package/templates/create/2d-survivor/ui/title.screen.js +13 -0
  145. package/templates/create/3d/assets/models/starter-avatar.gltf +184 -0
  146. package/templates/create/3d/config/gameplay/.gitkeep +1 -0
  147. package/templates/create/3d/content/gameplay/checkpoints.json +33 -0
  148. package/templates/create/3d/content/gameplay/course.js +40 -0
  149. package/templates/create/3d/content/registries/.gitkeep +1 -0
  150. package/templates/create/3d/docs/design/.gitkeep +1 -0
  151. package/templates/create/3d/docs/design/loop.md +5 -0
  152. package/templates/create/3d/prefabs/checkpoint.prefab.js +15 -0
  153. package/templates/create/3d/prefabs/player.prefab.js +204 -0
  154. package/templates/create/3d/prefabs/world.prefab.js +112 -0
  155. package/templates/create/3d/scenes/boot.scene.js +12 -0
  156. package/templates/create/3d/scenes/checkpoint.scene.js +9 -0
  157. package/templates/create/3d/scenes/gameplay.scene.js +292 -0
  158. package/templates/create/3d/src/main.js +6 -295
  159. package/templates/create/3d/src/runtime/app.js +49 -0
  160. package/templates/create/3d/src/runtime/capabilities.js +53 -0
  161. package/templates/create/3d/src/runtime/materials.js +34 -0
  162. package/templates/create/3d/src/runtime/state.js +39 -0
  163. package/templates/create/3d/ui/hud.screen.js +75 -0
  164. package/templates/create/3d/ui/pause.screen.js +166 -0
  165. package/templates/create/3d/ui/settings.screen.js +387 -0
  166. package/templates/create/3d-adventure/assets/models/starter-avatar.gltf +184 -0
  167. package/templates/create/3d-adventure/aura.config.json +28 -0
  168. package/templates/create/3d-adventure/config/gameplay/adventure.config.js +9 -0
  169. package/templates/create/3d-adventure/content/gameplay/course.js +62 -0
  170. package/templates/create/3d-adventure/content/registries/.gitkeep +1 -0
  171. package/templates/create/3d-adventure/docs/design/loop.md +5 -0
  172. package/templates/create/3d-adventure/prefabs/player.prefab.js +168 -0
  173. package/templates/create/3d-adventure/prefabs/relic.prefab.js +35 -0
  174. package/templates/create/3d-adventure/prefabs/world.prefab.js +119 -0
  175. package/templates/create/3d-adventure/scenes/gameplay.scene.js +358 -0
  176. package/templates/create/3d-adventure/src/runtime/capabilities.js +56 -0
  177. package/templates/create/3d-adventure/src/runtime/materials.js +39 -0
  178. package/templates/create/3d-adventure/src/runtime/state.js +31 -0
  179. package/templates/create/3d-adventure/ui/hud.screen.js +70 -0
  180. package/templates/create/3d-adventure/ui/pause.screen.js +437 -0
  181. package/templates/create/3d-collectathon/assets/models/starter-avatar.gltf +184 -0
  182. package/templates/create/3d-collectathon/config/gameplay/.gitkeep +1 -0
  183. package/templates/create/3d-collectathon/content/gameplay/collectibles.json +26 -0
  184. package/templates/create/3d-collectathon/content/gameplay/course.js +46 -0
  185. package/templates/create/3d-collectathon/content/registries/.gitkeep +1 -0
  186. package/templates/create/3d-collectathon/docs/design/.gitkeep +1 -0
  187. package/templates/create/3d-collectathon/docs/design/loop.md +5 -0
  188. package/templates/create/3d-collectathon/prefabs/collectible.prefab.js +15 -0
  189. package/templates/create/3d-collectathon/prefabs/player.prefab.js +207 -0
  190. package/templates/create/3d-collectathon/prefabs/world.prefab.js +112 -0
  191. package/templates/create/3d-collectathon/scenes/boot.scene.js +12 -0
  192. package/templates/create/3d-collectathon/scenes/checkpoint.scene.js +9 -0
  193. package/templates/create/3d-collectathon/scenes/gameplay.scene.js +200 -0
  194. package/templates/create/3d-collectathon/src/main.js +5 -355
  195. package/templates/create/3d-collectathon/src/runtime/app.js +49 -0
  196. package/templates/create/3d-collectathon/src/runtime/capabilities.js +53 -0
  197. package/templates/create/3d-collectathon/src/runtime/materials.js +34 -0
  198. package/templates/create/3d-collectathon/src/runtime/state.js +27 -0
  199. package/templates/create/3d-collectathon/ui/hud.screen.js +66 -0
  200. package/templates/create/3d-collectathon/ui/pause.screen.js +13 -0
  201. package/templates/create/blank/config/gameplay/.gitkeep +1 -0
  202. package/templates/create/blank/content/gameplay/.gitkeep +1 -0
  203. package/templates/create/blank/content/registries/.gitkeep +1 -0
  204. package/templates/create/blank/docs/design/.gitkeep +1 -0
  205. package/templates/create/blank/docs/design/loop.md +5 -0
  206. package/templates/create/blank/prefabs/.gitkeep +1 -0
  207. package/templates/create/blank/scenes/.gitkeep +1 -0
  208. package/templates/create/blank/src/runtime/.gitkeep +1 -0
  209. package/templates/create/blank/ui/.gitkeep +1 -0
  210. package/templates/create/deckbuilder-2d/assets/audio/.gitkeep +1 -0
  211. package/templates/create/deckbuilder-2d/assets/fonts/.gitkeep +1 -0
  212. package/templates/create/deckbuilder-2d/assets/sprites/.gitkeep +1 -0
  213. package/templates/create/deckbuilder-2d/assets/starter/README.md +11 -0
  214. package/templates/create/deckbuilder-2d/assets/ui/.gitkeep +1 -0
  215. package/templates/create/deckbuilder-2d/aura.config.json +28 -0
  216. package/templates/create/deckbuilder-2d/config/gameplay/deckbuilder.config.js +26 -0
  217. package/templates/create/deckbuilder-2d/content/cards/guard.card.js +19 -0
  218. package/templates/create/deckbuilder-2d/content/cards/spark.card.js +20 -0
  219. package/templates/create/deckbuilder-2d/content/cards/starter.deck.js +69 -0
  220. package/templates/create/deckbuilder-2d/content/cards/strike.card.js +19 -0
  221. package/templates/create/deckbuilder-2d/content/cards/survey.card.js +20 -0
  222. package/templates/create/deckbuilder-2d/content/encounters/training-battle.encounter.js +14 -0
  223. package/templates/create/deckbuilder-2d/content/encounters/training-battle.js +65 -0
  224. package/templates/create/deckbuilder-2d/content/enemies/training-automaton.enemy.js +48 -0
  225. package/templates/create/deckbuilder-2d/content/gameplay/.gitkeep +1 -0
  226. package/templates/create/deckbuilder-2d/content/registries/cards.registry.js +26 -0
  227. package/templates/create/deckbuilder-2d/content/registries/encounters.registry.js +20 -0
  228. package/templates/create/deckbuilder-2d/content/registries/enemies.registry.js +20 -0
  229. package/templates/create/deckbuilder-2d/content/registries/relics.registry.js +20 -0
  230. package/templates/create/deckbuilder-2d/content/relics/ember-charm.relic.js +18 -0
  231. package/templates/create/deckbuilder-2d/docs/design/loop.md +12 -0
  232. package/templates/create/deckbuilder-2d/prefabs/.gitkeep +1 -0
  233. package/templates/create/deckbuilder-2d/scenes/boot.scene.js +84 -0
  234. package/templates/create/deckbuilder-2d/scenes/gameplay.scene.js +641 -0
  235. package/templates/create/deckbuilder-2d/src/components/.gitkeep +1 -0
  236. package/templates/create/deckbuilder-2d/src/main.js +17 -0
  237. package/templates/create/deckbuilder-2d/src/runtime/capabilities.js +22 -0
  238. package/templates/create/deckbuilder-2d/src/shared/.gitkeep +1 -0
  239. package/templates/create/deckbuilder-2d/src/systems/.gitkeep +1 -0
  240. package/templates/create/deckbuilder-2d/tests/smoke/.gitkeep +1 -0
  241. package/templates/create/deckbuilder-2d/ui/hud.screen.js +80 -0
  242. package/templates/create/deckbuilder-2d/ui/pause.screen.js +146 -0
  243. package/templates/create/deckbuilder-2d/ui/settings.screen.js +342 -0
  244. package/templates/create/local-multiplayer/aura.config.json +40 -0
  245. package/templates/create/local-multiplayer/config/gameplay/local-multiplayer.config.js +26 -0
  246. package/templates/create/local-multiplayer/content/gameplay/room-layout.js +13 -0
  247. package/templates/create/local-multiplayer/content/registries/.gitkeep +1 -0
  248. package/templates/create/local-multiplayer/docs/design/loop.md +14 -0
  249. package/templates/create/local-multiplayer/prefabs/player.prefab.js +99 -0
  250. package/templates/create/local-multiplayer/scenes/boot.scene.js +12 -0
  251. package/templates/create/local-multiplayer/scenes/gameplay.scene.js +443 -0
  252. package/templates/create/local-multiplayer/src/main.js +17 -0
  253. package/templates/create/local-multiplayer/src/runtime/capabilities.js +28 -0
  254. package/templates/create/local-multiplayer/ui/hud.screen.js +60 -0
  255. package/templates/create/shared/src/runtime/project-inspector.js +105 -0
  256. package/templates/create/shared/src/runtime/scene-flow.js +290 -0
  257. package/templates/create/shared/src/runtime/screen-shell.js +222 -0
  258. package/templates/create/shared/src/runtime/ui-forms.js +209 -0
  259. package/templates/create/shared/src/runtime/ui-settings.js +237 -0
  260. package/templates/create/shared/src/runtime/ui-theme.js +352 -0
  261. package/templates/create/shared/src/starter-utils/adventure-objectives.js +102 -0
  262. package/templates/create/shared/src/starter-utils/animation-2d.js +337 -0
  263. package/templates/create/shared/src/starter-utils/avatar-3d.js +404 -0
  264. package/templates/create/shared/src/starter-utils/combat-feedback-2d.js +320 -0
  265. package/templates/create/shared/src/starter-utils/core.js +39 -3
  266. package/templates/create/shared/src/starter-utils/index.js +8 -2
  267. package/templates/create/shared/src/starter-utils/platformer-3d.js +34 -3
  268. package/templates/create/shared/src/starter-utils/triggers.js +662 -0
  269. package/templates/create/shared/src/starter-utils/tween-2d.js +615 -0
  270. package/templates/create/video-cutscene/assets/video/.gitkeep +0 -0
  271. package/templates/create/video-cutscene/aura.config.json +28 -0
  272. package/templates/create/video-cutscene/config/gameplay/.gitkeep +0 -0
  273. package/templates/create/video-cutscene/content/gameplay/.gitkeep +0 -0
  274. package/templates/create/video-cutscene/content/registries/.gitkeep +0 -0
  275. package/templates/create/video-cutscene/docs/design/loop.md +22 -0
  276. package/templates/create/video-cutscene/prefabs/.gitkeep +0 -0
  277. package/templates/create/video-cutscene/scenes/boot.scene.js +11 -0
  278. package/templates/create/video-cutscene/scenes/cutscene.scene.js +113 -0
  279. package/templates/create/video-cutscene/scenes/gameplay.scene.js +50 -0
  280. package/templates/create/video-cutscene/src/main.js +17 -0
  281. package/templates/create/video-cutscene/src/runtime/app.js +52 -0
  282. package/templates/create/video-cutscene/src/runtime/capabilities.js +35 -0
  283. package/templates/create/video-cutscene/src/runtime/state.js +13 -0
  284. package/templates/create/video-cutscene/ui/.gitkeep +0 -0
  285. package/templates/create-bin/play.js +1187 -0
  286. package/templates/make/README.md +46 -0
  287. package/templates/make/catalog.json +51 -0
  288. package/templates/make/component/files/{{MAKE_NAME}}.component.js +20 -0
  289. package/templates/make/component/manifest.json +9 -0
  290. package/templates/make/data/files/{{MAKE_NAME}}.json +14 -0
  291. package/templates/make/data/manifest.json +9 -0
  292. package/templates/make/material/files/{{MAKE_NAME}}.material.json +17 -0
  293. package/templates/make/material/manifest.json +9 -0
  294. package/templates/make/prefab/files/{{MAKE_NAME}}.prefab.js +20 -0
  295. package/templates/make/prefab/manifest.json +9 -0
  296. package/templates/make/scene/files/{{MAKE_NAME}}.scene.js +31 -0
  297. package/templates/make/scene/manifest.json +9 -0
  298. package/templates/make/shader/files/{{MAKE_NAME}}.shader.js +23 -0
  299. package/templates/make/shader/manifest.json +9 -0
  300. package/templates/make/system/files/{{MAKE_NAME}}.system.js +15 -0
  301. package/templates/make/system/manifest.json +9 -0
  302. package/templates/make/ui-screen/files/{{MAKE_NAME}}.screen.js +16 -0
  303. package/templates/make/ui-screen/files/{{MAKE_NAME}}.screen.json +23 -0
  304. package/templates/make/ui-screen/manifest.json +10 -0
  305. package/templates/make-starters/deckbuilder-2d/card/files/{{MAKE_NAME}}.card.js +22 -0
  306. package/templates/make-starters/deckbuilder-2d/card/manifest.json +9 -0
  307. package/templates/make-starters/deckbuilder-2d/catalog.json +34 -0
  308. package/templates/make-starters/deckbuilder-2d/encounter/files/{{MAKE_NAME}}.encounter.js +18 -0
  309. package/templates/make-starters/deckbuilder-2d/encounter/manifest.json +9 -0
  310. package/templates/make-starters/deckbuilder-2d/enemy/files/{{MAKE_NAME}}.enemy.js +28 -0
  311. package/templates/make-starters/deckbuilder-2d/enemy/manifest.json +9 -0
  312. package/templates/make-starters/deckbuilder-2d/relic/files/{{MAKE_NAME}}.relic.js +23 -0
  313. package/templates/make-starters/deckbuilder-2d/relic/manifest.json +9 -0
  314. package/templates/retro/platformer/README.md +10 -0
  315. package/templates/retro/platformer/assets/retro/assets.json +91 -0
  316. package/templates/retro/platformer/aura.config.json +7 -0
  317. package/templates/retro/platformer/package.json +5 -0
  318. package/templates/retro/platformer/src/main.js +40 -0
  319. package/templates/retro/puzzle-grid/README.md +10 -0
  320. package/templates/retro/puzzle-grid/assets/retro/assets.json +90 -0
  321. package/templates/retro/puzzle-grid/aura.config.json +7 -0
  322. package/templates/retro/puzzle-grid/package.json +5 -0
  323. package/templates/retro/puzzle-grid/src/main.js +29 -0
  324. package/templates/retro/tactics-grid/README.md +10 -0
  325. package/templates/retro/tactics-grid/assets/retro/assets.json +90 -0
  326. package/templates/retro/tactics-grid/aura.config.json +7 -0
  327. package/templates/retro/tactics-grid/package.json +5 -0
  328. package/templates/retro/tactics-grid/src/main.js +35 -0
  329. package/templates/retro/topdown-adventure/README.md +10 -0
  330. package/templates/retro/topdown-adventure/assets/retro/assets.json +95 -0
  331. package/templates/retro/topdown-adventure/aura.config.json +7 -0
  332. package/templates/retro/topdown-adventure/package.json +5 -0
  333. package/templates/retro/topdown-adventure/src/main.js +29 -0
  334. package/templates/skills/aurajs/SKILL.md +61 -5
@@ -4,7 +4,7 @@ export const GAME_STATE_SCHEMA_VERSION = 'aurajs.game-state.v1';
4
4
 
5
5
  const CANONICAL_TOP_LEVEL_ORDER = ['schemaVersion', 'export', 'state'];
6
6
  const CANONICAL_EXPORT_ORDER = ['mode', 'seed', 'frameIndex', 'elapsedSeconds', 'fingerprint', 'capturedAt'];
7
- const CANONICAL_STATE_SECTION_ORDER = ['globals', 'camera', 'scene3d', 'physics', 'ecs', 'tilemap'];
7
+ const CANONICAL_STATE_SECTION_ORDER = ['globals', 'camera', 'project', 'scene3d', 'physics', 'ecs', 'tilemap'];
8
8
  const SUPPORTED_TOP_LEVEL_KEYS = new Set(CANONICAL_TOP_LEVEL_ORDER);
9
9
  const SUPPORTED_STATE_SECTION_KEYS = new Set(CANONICAL_STATE_SECTION_ORDER);
10
10
  const SUPPORTED_PATCH_MUTATION_OPS = new Set(['set', 'delete']);
@@ -15,6 +15,7 @@ const DEFAULT_MUTATION_MAX_RUNTIME_MS = 200;
15
15
  export const STATE_MUTATION_ALLOWLIST_PREFIXES = Object.freeze([
16
16
  '/state/globals',
17
17
  '/state/camera',
18
+ '/state/project',
18
19
  '/state/scene3d',
19
20
  '/state/physics',
20
21
  '/state/ecs',
@@ -31,7 +32,7 @@ export const DEFAULT_STATE_MUTATION_GUARDRAILS = Object.freeze({
31
32
  export function installStateRestoreRuntimeBootstrap(aura) {
32
33
  const schemaVersion = 'aurajs.game-state.v1';
33
34
  const knownTopLevel = Object.freeze(['schemaVersion', 'export', 'state']);
34
- const knownStateSections = Object.freeze(['globals', 'camera', 'scene3d', 'physics', 'ecs', 'tilemap']);
35
+ const knownStateSections = Object.freeze(['globals', 'camera', 'project', 'scene3d', 'physics', 'ecs', 'tilemap']);
35
36
 
36
37
  const isObject = (value) => (
37
38
  !!value
@@ -49,7 +50,7 @@ export function installStateRestoreRuntimeBootstrap(aura) {
49
50
  }
50
51
  if (isObject(value)) {
51
52
  const out = {};
52
- for (const key of Object.keys(value).sort((a, b) => a.localeCompare(b))) {
53
+ for (const key of Object.keys(value).sort()) {
53
54
  const next = sanitizeJsonValueLocal(value[key]);
54
55
  if (next === undefined) continue;
55
56
  out[key] = next;
@@ -61,7 +62,7 @@ export function installStateRestoreRuntimeBootstrap(aura) {
61
62
  const sanitizeObjectLocal = (value) => {
62
63
  const out = {};
63
64
  const source = isObject(value) ? value : {};
64
- for (const key of Object.keys(source).sort((a, b) => a.localeCompare(b))) {
65
+ for (const key of Object.keys(source).sort()) {
65
66
  const next = sanitizeJsonValueLocal(source[key]);
66
67
  if (next === undefined) continue;
67
68
  out[key] = next;
@@ -82,9 +83,33 @@ export function installStateRestoreRuntimeBootstrap(aura) {
82
83
  };
83
84
  const resolveGlobalsMapLocal = () => {
84
85
  const storage = aura?.storage && typeof aura.storage === 'object' ? aura.storage : null;
86
+ if (storage && typeof storage.save === 'function' && typeof storage.set !== 'function') {
87
+ storage.set = (key, value) => storage.save(key, value);
88
+ }
89
+ if (storage && typeof storage.load === 'function' && typeof storage.get !== 'function') {
90
+ storage.get = (key, fallback = null) => {
91
+ const value = storage.load(key);
92
+ return value == null ? fallback : value;
93
+ };
94
+ }
85
95
  if (storage && storage._store instanceof Map) {
86
96
  return storage._store;
87
97
  }
98
+ if (storage && typeof storage.keys === 'function' && typeof storage.load === 'function') {
99
+ const map = new Map();
100
+ try {
101
+ const keys = storage.keys();
102
+ if (Array.isArray(keys)) {
103
+ for (const key of [...keys].map((entry) => String(entry)).sort()) {
104
+ map.set(key, sanitizeJsonValueLocal(storage.load(key)));
105
+ }
106
+ }
107
+ } catch {}
108
+ if (aura && typeof aura === 'object') {
109
+ aura.__gameStateGlobals = map;
110
+ }
111
+ return map;
112
+ }
88
113
  if (aura && aura.__gameStateGlobals instanceof Map) {
89
114
  return aura.__gameStateGlobals;
90
115
  }
@@ -101,10 +126,20 @@ export function installStateRestoreRuntimeBootstrap(aura) {
101
126
  const globalsMap = resolveGlobalsMapLocal();
102
127
  globalsMap.clear();
103
128
  const normalized = sanitizeObjectLocal(sectionValue);
129
+ const storage = aura?.storage && typeof aura.storage === 'object' ? aura.storage : null;
130
+ if (storage && typeof storage.keys === 'function' && typeof storage.delete === 'function') {
131
+ try {
132
+ const existingKeys = storage.keys();
133
+ if (Array.isArray(existingKeys)) {
134
+ for (const key of existingKeys) {
135
+ storage.delete(key);
136
+ }
137
+ }
138
+ } catch {}
139
+ }
104
140
  for (const [key, value] of Object.entries(normalized)) {
105
141
  globalsMap.set(key, value);
106
142
  }
107
- const storage = aura?.storage && typeof aura.storage === 'object' ? aura.storage : null;
108
143
  if (storage && typeof storage.set === 'function') {
109
144
  for (const [key, value] of globalsMap.entries()) {
110
145
  storage.set(key, value);
@@ -222,17 +257,175 @@ export function installStateRestoreRuntimeBootstrap(aura) {
222
257
  state: collectCanonicalStateFromPayloadLocal(payload.state),
223
258
  };
224
259
  };
260
+ const mapToObjectLocal = (map) => {
261
+ const out = {};
262
+ const rows = [...map.entries()].map(([key, value]) => [String(key), sanitizeJsonValueLocal(value)]);
263
+ rows.sort((a, b) => (
264
+ a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0
265
+ ));
266
+ for (const [key, value] of rows) {
267
+ out[key] = value;
268
+ }
269
+ return out;
270
+ };
271
+ const collectCameraSnapshotLocal = () => {
272
+ if (!aura?.camera || typeof aura.camera !== 'object') {
273
+ return null;
274
+ }
275
+
276
+ let source = null;
277
+ if (typeof aura.camera.getState === 'function') {
278
+ try {
279
+ source = aura.camera.getState();
280
+ } catch {
281
+ source = null;
282
+ }
283
+ }
284
+
285
+ if (!isObject(source)) {
286
+ source = {
287
+ x: aura.camera.x,
288
+ y: aura.camera.y,
289
+ zoom: aura.camera.zoom,
290
+ rotation: aura.camera.rotation,
291
+ };
292
+ }
293
+
294
+ if (!isObject(source)) {
295
+ return null;
296
+ }
297
+
298
+ const camera = {};
299
+ if (Number.isFinite(source.x)) camera.x = Number(source.x);
300
+ if (Number.isFinite(source.y)) camera.y = Number(source.y);
301
+ if (Number.isFinite(source.zoom) && source.zoom > 0) camera.zoom = Number(source.zoom);
302
+ if (Number.isFinite(source.rotation)) camera.rotation = Number(source.rotation);
303
+ if (typeof source.following === 'boolean') camera.following = source.following;
304
+ if (Number.isInteger(source.activeEffects) && source.activeEffects >= 0) {
305
+ camera.activeEffects = Number(source.activeEffects);
306
+ }
307
+
308
+ return Object.keys(camera).length > 0 ? camera : null;
309
+ };
310
+ const collectObjectSectionLocal = (section) => {
311
+ if (!section || typeof section !== 'object') {
312
+ return null;
313
+ }
314
+ if (typeof section.getState === 'function') {
315
+ try {
316
+ const state = section.getState();
317
+ if (state && typeof state === 'object') {
318
+ return state;
319
+ }
320
+ } catch {
321
+ return null;
322
+ }
323
+ }
324
+ return null;
325
+ };
326
+ const collectStateSectionsLocal = () => collectCanonicalStateFromPayloadLocal({
327
+ globals: mapToObjectLocal(resolveGlobalsMapLocal()),
328
+ camera: collectCameraSnapshotLocal(),
329
+ project: collectObjectSectionLocal(aura?.project),
330
+ scene3d: collectObjectSectionLocal(aura?.scene3d),
331
+ physics: collectObjectSectionLocal(aura?.physics),
332
+ ecs: collectObjectSectionLocal(aura?.ecs),
333
+ tilemap: collectObjectSectionLocal(aura?.tilemap),
334
+ });
335
+ const normalizeIntLocal = (value, fallback = 0) => (
336
+ Number.isInteger(Number(value)) && Number(value) >= 0
337
+ ? Number(value)
338
+ : Number(fallback)
339
+ );
340
+ const normalizeModeLocal = (value) => {
341
+ const normalized = typeof value === 'string' ? value.trim().toLowerCase() : '';
342
+ if (normalized === 'headless' || normalized === 'shim') {
343
+ return normalized;
344
+ }
345
+ return 'native';
346
+ };
347
+ const normalizeElapsedSecondsLocal = (value) => (
348
+ Number.isFinite(Number(value)) && Number(value) >= 0
349
+ ? Number(value)
350
+ : 0
351
+ );
352
+ const normalizeCapturedAtLocal = (value) => (
353
+ typeof value === 'string' && value.trim()
354
+ ? value.trim()
355
+ : new Date().toISOString()
356
+ );
357
+ const stableStringifyLocal = (value) => JSON.stringify(sanitizeJsonValueLocal(value));
358
+ const hashHex64Local = (value) => {
359
+ const text = String(value || '');
360
+ let hash = 2166136261;
361
+ for (let i = 0; i < text.length; i += 1) {
362
+ hash ^= text.charCodeAt(i);
363
+ hash = Math.imul(hash, 16777619);
364
+ }
365
+ const chunk = (hash >>> 0).toString(16).padStart(8, '0');
366
+ return chunk.repeat(8);
367
+ };
368
+ const orderExportPayloadLocal = (payload) => {
369
+ const orderedExport = {
370
+ mode: payload.export.mode,
371
+ seed: payload.export.seed,
372
+ frameIndex: payload.export.frameIndex,
373
+ elapsedSeconds: payload.export.elapsedSeconds,
374
+ fingerprint: payload.export.fingerprint,
375
+ capturedAt: payload.export.capturedAt,
376
+ };
377
+ return {
378
+ schemaVersion: payload.schemaVersion,
379
+ export: orderedExport,
380
+ state: payload.state,
381
+ };
382
+ };
383
+ const exportPayload = (options = {}) => {
384
+ const state = collectStateSectionsLocal();
385
+ const payload = {
386
+ schemaVersion,
387
+ export: {
388
+ mode: normalizeModeLocal(options.mode),
389
+ seed: normalizeIntLocal(options.seed, 0),
390
+ frameIndex: normalizeIntLocal(options.frameIndex, 0),
391
+ elapsedSeconds: normalizeElapsedSecondsLocal(options.elapsedSeconds),
392
+ fingerprint: hashHex64Local(stableStringifyLocal(state)),
393
+ capturedAt: normalizeCapturedAtLocal(options.capturedAt),
394
+ },
395
+ state,
396
+ };
397
+
398
+ return {
399
+ ok: true,
400
+ reasonCode: 'state_export_ok',
401
+ payload: orderExportPayloadLocal(payload),
402
+ };
403
+ };
225
404
 
226
405
  if (!aura || typeof aura !== 'object') {
227
406
  return {
407
+ export() {
408
+ return { ok: false, reasonCode: 'state_export_failed', detail: 'aura runtime unavailable' };
409
+ },
410
+ exportState() {
411
+ return { ok: false, reasonCode: 'state_export_failed', detail: 'aura runtime unavailable' };
412
+ },
228
413
  apply() {
229
414
  return { ok: false, reasonCode: 'invalid_schema_payload', detail: 'aura runtime unavailable' };
230
415
  },
416
+ applyState() {
417
+ return { ok: false, reasonCode: 'invalid_schema_payload', detail: 'aura runtime unavailable' };
418
+ },
231
419
  };
232
420
  }
233
421
 
234
422
  const stateNamespace = aura.state && typeof aura.state === 'object' ? aura.state : {};
235
- if (typeof stateNamespace.apply === 'function' && typeof stateNamespace.applyState === 'function') {
423
+ if (
424
+ typeof stateNamespace.apply === 'function'
425
+ && typeof stateNamespace.applyState === 'function'
426
+ && typeof stateNamespace.export === 'function'
427
+ && typeof stateNamespace.exportState === 'function'
428
+ ) {
236
429
  stateNamespace.schemaVersion = schemaVersion;
237
430
  aura.state = stateNamespace;
238
431
  return stateNamespace;
@@ -274,6 +467,12 @@ export function installStateRestoreRuntimeBootstrap(aura) {
274
467
  };
275
468
 
276
469
  stateNamespace.schemaVersion = schemaVersion;
470
+ if (typeof stateNamespace.export !== 'function') {
471
+ stateNamespace.export = exportPayload;
472
+ }
473
+ if (typeof stateNamespace.exportState !== 'function') {
474
+ stateNamespace.exportState = exportPayload;
475
+ }
277
476
  if (typeof stateNamespace.apply !== 'function') {
278
477
  stateNamespace.apply = applyPayload;
279
478
  }
@@ -665,6 +864,7 @@ function collectStateSections(aura) {
665
864
  const raw = {
666
865
  globals,
667
866
  camera,
867
+ project: collectObjectSection(aura.project),
668
868
  scene3d: collectObjectSection(aura.scene3d),
669
869
  physics: collectObjectSection(aura.physics),
670
870
  ecs: collectObjectSection(aura.ecs),
@@ -0,0 +1,186 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import vm from 'node:vm';
4
+
5
+ import { bundleProject } from './bundler.mjs';
6
+ import {
7
+ HeadlessTestError,
8
+ createHeadlessAura,
9
+ createRuntimeContext,
10
+ executeSetup,
11
+ executeFrameSteps,
12
+ } from './headless-test.mjs';
13
+
14
+ function createHeadlessActionTestState() {
15
+ return {
16
+ failures: [],
17
+ passes: 0,
18
+ drawCalls: 0,
19
+ audioCalls: 0,
20
+ logs: [],
21
+ };
22
+ }
23
+
24
+ export async function runHeadlessActionSchema(options = {}) {
25
+ const runtime = await bootHeadlessActionRuntime(options, '.aura/test/action-schema.bundle.js');
26
+ const schemaResult = resolveActionSchemaResult(runtime.aura);
27
+
28
+ return {
29
+ ok: true,
30
+ entryFile: runtime.entryFile,
31
+ bundle: runtime.bundle,
32
+ frames: 0,
33
+ width: runtime.width,
34
+ height: runtime.height,
35
+ schemaResult,
36
+ passes: runtime.testState.passes,
37
+ drawCalls: runtime.testState.drawCalls,
38
+ audioCalls: runtime.testState.audioCalls,
39
+ };
40
+ }
41
+
42
+ export async function runHeadlessActionRun(options = {}) {
43
+ const runtime = await bootHeadlessActionRuntime(options, '.aura/test/action-run.bundle.js');
44
+ const frames = options.frames ?? 0;
45
+ const request = options.request;
46
+ let seedStateApplyResult = null;
47
+
48
+ if (!request || typeof request !== 'object' || Array.isArray(request)) {
49
+ throw new HeadlessTestError('Headless action run failed: request must be an object.');
50
+ }
51
+
52
+ if (options.statePayload != null) {
53
+ if (!runtime.aura.state || typeof runtime.aura.state.apply !== 'function') {
54
+ throw new HeadlessTestError('Headless action run failed: aura.state.apply hook is unavailable.');
55
+ }
56
+ seedStateApplyResult = runtime.aura.state.apply(options.statePayload);
57
+ if (!seedStateApplyResult || typeof seedStateApplyResult !== 'object') {
58
+ throw new HeadlessTestError('Headless action run failed: aura.state.apply returned invalid result.');
59
+ }
60
+ if (seedStateApplyResult.ok !== true) {
61
+ return {
62
+ ok: true,
63
+ entryFile: runtime.entryFile,
64
+ bundle: runtime.bundle,
65
+ frames,
66
+ width: runtime.width,
67
+ height: runtime.height,
68
+ actionResult: null,
69
+ stateResult: null,
70
+ seedStateApplyResult,
71
+ passes: runtime.testState.passes,
72
+ drawCalls: runtime.testState.drawCalls,
73
+ audioCalls: runtime.testState.audioCalls,
74
+ };
75
+ }
76
+ }
77
+
78
+ const actionNs = runtime.aura.action && typeof runtime.aura.action === 'object'
79
+ ? runtime.aura.action
80
+ : null;
81
+ if (!actionNs || typeof actionNs.run !== 'function') {
82
+ throw new HeadlessTestError('Headless action run failed: aura.action.run hook is unavailable.');
83
+ }
84
+
85
+ let actionResult;
86
+ try {
87
+ actionResult = await Promise.resolve(actionNs.run(request));
88
+ } catch (error) {
89
+ throw new HeadlessTestError(`Headless action run failed: ${error.message}`, {
90
+ stack: error.stack,
91
+ });
92
+ }
93
+
94
+ let stateResult = null;
95
+ if (options.includeState === true || frames > 0) {
96
+ if (!runtime.aura.state || typeof runtime.aura.state.exportState !== 'function') {
97
+ throw new HeadlessTestError('Headless action run failed: aura.state.exportState hook is unavailable.');
98
+ }
99
+
100
+ await executeFrameSteps(runtime.aura, frames);
101
+
102
+ stateResult = runtime.aura.state.exportState({
103
+ mode: options.mode,
104
+ seed: options.seed,
105
+ frameIndex: options.frameIndex ?? frames,
106
+ elapsedSeconds: options.elapsedSeconds,
107
+ capturedAt: options.capturedAt ?? null,
108
+ });
109
+ }
110
+
111
+ return {
112
+ ok: true,
113
+ entryFile: runtime.entryFile,
114
+ bundle: runtime.bundle,
115
+ frames,
116
+ width: runtime.width,
117
+ height: runtime.height,
118
+ actionResult,
119
+ stateResult,
120
+ seedStateApplyResult,
121
+ passes: runtime.testState.passes,
122
+ drawCalls: runtime.testState.drawCalls,
123
+ audioCalls: runtime.testState.audioCalls,
124
+ };
125
+ }
126
+
127
+ async function bootHeadlessActionRuntime(options, outFile) {
128
+ const projectRoot = resolve(options.projectRoot || process.cwd());
129
+ const entryFile = resolve(projectRoot, options.file || 'src/main.js');
130
+ const width = options.width ?? 1280;
131
+ const height = options.height ?? 720;
132
+
133
+ if (!existsSync(entryFile)) {
134
+ throw new HeadlessTestError(`Action entry file not found: ${entryFile}`);
135
+ }
136
+
137
+ const bundle = bundleProject({
138
+ projectRoot,
139
+ mode: 'test',
140
+ entryFile,
141
+ outFile: resolve(projectRoot, outFile),
142
+ });
143
+
144
+ const testState = createHeadlessActionTestState();
145
+ const aura = createHeadlessAura({ width, height, testState });
146
+ const context = vm.createContext(createRuntimeContext(aura, testState));
147
+
148
+ const source = readFileSync(bundle.outFile, 'utf8');
149
+ const script = new vm.Script(source, {
150
+ filename: bundle.outFile,
151
+ displayErrors: true,
152
+ });
153
+
154
+ try {
155
+ script.runInContext(context, { timeout: 5000 });
156
+ await executeSetup(aura);
157
+ } catch (error) {
158
+ throw new HeadlessTestError(`Headless action execution failed: ${error.message}`, {
159
+ stack: error.stack,
160
+ });
161
+ }
162
+
163
+ return {
164
+ aura,
165
+ bundle,
166
+ entryFile,
167
+ width,
168
+ height,
169
+ testState,
170
+ };
171
+ }
172
+
173
+ function resolveActionSchemaResult(aura) {
174
+ const actionNs = aura.action && typeof aura.action === 'object' ? aura.action : null;
175
+ if (!actionNs || typeof actionNs.getSchema !== 'function') {
176
+ throw new HeadlessTestError('Headless action schema failed: aura.action.getSchema hook is unavailable.');
177
+ }
178
+
179
+ try {
180
+ return actionNs.getSchema();
181
+ } catch (error) {
182
+ throw new HeadlessTestError(`Headless action schema failed: ${error.message}`, {
183
+ stack: error.stack,
184
+ });
185
+ }
186
+ }