@auraindustry/aurajs 0.0.7 → 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 +98 -2
  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
package/src/scaffold.mjs CHANGED
@@ -1,340 +1,34 @@
1
- import { mkdirSync, writeFileSync, readFileSync, existsSync, readdirSync, statSync } from 'node:fs';
2
- import { resolve, join, dirname } from 'node:path';
3
- import { fileURLToPath } from 'node:url';
4
-
5
- const CLI_SRC_DIR = dirname(fileURLToPath(import.meta.url));
6
-
7
- const LEGACY_STARTER_TEMPLATE_DIR = resolve(CLI_SRC_DIR, '../templates/starter');
8
-
9
- const CREATE_TEMPLATE_DIRS = {
10
- '2d-shooter': resolve(CLI_SRC_DIR, '../templates/create/2d'),
11
- '2d-survivor': resolve(CLI_SRC_DIR, '../templates/create/2d-survivor'),
12
- '3d-platformer': resolve(CLI_SRC_DIR, '../templates/create/3d'),
13
- '3d-collectathon': resolve(CLI_SRC_DIR, '../templates/create/3d-collectathon'),
14
- blank: resolve(CLI_SRC_DIR, '../templates/create/blank'),
15
- };
16
- const CREATE_SHARED_TEMPLATE_DIR = resolve(CLI_SRC_DIR, '../templates/create/shared');
17
-
18
- const CREATE_TEMPLATE_ALIASES = {
19
- '2d': '2d-shooter',
20
- shooter: '2d-shooter',
21
- '2d shooter': '2d-shooter',
22
- '2d-shooter': '2d-shooter',
23
- '2d-survivor': '2d-survivor',
24
- survivor: '2d-survivor',
25
- '2d survival': '2d-survivor',
26
- '2d-survival': '2d-survivor',
27
- topdown: '2d-survivor',
28
- 'top-down': '2d-survivor',
29
- '3d': '3d-platformer',
30
- platformer: '3d-platformer',
31
- platformers: '3d-platformer',
32
- '3d platformer': '3d-platformer',
33
- '3d platformers': '3d-platformer',
34
- '3d-platformer': '3d-platformer',
35
- '3d-collectathon': '3d-collectathon',
36
- collectathon: '3d-collectathon',
37
- explorer: '3d-collectathon',
38
- exploration: '3d-collectathon',
39
- '3d collectathon': '3d-collectathon',
40
- '3d explorer': '3d-collectathon',
41
- blank: 'blank',
42
- };
43
- const CREATE_TEMPLATE_ALIAS_HINTS = ['2d', '3d', 'shooter', 'platformer', 'survivor', 'collectathon', 'blank'];
44
-
45
- const ROOT_SKILLS_DIR = resolve(CLI_SRC_DIR, '../../../skills');
46
- const PACKAGED_SKILLS_DIR = resolve(CLI_SRC_DIR, '../templates/skills');
47
-
48
- const GITIGNORE_TEMPLATE = `# Dependencies\nnode_modules/\n\n# Build output\nbuild/\n.aura/\n\n# Runtime logs\n.logs/\n*.log\nnpm-debug.log*\n\n# Local env\n.env\n.env.*\n`;
49
-
50
- const PLAY_BIN_TEMPLATE = `#!/usr/bin/env node
51
-
52
- import { spawn } from 'node:child_process';
53
- import { existsSync, mkdirSync, createWriteStream } from 'node:fs';
54
- import { resolve, dirname, join } from 'node:path';
55
- import { fileURLToPath } from 'node:url';
56
-
57
- const __dirname = dirname(fileURLToPath(import.meta.url));
58
- const projectRoot = resolve(__dirname, '..');
59
- const localAuraCli = resolve(projectRoot, 'node_modules', '@auraindustry', 'aurajs', 'src', 'cli.mjs');
60
- const runArgs = ['run', '--asset-mode', 'sibling'];
61
-
62
- const logDir = resolve(projectRoot, '.logs');
63
- mkdirSync(logDir, { recursive: true });
64
- const stamp = new Date().toISOString().replace(/[:.]/g, '-');
65
- const logPath = join(logDir, \`play-\${stamp}.log\`);
66
- const logStream = createWriteStream(logPath, { flags: 'a' });
67
-
68
- const command = existsSync(localAuraCli)
69
- ? {
70
- cmd: process.execPath,
71
- args: [localAuraCli, ...runArgs],
72
- }
73
- : {
74
- cmd: 'npm',
75
- args: ['exec', '--yes', '--package', '@auraindustry/aurajs', '--', 'aura', ...runArgs],
76
- };
77
-
78
- logStream.write(\`[play] \${new Date().toISOString()} command=\${command.cmd} \${command.args.join(' ')}\\n\`);
79
-
80
- const child = spawn(command.cmd, command.args, {
81
- cwd: projectRoot,
82
- stdio: ['inherit', 'pipe', 'pipe'],
83
- env: process.env,
84
- });
85
-
86
- function pipeToConsoleAndLog(stream, target) {
87
- if (!stream) return;
88
- stream.on('data', (chunk) => {
89
- target.write(chunk);
90
- logStream.write(chunk);
91
- });
92
- }
93
-
94
- pipeToConsoleAndLog(child.stdout, process.stdout);
95
- pipeToConsoleAndLog(child.stderr, process.stderr);
96
-
97
- child.on('error', (err) => {
98
- const message = \`[play:error] \${err.message}\\n\`;
99
- process.stderr.write(message);
100
- logStream.write(message);
101
- logStream.end();
102
- process.exit(1);
103
- });
104
-
105
- child.on('close', (code) => {
106
- logStream.write(\`\\n[play:exit] code=\${code ?? 1}\\n\`);
107
- logStream.end(() => {
108
- process.exit(code ?? 1);
109
- });
110
- });
111
- `;
112
-
113
- const CREATE_TEMPLATE_METADATA = {
114
- '2d-shooter': {
115
- summary: 'Arcade shooter baseline with waves, score, and lives loop.',
116
- controls: [
117
- 'Move: Arrow keys or WASD',
118
- 'Fire: Space or Z',
119
- 'Restart: Enter (after game over)',
120
- ],
121
- firstEdits: [
122
- 'Tune encounter pacing in src/main.js -> WAVE_CONFIG.',
123
- 'Add custom enemy variants in src/starter-utils/enemy-archetypes-2d.js.',
124
- 'Swap starter palette and HUD text in src/main.js.',
125
- ],
126
- keywords: ['2d', 'shooter', 'arcade'],
127
- requiredApis: [
128
- 'aura.window.getSize',
129
- 'aura.window.getFPS',
130
- 'aura.input.isKeyDown',
131
- 'aura.input.isKeyPressed',
132
- 'aura.draw2d.clear',
133
- 'aura.draw2d.rect',
134
- 'aura.draw2d.text',
135
- 'aura.draw2d.measureText',
136
- 'aura.rgb',
137
- 'aura.rgba',
138
- 'aura.Color.WHITE',
139
- ],
140
- starterAssetPlan: {
141
- file: 'wave-plan.json',
142
- title: '2D Shooter Wave Plan',
143
- steps: [
144
- 'Replace this JSON with your own wave progression and enemy mix.',
145
- 'Load this file in game logic after adding your preferred file-loading flow.',
146
- ],
147
- payload: {
148
- waves: [
149
- { id: 'intro', maxSpawns: 9, spawnEvery: 0.62, archetype: 'scout' },
150
- { id: 'pressure', maxSpawns: 10, spawnEvery: 0.56, archetype: 'striker' },
151
- { id: 'anchor', maxSpawns: 8, spawnEvery: 0.74, archetype: 'tank' },
152
- ],
153
- },
154
- },
155
- },
156
- '2d-survivor': {
157
- summary: 'Top-down auto-fire survival loop tuned for quick iteration.',
158
- controls: [
159
- 'Move: Arrow keys or WASD',
160
- 'Dash: Shift',
161
- 'Restart: Enter (after game over)',
162
- ],
163
- firstEdits: [
164
- 'Adjust spawn pressure in src/main.js -> spawnDirector + difficulty ramps.',
165
- 'Tune dash timings in src/main.js constants.',
166
- 'Extend enemy archetypes in src/starter-utils/enemy-archetypes-2d.js.',
167
- ],
168
- keywords: ['2d', 'survivor', 'topdown'],
169
- requiredApis: [
170
- 'aura.window.getSize',
171
- 'aura.window.getFPS',
172
- 'aura.input.isKeyDown',
173
- 'aura.input.isKeyPressed',
174
- 'aura.draw2d.clear',
175
- 'aura.draw2d.rect',
176
- 'aura.draw2d.text',
177
- 'aura.draw2d.measureText',
178
- 'aura.rgb',
179
- 'aura.rgba',
180
- 'aura.Color.WHITE',
181
- ],
182
- starterAssetPlan: {
183
- file: 'survivor-zones.json',
184
- title: '2D Survivor Spawn Zones',
185
- steps: [
186
- 'Use these zones to bias enemy spawns by map phase.',
187
- 'Add your own tags (boss, swarm, elite) and branch in update().',
188
- ],
189
- payload: {
190
- zones: [
191
- { id: 'north-lane', x: 0.5, y: 0.08, weight: 1.0 },
192
- { id: 'east-lane', x: 0.92, y: 0.52, weight: 1.2 },
193
- { id: 'south-lane', x: 0.5, y: 0.94, weight: 1.0 },
194
- { id: 'west-lane', x: 0.08, y: 0.52, weight: 1.1 },
195
- ],
196
- },
197
- },
198
- },
199
- '3d-platformer': {
200
- summary: '3D checkpoint platformer loop with moving platform helper primitives.',
201
- controls: [
202
- 'Move: Arrow keys or WASD',
203
- 'Jump: Space',
204
- 'Restart: Enter (after goal)',
205
- ],
206
- firstEdits: [
207
- 'Adjust traversal beats in src/main.js -> STATIC_PLATFORMS and CHECKPOINTS.',
208
- 'Tune camera offsets in aura.update.',
209
- 'Swap material colors in aura.setup for your theme.',
210
- ],
211
- keywords: ['3d', 'platformer', 'checkpoint'],
212
- requiredApis: [
213
- 'aura.mesh.createBox',
214
- 'aura.material.create',
215
- 'aura.light.ambient',
216
- 'aura.light.directional',
217
- 'aura.camera3d.perspective',
218
- 'aura.camera3d.setPosition',
219
- 'aura.camera3d.lookAt',
220
- 'aura.input.isKeyDown',
221
- 'aura.input.isKeyPressed',
222
- 'aura.draw3d.clear3d',
223
- 'aura.draw3d.drawMesh',
224
- 'aura.draw2d.text',
225
- 'aura.draw2d.measureText',
226
- 'aura.rgb',
227
- 'aura.Color.WHITE',
228
- ],
229
- starterAssetPlan: {
230
- file: 'checkpoint-route.json',
231
- title: '3D Platformer Route Notes',
232
- steps: [
233
- 'Use this path list to plan encounter/collectible placement between checkpoints.',
234
- 'Attach analytics ids if you track failed jump segments.',
235
- ],
236
- payload: {
237
- path: [
238
- { id: 'spawn', x: 0.0, y: 1.1, z: 5.5 },
239
- { id: 'ridge-a', x: -3.2, y: 2.0, z: -2.4 },
240
- { id: 'ridge-b', x: 1.4, y: 3.2, z: -0.8 },
241
- { id: 'goal', x: 4.4, y: 4.8, z: -3.0 },
242
- ],
243
- },
244
- },
245
- },
246
- '3d-collectathon': {
247
- summary: '3D collection race starter with timer pressure and checkpoint fallback.',
248
- controls: [
249
- 'Move: Arrow keys or WASD',
250
- 'Jump: Space',
251
- 'Restart: Enter (after clear/failure)',
252
- ],
253
- firstEdits: [
254
- 'Add world pieces in src/main.js -> WORLD_PLATFORMS + COLLECTIBLES.',
255
- 'Balance the timer and required collectible count in constants.',
256
- 'Customize checkpoint/goal feedback text in aura.draw.',
257
- ],
258
- keywords: ['3d', 'collectathon', 'exploration'],
259
- requiredApis: [
260
- 'aura.mesh.createBox',
261
- 'aura.material.create',
262
- 'aura.light.ambient',
263
- 'aura.light.directional',
264
- 'aura.camera3d.perspective',
265
- 'aura.camera3d.setPosition',
266
- 'aura.camera3d.lookAt',
267
- 'aura.input.isKeyDown',
268
- 'aura.input.isKeyPressed',
269
- 'aura.draw3d.clear3d',
270
- 'aura.draw3d.drawMesh',
271
- 'aura.draw2d.text',
272
- 'aura.draw2d.measureText',
273
- 'aura.rgb',
274
- 'aura.Color.WHITE',
275
- ],
276
- starterAssetPlan: {
277
- file: 'collectible-layout.json',
278
- title: '3D Collectathon Layout Plan',
279
- steps: [
280
- 'Extend this list with your final collectible and checkpoint route.',
281
- 'Optionally mirror ids in your quest/state system for save/load.',
282
- ],
283
- payload: {
284
- collectibles: [
285
- { id: 'orb-a', x: -2.8, y: 1.8, z: 2.2, value: 1 },
286
- { id: 'orb-b', x: 2.4, y: 2.4, z: 0.4, value: 1 },
287
- { id: 'orb-c', x: 4.6, y: 3.8, z: -2.8, value: 1 },
288
- ],
289
- },
290
- },
291
- },
292
- blank: {
293
- summary: 'Minimal blank loop with runtime API checks for quick custom starts.',
294
- controls: [
295
- 'No controls wired yet.',
296
- 'Add input + systems directly in src/main.js.',
297
- ],
298
- firstEdits: [
299
- 'Define your own game-state object and update loop in src/main.js.',
300
- 'Set modules and identity in aura.config.json.',
301
- 'Replace starter asset notes under assets/starter/.',
302
- ],
303
- keywords: ['blank', 'starter'],
304
- requiredApis: [
305
- 'aura.draw2d.clear',
306
- 'aura.rgba',
307
- ],
308
- starterAssetPlan: {
309
- file: 'starter-notes.json',
310
- title: 'Blank Starter Notes',
311
- steps: [
312
- 'Write your core loop goals before coding to keep agent prompts precise.',
313
- 'Track capability assumptions here as you expand runtime usage.',
314
- ],
315
- payload: {
316
- goals: [
317
- 'Define camera and movement model.',
318
- 'Pick combat/progression loop.',
319
- 'Specify first milestone acceptance criteria.',
320
- ],
321
- },
322
- },
323
- },
324
- };
325
-
326
- export function listCreateTemplates() {
327
- return Object.keys(CREATE_TEMPLATE_DIRS);
328
- }
329
-
330
- export function listCreateTemplateAliasHints() {
331
- return [...CREATE_TEMPLATE_ALIAS_HINTS];
332
- }
333
-
334
- export function normalizeCreateTemplate(template) {
335
- const normalized = String(template || '').trim().toLowerCase();
336
- return CREATE_TEMPLATE_ALIASES[normalized] || null;
337
- }
1
+ import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { initRetroTemplate } from './retro/cli/templates.mjs';
4
+
5
+ import {
6
+ CREATE_SHARED_TEMPLATE_DIR,
7
+ CREATE_TEMPLATE_DIRS,
8
+ GITIGNORE_TEMPLATE,
9
+ LEGACY_STARTER_TEMPLATE_DIR,
10
+ PLAY_BIN_TEMPLATE,
11
+ applyTemplateConfigOverrides,
12
+ buildCapabilitiesDeclaration,
13
+ buildPackageJson,
14
+ listCreateTemplateAliasHints,
15
+ listCreateTemplates,
16
+ normalizeCreateTemplate,
17
+ resolveSkillsSourceDir,
18
+ resolveTemplateMetadata,
19
+ sanitizeBinName,
20
+ shouldCopyCreateSharedTemplate,
21
+ toDisplayTitle,
22
+ } from './scaffold/config.mjs';
23
+ import { assertDestinationIsEmpty, copyTree, listFiles } from './scaffold/fs.mjs';
24
+ import { writeStarterAssetPack, writeUnityLikeProjectLayout } from './scaffold/layout.mjs';
25
+ import { renderProjectReadme, renderProjectRunbook } from './scaffold/project-docs.mjs';
26
+
27
+ export {
28
+ listCreateTemplateAliasHints,
29
+ listCreateTemplates,
30
+ normalizeCreateTemplate,
31
+ } from './scaffold/config.mjs';
338
32
 
339
33
  /**
340
34
  * Scaffold the legacy starter template (`aura init`).
@@ -358,7 +52,7 @@ export function scaffold(name, dest) {
358
52
  * @param {object} options - Scaffolding options.
359
53
  * @param {string} options.name - Project directory name (npm package defaults to @aurajs/<name>).
360
54
  * @param {string} options.dest - Absolute destination directory.
361
- * @param {string} [options.template='2d-shooter'] - Template key from listCreateTemplates().
55
+ * @param {string} [options.template='2d-adventure'] - Template key from listCreateTemplates().
362
56
  * @param {string} [options.version='0.1.0'] - Initial package version.
363
57
  * @param {string} [options.license='MIT'] - Initial package license.
364
58
  */
@@ -366,7 +60,7 @@ export function scaffoldGame(options) {
366
60
  const {
367
61
  name,
368
62
  dest,
369
- template = '2d-shooter',
63
+ template = '2d-adventure',
370
64
  version = '0.1.0',
371
65
  license = 'MIT',
372
66
  } = options;
@@ -391,9 +85,26 @@ export function scaffoldGame(options) {
391
85
  PROJECT_LICENSE: license,
392
86
  };
393
87
  const templateMetadata = resolveTemplateMetadata(normalizedTemplate);
88
+ if (templateMetadata?.runtimeFamily === 'retro') {
89
+ const retroResult = scaffoldRetroGame({
90
+ name,
91
+ dest,
92
+ version,
93
+ license,
94
+ binName,
95
+ normalizedTemplate,
96
+ templateMetadata,
97
+ });
98
+ return retroResult;
99
+ }
100
+ const baseTemplate = templateMetadata?.baseTemplate || null;
101
+ const baseTemplateDir = baseTemplate ? CREATE_TEMPLATE_DIRS[baseTemplate] : null;
394
102
 
103
+ if (baseTemplateDir && existsSync(baseTemplateDir)) {
104
+ copyTree(baseTemplateDir, dest, replacements);
105
+ }
395
106
  copyTree(templateDir, dest, replacements);
396
- if (normalizedTemplate !== 'blank' && existsSync(CREATE_SHARED_TEMPLATE_DIR)) {
107
+ if (shouldCopyCreateSharedTemplate(normalizedTemplate, templateMetadata) && existsSync(CREATE_SHARED_TEMPLATE_DIR)) {
397
108
  copyTree(CREATE_SHARED_TEMPLATE_DIR, dest, replacements);
398
109
  }
399
110
 
@@ -407,12 +118,14 @@ export function scaffoldGame(options) {
407
118
  version,
408
119
  license,
409
120
  binName,
121
+ template: normalizedTemplate,
410
122
  templateMetadata,
411
123
  });
412
124
 
413
125
  writeFileSync(join(dest, 'package.json'), JSON.stringify(pkg, null, 2) + '\n', 'utf8');
414
126
  writeFileSync(join(dest, '.gitignore'), GITIGNORE_TEMPLATE, 'utf8');
415
127
  writeFileSync(join(dest, 'bin', 'play.js'), PLAY_BIN_TEMPLATE, { encoding: 'utf8', mode: 0o755 });
128
+ applyTemplateConfigOverrides({ dest, templateMetadata });
416
129
  writeFileSync(
417
130
  join(dest, 'README.md'),
418
131
  renderProjectReadme({ name, projectTitle, template: normalizedTemplate, templateMetadata }),
@@ -436,6 +149,7 @@ export function scaffoldGame(options) {
436
149
  'utf8',
437
150
  );
438
151
  writeStarterAssetPack({ dest, projectTitle, template: normalizedTemplate, templateMetadata });
152
+ writeUnityLikeProjectLayout({ dest, projectTitle, template: normalizedTemplate, templateMetadata });
439
153
 
440
154
  const skillsSource = resolveSkillsSourceDir();
441
155
  if (skillsSource) {
@@ -447,282 +161,65 @@ export function scaffoldGame(options) {
447
161
  return {
448
162
  dest,
449
163
  template: normalizedTemplate,
164
+ runtimeFamily: templateMetadata?.runtimeFamily || 'default',
450
165
  files: listFiles(dest),
451
166
  };
452
167
  }
453
168
 
454
- function sanitizeBinName(name) {
455
- const normalized = String(name || '').trim();
456
- const compact = normalized
457
- .replace(/^@[^/]+\//, '')
458
- .replace(/\s+/g, '-')
459
- .replace(/[^a-zA-Z0-9._-]/g, '-')
460
- .replace(/-+/g, '-')
461
- .replace(/^[-._]+|[-._]+$/g, '')
462
- .toLowerCase();
463
-
464
- if (!compact) {
465
- throw new Error(`Unable to derive executable name from project name "${name}".`);
466
- }
467
-
468
- return compact;
469
- }
470
-
471
- function sanitizePackageSlug(name) {
472
- const normalized = String(name || '').trim();
473
- const compact = normalized
474
- .replace(/^@[^/]+\//, '')
475
- .replace(/\s+/g, '-')
476
- .replace(/[^a-zA-Z0-9._-]/g, '-')
477
- .replace(/-+/g, '-')
478
- .replace(/^[-._]+|[-._]+$/g, '')
479
- .toLowerCase();
480
-
481
- if (!compact) {
482
- throw new Error(`Unable to derive package slug from project name "${name}".`);
483
- }
484
-
485
- return compact;
486
- }
487
-
488
- function toDisplayTitle(name) {
489
- const cleaned = String(name || '').replace(/^@[^/]+\//, '');
490
- const words = cleaned.split(/[-_\s]+/).filter(Boolean);
491
- if (words.length === 0) return String(name || '').trim() || 'AuraJS Game';
492
- return words.map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
493
- }
494
-
495
- function resolveSkillsSourceDir() {
496
- if (existsSync(ROOT_SKILLS_DIR)) return ROOT_SKILLS_DIR;
497
- if (existsSync(PACKAGED_SKILLS_DIR)) return PACKAGED_SKILLS_DIR;
498
- return null;
499
- }
500
-
501
- function resolveTemplateMetadata(template) {
502
- return CREATE_TEMPLATE_METADATA[template] || CREATE_TEMPLATE_METADATA.blank;
503
- }
504
-
505
- function buildPackageJson({ name, version, license, binName, templateMetadata }) {
506
- const packageSlug = sanitizePackageSlug(name);
507
- const packageName = `@aurajs/${packageSlug}`;
508
- const keywords = ['aurajs', 'game', ...(templateMetadata?.keywords || [])];
169
+ function scaffoldRetroGame({
170
+ name,
171
+ dest,
172
+ version,
173
+ license,
174
+ binName,
175
+ normalizedTemplate,
176
+ templateMetadata,
177
+ }) {
178
+ initRetroTemplate({
179
+ destination: dest,
180
+ template: templateMetadata.retroTemplateId,
181
+ force: false,
182
+ });
509
183
 
510
- return {
511
- name: packageName,
184
+ const projectTitle = toDisplayTitle(name);
185
+ const pkg = buildPackageJson({
186
+ name,
512
187
  version,
513
- description: `${toDisplayTitle(name)} — built with AuraJS`,
514
- type: 'module',
515
- bin: {
516
- [binName]: './bin/play.js',
517
- },
518
- files: ['bin/', 'src/', 'assets/', 'skills/', 'aura.config.json', 'aura.capabilities.json', 'README.md', 'RUNBOOK.md'],
519
- scripts: {
520
- dev: 'aura dev',
521
- build: 'aura build',
522
- play: 'node ./bin/play.js',
523
- publish: 'npx auramaxx publish',
524
- },
525
- dependencies: {
526
- '@auraindustry/aurajs': '*',
527
- },
528
- keywords,
529
188
  license,
530
- };
531
- }
532
-
533
- function buildCapabilitiesDeclaration({ template, templateMetadata }) {
534
- return {
535
- schema: 'aurajs.create-capabilities.v1',
536
- template,
537
- summary: templateMetadata.summary,
538
- requiredApis: [...templateMetadata.requiredApis],
539
- optionalModules: {
540
- physics: false,
541
- network: true,
542
- multiplayer: false,
543
- steam: false,
544
- },
545
- notes: [
546
- 'Keep this file in sync with runtime API usage added in src/main.js.',
547
- 'Treat missing APIs as scaffold contract mismatches, not silent fallbacks.',
548
- ],
549
- };
550
- }
551
-
552
- function renderProjectReadme({ name, projectTitle, template, templateMetadata }) {
553
- const controls = templateMetadata.controls.map((line) => `- ${line}`).join('\n');
554
- const firstEdits = templateMetadata.firstEdits.map((line) => `1. ${line}`).join('\n');
555
-
556
- return `# ${projectTitle}
557
-
558
- Scaffolded with \`aura create ${name} --template ${template}\`.
559
-
560
- ## Quick Start
561
-
562
- \`\`\`bash
563
- npm install
564
- npm run dev
565
- \`\`\`
566
-
567
- Optional commands:
568
-
569
- \`\`\`bash
570
- npm run build
571
- npm run play
572
- npm run publish
573
- \`\`\`
574
-
575
- ## Template Summary
576
-
577
- ${templateMetadata.summary}
578
-
579
- ## Controls
580
-
581
- ${controls}
582
-
583
- ## Project Map
584
-
585
- - \`src/main.js\` - gameplay loop and rendering.
586
- - \`src/starter-utils/\` - reusable helpers copied for non-blank templates.
587
- - \`assets/starter/\` - starter asset pack and editable design payloads.
588
- - \`aura.config.json\` - identity/window/build/modules.
589
- - \`aura.capabilities.json\` - canonical runtime API declaration for this scaffold.
590
- - \`RUNBOOK.md\` - first-hour implementation and triage checklist.
591
-
592
- ## First Edits
593
-
594
- ${firstEdits}
595
- `;
596
- }
597
-
598
- function renderProjectRunbook({ projectTitle, template, templateMetadata }) {
599
- const firstEdits = templateMetadata.firstEdits.map((line) => `1. ${line}`).join('\n');
600
- const requiredApis = templateMetadata.requiredApis.map((entry) => `- \`${entry}\``).join('\n');
601
-
602
- return `# ${projectTitle} Runbook
603
-
604
- Template: \`${template}\`
605
-
606
- ## First 30 Minutes
607
-
608
- 1. Run \`npm install\` then \`npm run dev\` and confirm the starter loop is playable.
609
- 1. Read \`src/main.js\` once end-to-end before editing prompts or logic.
610
- 1. Review \`assets/starter/\` and replace placeholder payloads with game-specific values.
611
-
612
- ## First-Hour Implementation Pass
613
-
614
- ${firstEdits}
615
-
616
- ## Capability Contract
617
-
618
- The scaffold assumes the runtime APIs below:
619
-
620
- ${requiredApis}
621
-
622
- If any are unavailable at runtime, fail fast and capture the reason code before adding fallback behavior.
623
-
624
- ## Build + Share
625
-
626
- 1. \`npm run build\` to emit native/web artifacts.
627
- 1. \`npm run play\` to package + execute with sibling assets.
628
- 1. \`npm run publish\` once metadata and binaries are ready.
629
- `;
630
- }
631
-
632
- function writeStarterAssetPack({ dest, projectTitle, template, templateMetadata }) {
633
- const starterDir = join(dest, 'assets', 'starter');
634
- mkdirSync(starterDir, { recursive: true });
189
+ binName,
190
+ template: normalizedTemplate,
191
+ templateMetadata,
192
+ });
635
193
 
194
+ writeFileSync(join(dest, 'package.json'), JSON.stringify(pkg, null, 2) + '\n', 'utf8');
195
+ writeFileSync(join(dest, '.gitignore'), GITIGNORE_TEMPLATE, 'utf8');
636
196
  writeFileSync(
637
- join(starterDir, 'README.md'),
638
- `# ${projectTitle} Starter Assets
639
-
640
- Template: \`${template}\`
641
-
642
- Use this folder as the first source of truth for seed content:
643
-
644
- - Keep machine-readable balancing data in JSON files.
645
- - Store design intent in markdown notes so agents can edit safely.
646
- - Replace placeholders as soon as your core loop is stable.
647
- `,
197
+ join(dest, 'README.md'),
198
+ renderProjectReadme({ name, projectTitle, template: normalizedTemplate, templateMetadata }),
648
199
  'utf8',
649
200
  );
650
-
651
201
  writeFileSync(
652
- join(starterDir, 'dev-notes.md'),
653
- `# First Pass Notes
654
-
655
- - Core loop hypothesis:
656
- - Success metric for this week:
657
- - Next three gameplay experiments:
658
- `,
202
+ join(dest, 'RUNBOOK.md'),
203
+ renderProjectRunbook({ projectTitle, template: normalizedTemplate, templateMetadata }),
659
204
  'utf8',
660
205
  );
661
-
662
- const plan = templateMetadata.starterAssetPlan;
663
206
  writeFileSync(
664
- join(starterDir, plan.file),
207
+ join(dest, 'aura.capabilities.json'),
665
208
  JSON.stringify(
666
- {
667
- schema: 'aurajs.starter-asset-plan.v1',
668
- title: plan.title,
669
- template,
670
- steps: plan.steps,
671
- payload: plan.payload,
672
- },
209
+ buildCapabilitiesDeclaration({
210
+ template: normalizedTemplate,
211
+ templateMetadata,
212
+ }),
673
213
  null,
674
214
  2,
675
215
  ) + '\n',
676
216
  'utf8',
677
217
  );
678
- }
679
-
680
- function assertDestinationIsEmpty(name, dest) {
681
- if (existsSync(dest)) {
682
- const entries = readdirSync(dest);
683
- if (entries.length > 0) {
684
- throw new Error(`Directory "${name}" already exists and is not empty.`);
685
- }
686
- }
687
- }
688
218
 
689
- /**
690
- * Recursively copy a directory tree, applying placeholder replacements
691
- * to text files.
692
- */
693
- function copyTree(src, dest, replacements) {
694
- mkdirSync(dest, { recursive: true });
695
-
696
- for (const entry of readdirSync(src)) {
697
- const srcPath = join(src, entry);
698
- const destPath = join(dest, entry);
699
- const stat = statSync(srcPath);
700
-
701
- if (stat.isDirectory()) {
702
- copyTree(srcPath, destPath, replacements);
703
- } else {
704
- let content = readFileSync(srcPath, 'utf8');
705
- for (const [key, value] of Object.entries(replacements)) {
706
- content = content.replaceAll(`{{${key}}}`, value);
707
- }
708
- writeFileSync(destPath, content, 'utf8');
709
- }
710
- }
711
- }
712
-
713
- /**
714
- * List all files in a directory tree (relative paths).
715
- */
716
- function listFiles(dir, prefix = '') {
717
- const files = [];
718
- for (const entry of readdirSync(dir)) {
719
- const full = join(dir, entry);
720
- const rel = prefix ? `${prefix}/${entry}` : entry;
721
- if (statSync(full).isDirectory()) {
722
- files.push(...listFiles(full, rel));
723
- } else {
724
- files.push(rel);
725
- }
726
- }
727
- return files;
219
+ return {
220
+ dest,
221
+ template: normalizedTemplate,
222
+ runtimeFamily: 'retro',
223
+ files: listFiles(dest),
224
+ };
728
225
  }