@nice2dev/game-engine 1.3.14 → 1.3.16

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 (434) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cjs/accessibility/Accessibility.js +152 -165
  3. package/dist/cjs/ai/AI.js +292 -294
  4. package/dist/cjs/ai/BehaviorTree.js +1029 -1113
  5. package/dist/cjs/ai/StateMachine.js +694 -756
  6. package/dist/cjs/animation/Animation.js +232 -241
  7. package/dist/cjs/audio/AudioAdvanced.js +221 -236
  8. package/dist/cjs/audio/AudioBridge.js +441 -435
  9. package/dist/cjs/audio/AudioManager.js +242 -259
  10. package/dist/cjs/build-cloud/BuildOrchestration.js +1059 -1098
  11. package/dist/cjs/build-cloud/GodotBuildCloud.js +641 -670
  12. package/dist/cjs/build-cloud/UnityBuildCloud.js +563 -610
  13. package/dist/cjs/build-cloud/UnrealBuildCloud.js +610 -635
  14. package/dist/cjs/core/EventBus.js +51 -56
  15. package/dist/cjs/core/GameClock.js +62 -66
  16. package/dist/cjs/core/GameConfig.js +72 -79
  17. package/dist/cjs/core/GameLoop.js +80 -89
  18. package/dist/cjs/core/ServiceLocator.js +61 -65
  19. package/dist/cjs/core/Validation.js +72 -82
  20. package/dist/cjs/core/math.js +108 -112
  21. package/dist/cjs/devtools/DevTools.js +542 -563
  22. package/dist/cjs/devtools/DeveloperExperience.js +521 -559
  23. package/dist/cjs/devtools/GameplayAnalytics.js +636 -646
  24. package/dist/cjs/dialogue/DialogueSystem.js +984 -986
  25. package/dist/cjs/docs/DocGenerator.js +339 -364
  26. package/dist/cjs/ecs/World.js +355 -371
  27. package/dist/cjs/editor/AchievementEditor.js +580 -636
  28. package/dist/cjs/editor/AdvancedEditor.js +184 -191
  29. package/dist/cjs/editor/AnimationRetargeting.js +696 -741
  30. package/dist/cjs/editor/AssetBrowser.js +1072 -1160
  31. package/dist/cjs/editor/AssetManager.js +187 -192
  32. package/dist/cjs/editor/ConsolePro.js +971 -1061
  33. package/dist/cjs/editor/CraftingEditor.js +680 -730
  34. package/dist/cjs/editor/DebugTools.js +187 -185
  35. package/dist/cjs/editor/DialogueSystem.js +844 -901
  36. package/dist/cjs/editor/LeaderboardSystem.js +429 -483
  37. package/dist/cjs/editor/NiceGameEditor.js +1903 -1201
  38. package/dist/cjs/editor/PrefabSystem.js +772 -838
  39. package/dist/cjs/editor/ProfilerPanel.js +649 -700
  40. package/dist/cjs/editor/QuestEditor.js +792 -839
  41. package/dist/cjs/editor/ReplaySystem.js +585 -634
  42. package/dist/cjs/editor/SceneEditor.js +176 -200
  43. package/dist/cjs/editor/ScreenshotMode.js +621 -688
  44. package/dist/cjs/editor/ShaderGraph.js +1556 -1582
  45. package/dist/cjs/editor/TimelineEditor.js +715 -778
  46. package/dist/cjs/editor/UndoRedoPro.js +830 -904
  47. package/dist/cjs/editor/VRARMode.js +582 -645
  48. package/dist/cjs/engine/NiceGameEngine.js +141 -164
  49. package/dist/cjs/engine/SaveSystem.js +441 -495
  50. package/dist/cjs/enterprise/Enterprise.js +254 -261
  51. package/dist/cjs/export/BevyExporter.js +927 -967
  52. package/dist/cjs/export/CocosExporter.js +644 -673
  53. package/dist/cjs/export/Construct3Exporter.js +783 -794
  54. package/dist/cjs/export/DefoldExporter.js +1028 -1069
  55. package/dist/cjs/export/GDevelopExporter.js +674 -708
  56. package/dist/cjs/export/GameMakerExporter.js +791 -805
  57. package/dist/cjs/export/GodotExporter.js +1003 -1045
  58. package/dist/cjs/export/MinecraftBedrockExporter.js +573 -578
  59. package/dist/cjs/export/MonoGameExporter.js +1265 -1293
  60. package/dist/cjs/export/Pico8Exporter.js +766 -812
  61. package/dist/cjs/export/PlatformExporter.js +188 -206
  62. package/dist/cjs/export/RPGMakerExporter.js +860 -879
  63. package/dist/cjs/export/RobloxExporter.js +883 -919
  64. package/dist/cjs/export/Solar2DExporter.js +1218 -1256
  65. package/dist/cjs/export/ThreeJSExporter.js +1006 -1073
  66. package/dist/cjs/export/Tic80Exporter.js +1210 -1267
  67. package/dist/cjs/export/UnityExporter.js +1116 -1131
  68. package/dist/cjs/export/UnrealExporter.js +889 -919
  69. package/dist/cjs/export/WebExporter.js +931 -970
  70. package/dist/cjs/export/index.js +42 -65
  71. package/dist/cjs/godot-integration/GodotAssetLibrary.js +659 -692
  72. package/dist/cjs/godot-integration/GodotImport.js +929 -1027
  73. package/dist/cjs/godot-integration/GodotLiveLink.js +915 -945
  74. package/dist/cjs/godot-integration/components/GodotProjectBrowser.js +911 -611
  75. package/dist/cjs/i18n/I18n.js +860 -900
  76. package/dist/cjs/i18n/useTranslation.js +84 -89
  77. package/dist/cjs/import/AsepriteImporter.js +658 -716
  78. package/dist/cjs/import/DragonBonesImporter.js +437 -461
  79. package/dist/cjs/import/GameMakerImporter.js +511 -521
  80. package/dist/cjs/import/GodotSceneImporter.js +788 -822
  81. package/dist/cjs/import/LDtkImporter.js +436 -454
  82. package/dist/cjs/import/Live2DImporter.js +497 -518
  83. package/dist/cjs/import/NdgFormat.js +424 -457
  84. package/dist/cjs/import/OgmoImporter.js +466 -493
  85. package/dist/cjs/import/RPGMakerImporter.js +451 -477
  86. package/dist/cjs/import/SceneImporter.js +378 -423
  87. package/dist/cjs/import/SpineImporter.js +511 -546
  88. package/dist/cjs/import/SpriterImporter.js +590 -613
  89. package/dist/cjs/import/TiledMapImporter.js +811 -846
  90. package/dist/cjs/import/UnitySceneImporter.js +687 -703
  91. package/dist/cjs/import/index.js +206 -251
  92. package/dist/cjs/index.js +275 -278
  93. package/dist/cjs/input/GamepadNavigation.js +185 -205
  94. package/dist/cjs/input/InputManager.js +397 -421
  95. package/dist/cjs/input/useGamepads.js +70 -81
  96. package/dist/cjs/integration/IconSprite.js +129 -256
  97. package/dist/cjs/inventory/InventorySystem.js +920 -995
  98. package/dist/cjs/kids/KidMode.js +997 -1022
  99. package/dist/cjs/kids/KidTools.js +570 -594
  100. package/dist/cjs/monetization/Monetization.js +170 -177
  101. package/dist/cjs/multiplayer/LocalMultiplayer.js +287 -287
  102. package/dist/cjs/multiplayer/MiniGameTypes.js +49 -59
  103. package/dist/cjs/native-engine/AnimationSystem.js +731 -806
  104. package/dist/cjs/native-engine/AssetPipeline.js +454 -515
  105. package/dist/cjs/native-engine/AudioEngine.js +763 -804
  106. package/dist/cjs/native-engine/InputSystem.js +1075 -1145
  107. package/dist/cjs/native-engine/NetworkingSystem.js +733 -793
  108. package/dist/cjs/native-engine/PhysicsEngine.js +583 -607
  109. package/dist/cjs/native-engine/RenderingEngine.js +302 -350
  110. package/dist/cjs/native-engine/SceneGraph.js +769 -808
  111. package/dist/cjs/network/MultiplayerTransport.js +97 -132
  112. package/dist/cjs/network/Networking.js +549 -564
  113. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/AbortController.js +21 -29
  114. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/AccessTokenHttpClient.js +40 -48
  115. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/DefaultHttpClient.js +35 -43
  116. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/DefaultReconnectPolicy.js +10 -15
  117. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/Errors.js +103 -135
  118. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/FetchHttpClient.js +131 -158
  119. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HandshakeProtocol.js +39 -53
  120. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HeaderNames.js +5 -8
  121. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HttpClient.js +40 -48
  122. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HttpConnection.js +494 -572
  123. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HubConnection.js +826 -953
  124. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HubConnectionBuilder.js +125 -146
  125. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/IHubProtocol.js +13 -23
  126. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/ILogger.js +11 -25
  127. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/ITransport.js +13 -24
  128. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/JsonHubProtocol.js +108 -121
  129. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/Loggers.js +10 -14
  130. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/LongPollingTransport.js +150 -185
  131. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/MessageBuffer.js +158 -196
  132. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/ServerSentEventsTransport.js +90 -105
  133. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/Subject.js +30 -35
  134. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/TextMessageFormat.js +16 -21
  135. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/Utils.js +215 -248
  136. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/WebSocketTransport.js +135 -157
  137. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/XhrHttpClient.js +76 -85
  138. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/index.js +24 -27
  139. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/pkg-version.js +3 -4
  140. package/dist/cjs/pathfinding/Pathfinding.js +245 -263
  141. package/dist/cjs/performance/AssetStreaming.js +561 -635
  142. package/dist/cjs/performance/BenchmarkSuite.js +283 -311
  143. package/dist/cjs/performance/DeltaCompression.js +467 -526
  144. package/dist/cjs/performance/DeterministicPhysics.js +450 -498
  145. package/dist/cjs/performance/ECSOptimization.js +644 -695
  146. package/dist/cjs/performance/GameSaveSystem.js +509 -556
  147. package/dist/cjs/performance/HotReload.js +447 -500
  148. package/dist/cjs/performance/InputRecording.js +511 -561
  149. package/dist/cjs/performance/InterestManagement.js +453 -500
  150. package/dist/cjs/performance/LocalizationRuntime.js +376 -423
  151. package/dist/cjs/performance/MemoryManagement.js +410 -470
  152. package/dist/cjs/performance/ModSupport.js +445 -496
  153. package/dist/cjs/performance/MultiThreadedPhysics.js +400 -443
  154. package/dist/cjs/performance/NetworkPrediction.js +424 -482
  155. package/dist/cjs/performance/ObjectPooling.js +569 -617
  156. package/dist/cjs/performance/Performance.js +174 -190
  157. package/dist/cjs/performance/PerformanceAdvanced.js +614 -637
  158. package/dist/cjs/performance/WebGPURenderer.js +656 -683
  159. package/dist/cjs/physics/PhysicsAdvanced.js +345 -379
  160. package/dist/cjs/physics/PhysicsEngine2D.js +391 -427
  161. package/dist/cjs/plugins/PluginSDK.js +432 -466
  162. package/dist/cjs/plugins/PluginTestKit.js +307 -330
  163. package/dist/cjs/procedural/Procedural.js +243 -254
  164. package/dist/cjs/procedural/WorldBuilding.js +297 -314
  165. package/dist/cjs/quest/QuestSystem.js +975 -932
  166. package/dist/cjs/release/MobileExport.js +157 -163
  167. package/dist/cjs/release/Release.js +225 -238
  168. package/dist/cjs/rendering/Camera2D.js +121 -124
  169. package/dist/cjs/rendering/Renderer2D.js +321 -335
  170. package/dist/cjs/rendering/WebGPURenderPipeline.js +632 -651
  171. package/dist/cjs/runtime3d/Runtime3D.js +359 -378
  172. package/dist/cjs/runtime3d/SceneEditor3D.js +252 -263
  173. package/dist/cjs/scene/SceneManager.js +177 -193
  174. package/dist/cjs/scripting/GraphToAST.js +574 -547
  175. package/dist/cjs/scripting/LanguageExporter.js +254 -279
  176. package/dist/cjs/scripting/NodeGraph.js +546 -570
  177. package/dist/cjs/scripting/ScriptAST.js +31 -39
  178. package/dist/cjs/scripting/VisualScripting2.js +1016 -1065
  179. package/dist/cjs/scripting/exporters/CSharpExporter.js +464 -496
  180. package/dist/cjs/scripting/exporters/GDScriptExporter.js +390 -442
  181. package/dist/cjs/scripting/exporters/LuaExporter.js +406 -447
  182. package/dist/cjs/scripting/exporters/PythonExporter.js +484 -549
  183. package/dist/cjs/scripting/exporters/RustExporter.js +459 -512
  184. package/dist/cjs/scripting/exporters/TypeScriptExporter.js +505 -556
  185. package/dist/cjs/social/Social.js +72 -80
  186. package/dist/cjs/systems/LightingSystem.js +844 -931
  187. package/dist/cjs/systems/ParticleSystem2.js +1447 -1451
  188. package/dist/cjs/systems/PhysicsDebugSystem.js +1070 -1141
  189. package/dist/cjs/systems/TerrainSystem.js +985 -1098
  190. package/dist/cjs/templates/ActionTemplates.js +296 -309
  191. package/dist/cjs/templates/FightingTemplate.js +417 -463
  192. package/dist/cjs/templates/MetroidvaniaTemplate.js +353 -405
  193. package/dist/cjs/templates/PartyTemplates.js +190 -202
  194. package/dist/cjs/templates/PuzzleTemplates.js +245 -261
  195. package/dist/cjs/templates/RPGTemplates.js +160 -178
  196. package/dist/cjs/templates/SportsTemplates.js +237 -250
  197. package/dist/cjs/templates/StrategyTemplates.js +143 -153
  198. package/dist/cjs/templates/SurvivalTemplate.js +336 -380
  199. package/dist/cjs/templates/WaveDefense.js +499 -526
  200. package/dist/cjs/tilemap/Tilemap.js +207 -214
  201. package/dist/cjs/tutorials/TutorialBranching.js +396 -417
  202. package/dist/cjs/tutorials/TutorialEngine.js +888 -931
  203. package/dist/cjs/tutorials/TutorialOverlay.js +602 -640
  204. package/dist/cjs/tutorials/content/Tutorials_T05_T08.js +787 -809
  205. package/dist/cjs/tutorials/content/Tutorials_T09_T11.js +736 -756
  206. package/dist/cjs/tutorials/content/Tutorials_T12_T15.js +754 -778
  207. package/dist/cjs/ui/GameUI.js +295 -312
  208. package/dist/cjs/unity-integration/UnityAssetStore.js +700 -741
  209. package/dist/cjs/unity-integration/UnityImport.js +1066 -1176
  210. package/dist/cjs/unity-integration/UnityLiveLink.js +934 -981
  211. package/dist/cjs/unity-integration/components/UnityAssetStoreBrowser.js +1233 -757
  212. package/dist/cjs/unity-integration/components/UnityProjectBrowser.js +1240 -768
  213. package/dist/cjs/unreal-integration/UnrealImport.js +391 -412
  214. package/dist/cjs/unreal-integration/UnrealLiveLink.js +1102 -1137
  215. package/dist/cjs/unreal-integration/UnrealMarketplace.js +436 -473
  216. package/dist/cjs/unreal-integration/components/UnrealProjectBrowser.js +1150 -767
  217. package/dist/cjs/xr/ARVR.js +167 -175
  218. package/dist/esm/accessibility/Accessibility.js +160 -164
  219. package/dist/esm/ai/AI.js +310 -293
  220. package/dist/esm/ai/BehaviorTree.js +1057 -1112
  221. package/dist/esm/ai/StateMachine.js +709 -755
  222. package/dist/esm/animation/Animation.js +237 -240
  223. package/dist/esm/audio/AudioAdvanced.js +239 -235
  224. package/dist/esm/audio/AudioBridge.js +448 -434
  225. package/dist/esm/audio/AudioManager.js +243 -258
  226. package/dist/esm/build-cloud/BuildOrchestration.js +1071 -1097
  227. package/dist/esm/build-cloud/GodotBuildCloud.js +647 -669
  228. package/dist/esm/build-cloud/UnityBuildCloud.js +571 -609
  229. package/dist/esm/build-cloud/UnrealBuildCloud.js +615 -634
  230. package/dist/esm/core/EventBus.js +52 -55
  231. package/dist/esm/core/GameClock.js +63 -65
  232. package/dist/esm/core/GameConfig.js +77 -78
  233. package/dist/esm/core/GameLoop.js +81 -88
  234. package/dist/esm/core/ServiceLocator.js +63 -64
  235. package/dist/esm/core/Validation.js +82 -81
  236. package/dist/esm/core/math.js +109 -111
  237. package/dist/esm/devtools/DevTools.js +546 -562
  238. package/dist/esm/devtools/DeveloperExperience.js +535 -558
  239. package/dist/esm/devtools/GameplayAnalytics.js +647 -645
  240. package/dist/esm/dialogue/DialogueSystem.js +998 -985
  241. package/dist/esm/docs/DocGenerator.js +342 -363
  242. package/dist/esm/ecs/World.js +358 -370
  243. package/dist/esm/editor/AchievementEditor.js +584 -635
  244. package/dist/esm/editor/AdvancedEditor.js +191 -190
  245. package/dist/esm/editor/AnimationRetargeting.js +700 -740
  246. package/dist/esm/editor/AssetBrowser.js +1078 -1159
  247. package/dist/esm/editor/AssetManager.js +188 -191
  248. package/dist/esm/editor/ConsolePro.js +977 -1060
  249. package/dist/esm/editor/CraftingEditor.js +684 -729
  250. package/dist/esm/editor/DebugTools.js +194 -184
  251. package/dist/esm/editor/DialogueSystem.js +849 -900
  252. package/dist/esm/editor/LeaderboardSystem.js +433 -482
  253. package/dist/esm/editor/NiceGameEditor.js +1908 -1200
  254. package/dist/esm/editor/PrefabSystem.js +777 -837
  255. package/dist/esm/editor/ProfilerPanel.js +654 -699
  256. package/dist/esm/editor/QuestEditor.js +795 -838
  257. package/dist/esm/editor/ReplaySystem.js +591 -633
  258. package/dist/esm/editor/SceneEditor.js +189 -199
  259. package/dist/esm/editor/ScreenshotMode.js +628 -687
  260. package/dist/esm/editor/ShaderGraph.js +1565 -1581
  261. package/dist/esm/editor/TimelineEditor.js +733 -777
  262. package/dist/esm/editor/UndoRedoPro.js +835 -903
  263. package/dist/esm/editor/VRARMode.js +586 -644
  264. package/dist/esm/engine/NiceGameEngine.js +142 -163
  265. package/dist/esm/engine/SaveSystem.js +447 -494
  266. package/dist/esm/enterprise/Enterprise.js +265 -260
  267. package/dist/esm/export/BevyExporter.js +929 -966
  268. package/dist/esm/export/CocosExporter.js +646 -672
  269. package/dist/esm/export/Construct3Exporter.js +785 -793
  270. package/dist/esm/export/DefoldExporter.js +1030 -1068
  271. package/dist/esm/export/GDevelopExporter.js +676 -707
  272. package/dist/esm/export/GameMakerExporter.js +793 -804
  273. package/dist/esm/export/GodotExporter.js +1004 -1044
  274. package/dist/esm/export/MinecraftBedrockExporter.js +575 -577
  275. package/dist/esm/export/MonoGameExporter.js +1267 -1292
  276. package/dist/esm/export/Pico8Exporter.js +768 -811
  277. package/dist/esm/export/PlatformExporter.js +193 -205
  278. package/dist/esm/export/RPGMakerExporter.js +862 -878
  279. package/dist/esm/export/RobloxExporter.js +885 -918
  280. package/dist/esm/export/Solar2DExporter.js +1220 -1255
  281. package/dist/esm/export/ThreeJSExporter.js +1007 -1072
  282. package/dist/esm/export/Tic80Exporter.js +1212 -1266
  283. package/dist/esm/export/UnityExporter.js +1117 -1130
  284. package/dist/esm/export/UnrealExporter.js +891 -918
  285. package/dist/esm/export/WebExporter.js +933 -969
  286. package/dist/esm/export/index.js +86 -71
  287. package/dist/esm/godot-integration/GodotAssetLibrary.js +663 -691
  288. package/dist/esm/godot-integration/GodotImport.js +935 -1026
  289. package/dist/esm/godot-integration/GodotLiveLink.js +918 -944
  290. package/dist/esm/godot-integration/components/GodotProjectBrowser.js +912 -610
  291. package/dist/esm/i18n/I18n.js +871 -899
  292. package/dist/esm/i18n/useTranslation.js +88 -88
  293. package/dist/esm/import/AsepriteImporter.js +637 -715
  294. package/dist/esm/import/DragonBonesImporter.js +417 -460
  295. package/dist/esm/import/GameMakerImporter.js +491 -520
  296. package/dist/esm/import/GodotSceneImporter.js +767 -821
  297. package/dist/esm/import/LDtkImporter.js +415 -453
  298. package/dist/esm/import/Live2DImporter.js +477 -517
  299. package/dist/esm/import/NdgFormat.js +410 -456
  300. package/dist/esm/import/OgmoImporter.js +446 -492
  301. package/dist/esm/import/RPGMakerImporter.js +431 -476
  302. package/dist/esm/import/SceneImporter.js +385 -422
  303. package/dist/esm/import/SpineImporter.js +491 -545
  304. package/dist/esm/import/SpriterImporter.js +570 -612
  305. package/dist/esm/import/TiledMapImporter.js +790 -845
  306. package/dist/esm/import/UnitySceneImporter.js +666 -702
  307. package/dist/esm/import/index.js +247 -258
  308. package/dist/esm/index.js +1332 -188
  309. package/dist/esm/input/GamepadNavigation.js +187 -204
  310. package/dist/esm/input/InputManager.js +401 -420
  311. package/dist/esm/input/useGamepads.js +72 -80
  312. package/dist/esm/integration/IconSprite.js +143 -255
  313. package/dist/esm/inventory/InventorySystem.js +925 -994
  314. package/dist/esm/kids/KidMode.js +1003 -1021
  315. package/dist/esm/kids/KidTools.js +573 -593
  316. package/dist/esm/monetization/Monetization.js +180 -176
  317. package/dist/esm/multiplayer/LocalMultiplayer.js +290 -286
  318. package/dist/esm/multiplayer/MiniGameTypes.js +58 -58
  319. package/dist/esm/native-engine/AnimationSystem.js +735 -805
  320. package/dist/esm/native-engine/AssetPipeline.js +456 -514
  321. package/dist/esm/native-engine/AudioEngine.js +765 -803
  322. package/dist/esm/native-engine/InputSystem.js +1079 -1144
  323. package/dist/esm/native-engine/NetworkingSystem.js +740 -792
  324. package/dist/esm/native-engine/PhysicsEngine.js +585 -606
  325. package/dist/esm/native-engine/RenderingEngine.js +304 -349
  326. package/dist/esm/native-engine/SceneGraph.js +773 -807
  327. package/dist/esm/network/MultiplayerTransport.js +99 -131
  328. package/dist/esm/network/Networking.js +556 -563
  329. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/AbortController.js +22 -28
  330. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/AccessTokenHttpClient.js +41 -47
  331. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/DefaultHttpClient.js +36 -42
  332. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/DefaultReconnectPolicy.js +11 -14
  333. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/Errors.js +111 -134
  334. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/FetchHttpClient.js +132 -157
  335. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HandshakeProtocol.js +40 -52
  336. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HeaderNames.js +6 -7
  337. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HttpClient.js +42 -47
  338. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HttpConnection.js +496 -571
  339. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HubConnection.js +828 -952
  340. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HubConnectionBuilder.js +126 -145
  341. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/IHubProtocol.js +14 -23
  342. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/ILogger.js +12 -25
  343. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/ITransport.js +15 -24
  344. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/JsonHubProtocol.js +109 -120
  345. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/Loggers.js +11 -13
  346. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/LongPollingTransport.js +151 -184
  347. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/MessageBuffer.js +159 -195
  348. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/ServerSentEventsTransport.js +91 -104
  349. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/Subject.js +31 -34
  350. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/TextMessageFormat.js +17 -20
  351. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/Utils.js +230 -248
  352. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/WebSocketTransport.js +136 -156
  353. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/XhrHttpClient.js +77 -84
  354. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/index.js +31 -12
  355. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/pkg-version.js +4 -3
  356. package/dist/esm/pathfinding/Pathfinding.js +249 -262
  357. package/dist/esm/performance/AssetStreaming.js +567 -634
  358. package/dist/esm/performance/BenchmarkSuite.js +285 -310
  359. package/dist/esm/performance/DeltaCompression.js +478 -525
  360. package/dist/esm/performance/DeterministicPhysics.js +479 -497
  361. package/dist/esm/performance/ECSOptimization.js +653 -694
  362. package/dist/esm/performance/GameSaveSystem.js +515 -555
  363. package/dist/esm/performance/HotReload.js +454 -499
  364. package/dist/esm/performance/InputRecording.js +520 -560
  365. package/dist/esm/performance/InterestManagement.js +460 -499
  366. package/dist/esm/performance/LocalizationRuntime.js +382 -422
  367. package/dist/esm/performance/MemoryManagement.js +415 -469
  368. package/dist/esm/performance/ModSupport.js +455 -495
  369. package/dist/esm/performance/MultiThreadedPhysics.js +408 -442
  370. package/dist/esm/performance/NetworkPrediction.js +436 -481
  371. package/dist/esm/performance/ObjectPooling.js +582 -616
  372. package/dist/esm/performance/Performance.js +182 -189
  373. package/dist/esm/performance/PerformanceAdvanced.js +621 -636
  374. package/dist/esm/performance/WebGPURenderer.js +660 -682
  375. package/dist/esm/physics/PhysicsAdvanced.js +359 -378
  376. package/dist/esm/physics/PhysicsEngine2D.js +393 -426
  377. package/dist/esm/plugins/PluginSDK.js +435 -465
  378. package/dist/esm/plugins/PluginTestKit.js +315 -329
  379. package/dist/esm/procedural/Procedural.js +248 -253
  380. package/dist/esm/procedural/WorldBuilding.js +316 -313
  381. package/dist/esm/quest/QuestSystem.js +982 -931
  382. package/dist/esm/release/MobileExport.js +163 -162
  383. package/dist/esm/release/Release.js +234 -237
  384. package/dist/esm/rendering/Camera2D.js +122 -123
  385. package/dist/esm/rendering/Renderer2D.js +323 -334
  386. package/dist/esm/rendering/WebGPURenderPipeline.js +647 -650
  387. package/dist/esm/runtime3d/Runtime3D.js +368 -377
  388. package/dist/esm/runtime3d/SceneEditor3D.js +268 -262
  389. package/dist/esm/scene/SceneManager.js +178 -192
  390. package/dist/esm/scripting/GraphToAST.js +576 -546
  391. package/dist/esm/scripting/LanguageExporter.js +263 -278
  392. package/dist/esm/scripting/NodeGraph.js +550 -569
  393. package/dist/esm/scripting/ScriptAST.js +45 -38
  394. package/dist/esm/scripting/VisualScripting2.js +1025 -1064
  395. package/dist/esm/scripting/exporters/CSharpExporter.js +465 -495
  396. package/dist/esm/scripting/exporters/GDScriptExporter.js +391 -441
  397. package/dist/esm/scripting/exporters/LuaExporter.js +407 -446
  398. package/dist/esm/scripting/exporters/PythonExporter.js +485 -548
  399. package/dist/esm/scripting/exporters/RustExporter.js +460 -511
  400. package/dist/esm/scripting/exporters/TypeScriptExporter.js +506 -555
  401. package/dist/esm/social/Social.js +77 -79
  402. package/dist/esm/systems/LightingSystem.js +855 -930
  403. package/dist/esm/systems/ParticleSystem2.js +1453 -1450
  404. package/dist/esm/systems/PhysicsDebugSystem.js +1078 -1140
  405. package/dist/esm/systems/TerrainSystem.js +996 -1097
  406. package/dist/esm/templates/ActionTemplates.js +307 -308
  407. package/dist/esm/templates/FightingTemplate.js +439 -462
  408. package/dist/esm/templates/MetroidvaniaTemplate.js +391 -404
  409. package/dist/esm/templates/PartyTemplates.js +206 -201
  410. package/dist/esm/templates/PuzzleTemplates.js +260 -260
  411. package/dist/esm/templates/RPGTemplates.js +172 -177
  412. package/dist/esm/templates/SportsTemplates.js +251 -249
  413. package/dist/esm/templates/StrategyTemplates.js +158 -152
  414. package/dist/esm/templates/SurvivalTemplate.js +367 -379
  415. package/dist/esm/templates/WaveDefense.js +501 -525
  416. package/dist/esm/tilemap/Tilemap.js +209 -213
  417. package/dist/esm/tutorials/TutorialBranching.js +399 -416
  418. package/dist/esm/tutorials/TutorialEngine.js +893 -930
  419. package/dist/esm/tutorials/TutorialOverlay.js +603 -639
  420. package/dist/esm/tutorials/content/Tutorials_T05_T08.js +792 -808
  421. package/dist/esm/tutorials/content/Tutorials_T09_T11.js +740 -755
  422. package/dist/esm/tutorials/content/Tutorials_T12_T15.js +759 -777
  423. package/dist/esm/ui/GameUI.js +296 -311
  424. package/dist/esm/unity-integration/UnityAssetStore.js +704 -740
  425. package/dist/esm/unity-integration/UnityImport.js +1071 -1175
  426. package/dist/esm/unity-integration/UnityLiveLink.js +938 -980
  427. package/dist/esm/unity-integration/components/UnityAssetStoreBrowser.js +1234 -756
  428. package/dist/esm/unity-integration/components/UnityProjectBrowser.js +1241 -767
  429. package/dist/esm/unreal-integration/UnrealImport.js +395 -411
  430. package/dist/esm/unreal-integration/UnrealLiveLink.js +1105 -1136
  431. package/dist/esm/unreal-integration/UnrealMarketplace.js +442 -472
  432. package/dist/esm/unreal-integration/components/UnrealProjectBrowser.js +1151 -766
  433. package/dist/esm/xr/ARVR.js +181 -174
  434. package/package.json +7 -12
@@ -1,845 +1,799 @@
1
- 'use strict';
2
-
3
- var PlatformExporter = require('./PlatformExporter.js');
4
-
5
- /* ────────────────────────────────────────────────────────────────
6
- PICO-8 Exporter — Fantasy Console Export
7
-
8
- Exports Nice2Dev projects to PICO-8 format:
9
- - P8 cartridge file format
10
- - Lua code section
11
- - Graphics data (sprites, map)
12
- - Sound effects
13
- - Music patterns
14
-
15
- Constraints:
16
- - 128x128 pixels
17
- - 16 colors palette
18
- - 8192 tokens max
19
- - 32KB cartridge size
20
- ──────────────────────────────────────────────────────────────── */
21
- /* ── PICO-8 Constants ─────────────────────────────────────────── */
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const PlatformExporter = require("./PlatformExporter.js");
22
4
  const PICO8_PALETTE = [
23
- '#000000', // 0 - black
24
- '#1D2B53', // 1 - dark blue
25
- '#7E2553', // 2 - dark purple
26
- '#008751', // 3 - dark green
27
- '#AB5236', // 4 - brown
28
- '#5F574F', // 5 - dark gray
29
- '#C2C3C7', // 6 - light gray
30
- '#FFF1E8', // 7 - white
31
- '#FF004D', // 8 - red
32
- '#FFA300', // 9 - orange
33
- '#FFEC27', // 10 - yellow
34
- '#00E436', // 11 - green
35
- '#29ADFF', // 12 - blue
36
- '#83769C', // 13 - indigo
37
- '#FF77A8', // 14 - pink
38
- '#FFCCAA', // 15 - peach
5
+ "#000000",
6
+ // 0 - black
7
+ "#1D2B53",
8
+ // 1 - dark blue
9
+ "#7E2553",
10
+ // 2 - dark purple
11
+ "#008751",
12
+ // 3 - dark green
13
+ "#AB5236",
14
+ // 4 - brown
15
+ "#5F574F",
16
+ // 5 - dark gray
17
+ "#C2C3C7",
18
+ // 6 - light gray
19
+ "#FFF1E8",
20
+ // 7 - white
21
+ "#FF004D",
22
+ // 8 - red
23
+ "#FFA300",
24
+ // 9 - orange
25
+ "#FFEC27",
26
+ // 10 - yellow
27
+ "#00E436",
28
+ // 11 - green
29
+ "#29ADFF",
30
+ // 12 - blue
31
+ "#83769C",
32
+ // 13 - indigo
33
+ "#FF77A8",
34
+ // 14 - pink
35
+ "#FFCCAA"
36
+ // 15 - peach
39
37
  ];
40
- /* ── Exporter Implementation ──────────────────────────────────── */
41
38
  class Pico8Exporter extends PlatformExporter.PlatformExporter {
42
- constructor() {
43
- super(...arguments);
44
- this.platformId = 'pico8';
45
- this.platformInfo = {
46
- id: 'pico8',
47
- name: 'PICO-8',
48
- description: 'PICO-8 Fantasy Console - Retro game development platform',
49
- website: 'https://www.lexaloffle.com/pico-8.php',
50
- features: ['2d-rendering', 'pixel-graphics', 'audio', 'music', 'retro'],
51
- supportedAssets: ['sprite', 'tilemap', 'audio', 'music'],
52
- exportFormats: ['.p8'],
53
- };
54
- }
55
- async doExport(project, options) {
56
- options.platformOptions ?? {};
57
- // Generate main P8 cartridge
58
- await this.generateCartridge(project, options);
59
- // Generate standalone Lua for reference
60
- await this.generateLuaSource(project, options);
61
- // Generate README
62
- await this.generateReadme(project, options);
39
+ constructor() {
40
+ super(...arguments);
41
+ this.platformId = "pico8";
42
+ this.platformInfo = {
43
+ id: "pico8",
44
+ name: "PICO-8",
45
+ description: "PICO-8 Fantasy Console - Retro game development platform",
46
+ website: "https://www.lexaloffle.com/pico-8.php",
47
+ features: ["2d-rendering", "pixel-graphics", "audio", "music", "retro"],
48
+ supportedAssets: ["sprite", "tilemap", "audio", "music"],
49
+ exportFormats: [".p8"]
50
+ };
51
+ }
52
+ async doExport(project, options) {
53
+ options.platformOptions ?? {};
54
+ await this.generateCartridge(project, options);
55
+ await this.generateLuaSource(project, options);
56
+ await this.generateReadme(project, options);
57
+ }
58
+ /* ── Cartridge Generation ───────────────────────────────────── */
59
+ async generateCartridge(project, options) {
60
+ options.platformOptions ?? {};
61
+ const safeName = (options.projectName ?? project.name).toLowerCase().replace(/[^a-z0-9_]/g, "_");
62
+ const code = this.generateCode(project, options);
63
+ const gfx = this.generateGfxSection(project, options);
64
+ const gff = this.generateGffSection(project);
65
+ const map = this.generateMapSection(project);
66
+ const sfx = this.generateSfxSection(project, options);
67
+ const music = this.generateMusicSection(project, options);
68
+ const cartridge = `pico-8 cartridge // http://www.pico-8.com
69
+ version 41
70
+ __lua__
71
+ ${code}
72
+ __gfx__
73
+ ${gfx}
74
+ __gff__
75
+ ${gff}
76
+ __map__
77
+ ${map}
78
+ __sfx__
79
+ ${sfx}
80
+ __music__
81
+ ${music}
82
+ `;
83
+ this.addTextFile(`${safeName}.p8`, cartridge);
84
+ }
85
+ /* ── Code Generation ────────────────────────────────────────── */
86
+ generateCode(project, options) {
87
+ const platformOpts = options.platformOptions ?? {};
88
+ const optimizeTokens = platformOpts.optimizeTokens ?? false;
89
+ const lines = [];
90
+ lines.push(`-- ${project.name} v${project.version}`);
91
+ lines.push("-- generated from nice2dev");
92
+ lines.push("");
93
+ lines.push("-- game state");
94
+ lines.push("game={");
95
+ lines.push(' state="play",');
96
+ lines.push(" frame=0,");
97
+ lines.push(" cam={x=0,y=0},");
98
+ lines.push(" entities={},");
99
+ lines.push(" debug=" + (platformOpts.includeDebug ? "true" : "false"));
100
+ lines.push("}");
101
+ lines.push("");
102
+ lines.push(this.generateCoreFunctions(project, options));
103
+ lines.push(this.generateEntitySystem(project, options));
104
+ lines.push(this.generateEntityDefinitions(project, options));
105
+ lines.push(this.generateSceneSetup(project, options));
106
+ lines.push(this.generateUtilityFunctions(optimizeTokens));
107
+ if (platformOpts.includeDebug) {
108
+ lines.push(this.generateDebugOverlay());
63
109
  }
64
- /* ── Cartridge Generation ───────────────────────────────────── */
65
- async generateCartridge(project, options) {
66
- options.platformOptions ?? {};
67
- const safeName = (options.projectName ?? project.name)
68
- .toLowerCase()
69
- .replace(/[^a-z0-9_]/g, '_');
70
- // Generate code section
71
- const code = this.generateCode(project, options);
72
- // Generate graphics section (placeholder)
73
- const gfx = this.generateGfxSection(project, options);
74
- // Generate gff (sprite flags) section
75
- const gff = this.generateGffSection(project);
76
- // Generate map section
77
- const map = this.generateMapSection(project);
78
- // Generate sfx section
79
- const sfx = this.generateSfxSection(project, options);
80
- // Generate music section
81
- const music = this.generateMusicSection(project, options);
82
- // Assemble cartridge
83
- const cartridge = `pico-8 cartridge // http://www.pico-8.com
84
- version 41
85
- __lua__
86
- ${code}
87
- __gfx__
88
- ${gfx}
89
- __gff__
90
- ${gff}
91
- __map__
92
- ${map}
93
- __sfx__
94
- ${sfx}
95
- __music__
96
- ${music}
110
+ return lines.join("\n");
111
+ }
112
+ generateCoreFunctions(project, _options) {
113
+ return `
114
+ -- initialization
115
+ function _init()
116
+ -- setup palette
117
+ palt(0,false)
118
+ palt(14,true) -- pink as transparent
119
+
120
+ -- initialize game
121
+ game.frame=0
122
+ game.entities={}
123
+
124
+ -- load first scene
125
+ load_scene(1)
126
+ end
127
+
128
+ -- update (60fps)
129
+ function _update60()
130
+ if game.state=="play" then
131
+ game.frame+=1
132
+
133
+ -- update all entities
134
+ for e in all(game.entities) do
135
+ if e.update then
136
+ e:update()
137
+ end
138
+ end
139
+
140
+ -- handle collisions
141
+ check_collisions()
142
+
143
+ -- clean dead entities
144
+ for i=#game.entities,1,-1 do
145
+ if game.entities[i].dead then
146
+ del(game.entities,game.entities[i])
147
+ end
148
+ end
149
+ end
150
+ end
151
+
152
+ -- draw
153
+ function _draw()
154
+ cls(${this.getClosestPico8Color(project.scenes[0]?.background ?? "#000000")})
155
+
156
+ -- apply camera
157
+ camera(game.cam.x,game.cam.y)
158
+
159
+ -- draw map
160
+ map(0,0,0,0,128,64)
161
+
162
+ -- draw entities (sorted by y)
163
+ sort_entities()
164
+ for e in all(game.entities) do
165
+ if e.draw then
166
+ e:draw()
167
+ end
168
+ end
169
+
170
+ camera()
171
+
172
+ -- ui
173
+ draw_ui()
174
+
175
+ -- debug
176
+ if game.debug then
177
+ draw_debug()
178
+ end
179
+ end
97
180
  `;
98
- this.addTextFile(`${safeName}.p8`, cartridge);
181
+ }
182
+ generateEntitySystem(_project, _options) {
183
+ return `
184
+ -- entity system
185
+ function make_entity(type,x,y,props)
186
+ local e={
187
+ type=type,
188
+ x=x,
189
+ y=y,
190
+ dx=0,
191
+ dy=0,
192
+ w=8,
193
+ h=8,
194
+ spr=0,
195
+ flip_x=false,
196
+ anim={frames={0},speed=0.1,t=0,i=1},
197
+ dead=false,
198
+ tags={}
199
+ }
200
+ -- apply props
201
+ if props then
202
+ for k,v in pairs(props) do
203
+ e[k]=v
204
+ end
205
+ end
206
+ -- type-specific init
207
+ if entity_types[type] then
208
+ for k,v in pairs(entity_types[type]) do
209
+ if type(v)!="function" then
210
+ e[k]=v
211
+ else
212
+ e[k]=v
213
+ end
214
+ end
215
+ if entity_types[type].init then
216
+ entity_types[type].init(e)
217
+ end
218
+ end
219
+ add(game.entities,e)
220
+ return e
221
+ end
222
+
223
+ function kill_entity(e)
224
+ e.dead=true
225
+ end
226
+
227
+ function has_tag(e,tag)
228
+ for t in all(e.tags) do
229
+ if t==tag then return true end
230
+ end
231
+ return false
232
+ end
233
+
234
+ -- collision
235
+ function check_collisions()
236
+ for i=1,#game.entities do
237
+ local a=game.entities[i]
238
+ if not a.dead and a.solid then
239
+ for j=i+1,#game.entities do
240
+ local b=game.entities[j]
241
+ if not b.dead and b.solid then
242
+ if collides(a,b) then
243
+ if a.on_collision then a:on_collision(b) end
244
+ if b.on_collision then b:on_collision(a) end
245
+ end
246
+ end
247
+ end
248
+ end
249
+ end
250
+ end
251
+
252
+ function collides(a,b)
253
+ return a.x<b.x+b.w and
254
+ a.x+a.w>b.x and
255
+ a.y<b.y+b.h and
256
+ a.y+a.h>b.y
257
+ end
258
+ `;
259
+ }
260
+ generateEntityDefinitions(project, _options) {
261
+ const lines = [];
262
+ lines.push("");
263
+ lines.push("-- entity types");
264
+ lines.push("entity_types={}");
265
+ lines.push("");
266
+ const entityTypes = /* @__PURE__ */ new Map();
267
+ for (const prefab of project.prefabs) {
268
+ entityTypes.set(prefab.name.toLowerCase().replace(/[^a-z0-9_]/g, "_"), prefab.entity);
99
269
  }
100
- /* ── Code Generation ────────────────────────────────────────── */
101
- generateCode(project, options) {
102
- const platformOpts = options.platformOptions ?? {};
103
- const optimizeTokens = platformOpts.optimizeTokens ?? false;
104
- const lines = [];
105
- // Header comment
106
- lines.push(`-- ${project.name} v${project.version}`);
107
- lines.push('-- generated from nice2dev');
108
- lines.push('');
109
- // Game state
110
- lines.push('-- game state');
111
- lines.push('game={');
112
- lines.push(' state="play",');
113
- lines.push(' frame=0,');
114
- lines.push(' cam={x=0,y=0},');
115
- lines.push(' entities={},');
116
- lines.push(' debug=' + (platformOpts.includeDebug ? 'true' : 'false'));
117
- lines.push('}');
118
- lines.push('');
119
- // Core functions
120
- lines.push(this.generateCoreFunctions(project, options));
121
- // Entity system
122
- lines.push(this.generateEntitySystem(project, options));
123
- // Entity definitions
124
- lines.push(this.generateEntityDefinitions(project, options));
125
- // Scene setup
126
- lines.push(this.generateSceneSetup(project, options));
127
- // Utility functions
128
- lines.push(this.generateUtilityFunctions(optimizeTokens));
129
- // Debug overlay
130
- if (platformOpts.includeDebug) {
131
- lines.push(this.generateDebugOverlay());
270
+ for (const scene of project.scenes) {
271
+ for (const entity of scene.entities) {
272
+ const typeName = (entity.name ?? entity.id).toLowerCase().replace(/[^a-z0-9_]/g, "_");
273
+ if (!entityTypes.has(typeName)) {
274
+ entityTypes.set(typeName, entity);
132
275
  }
133
- return lines.join('\n');
276
+ }
134
277
  }
135
- generateCoreFunctions(project, _options) {
136
- return `
137
- -- initialization
138
- function _init()
139
- -- setup palette
140
- palt(0,false)
141
- palt(14,true) -- pink as transparent
142
-
143
- -- initialize game
144
- game.frame=0
145
- game.entities={}
146
-
147
- -- load first scene
148
- load_scene(1)
149
- end
150
-
151
- -- update (60fps)
152
- function _update60()
153
- if game.state=="play" then
154
- game.frame+=1
155
-
156
- -- update all entities
157
- for e in all(game.entities) do
158
- if e.update then
159
- e:update()
160
- end
161
- end
162
-
163
- -- handle collisions
164
- check_collisions()
165
-
166
- -- clean dead entities
167
- for i=#game.entities,1,-1 do
168
- if game.entities[i].dead then
169
- del(game.entities,game.entities[i])
170
- end
171
- end
172
- end
173
- end
174
-
175
- -- draw
176
- function _draw()
177
- cls(${this.getClosestPico8Color(project.scenes[0]?.background ?? '#000000')})
178
-
179
- -- apply camera
180
- camera(game.cam.x,game.cam.y)
181
-
182
- -- draw map
183
- map(0,0,0,0,128,64)
184
-
185
- -- draw entities (sorted by y)
186
- sort_entities()
187
- for e in all(game.entities) do
188
- if e.draw then
189
- e:draw()
190
- end
191
- end
192
-
193
- camera()
194
-
195
- -- ui
196
- draw_ui()
197
-
198
- -- debug
199
- if game.debug then
200
- draw_debug()
201
- end
202
- end
203
- `;
278
+ for (const [typeName, entity] of entityTypes) {
279
+ lines.push(this.entityTypeToLua(typeName, entity));
204
280
  }
205
- generateEntitySystem(_project, _options) {
206
- return `
207
- -- entity system
208
- function make_entity(type,x,y,props)
209
- local e={
210
- type=type,
211
- x=x,
212
- y=y,
213
- dx=0,
214
- dy=0,
215
- w=8,
216
- h=8,
217
- spr=0,
218
- flip_x=false,
219
- anim={frames={0},speed=0.1,t=0,i=1},
220
- dead=false,
221
- tags={}
222
- }
223
- -- apply props
224
- if props then
225
- for k,v in pairs(props) do
226
- e[k]=v
227
- end
228
- end
229
- -- type-specific init
230
- if entity_types[type] then
231
- for k,v in pairs(entity_types[type]) do
232
- if type(v)!="function" then
233
- e[k]=v
234
- else
235
- e[k]=v
236
- end
237
- end
238
- if entity_types[type].init then
239
- entity_types[type].init(e)
240
- end
241
- end
242
- add(game.entities,e)
243
- return e
244
- end
245
-
246
- function kill_entity(e)
247
- e.dead=true
248
- end
249
-
250
- function has_tag(e,tag)
251
- for t in all(e.tags) do
252
- if t==tag then return true end
253
- end
254
- return false
255
- end
256
-
257
- -- collision
258
- function check_collisions()
259
- for i=1,#game.entities do
260
- local a=game.entities[i]
261
- if not a.dead and a.solid then
262
- for j=i+1,#game.entities do
263
- local b=game.entities[j]
264
- if not b.dead and b.solid then
265
- if collides(a,b) then
266
- if a.on_collision then a:on_collision(b) end
267
- if b.on_collision then b:on_collision(a) end
268
- end
269
- end
270
- end
271
- end
272
- end
273
- end
274
-
275
- function collides(a,b)
276
- return a.x<b.x+b.w and
277
- a.x+a.w>b.x and
278
- a.y<b.y+b.h and
279
- a.y+a.h>b.y
280
- end
281
+ return lines.join("\n");
282
+ }
283
+ entityTypeToLua(typeName, entity) {
284
+ const tags = entity.tags ?? [];
285
+ entity.components.some((c) => c.type === "sprite");
286
+ const hasPhysics = entity.components.some((c) => c.type === "rigidbody");
287
+ entity.components.some((c) => c.type === "script");
288
+ const sprIndex = this.getEntitySpriteIndex(entity);
289
+ const speed = this.getComponentProperty(entity, "movement", "speed", 1);
290
+ return `entity_types.${typeName}={
291
+ spr=${sprIndex},
292
+ w=8,h=8,
293
+ solid=${hasPhysics},
294
+ tags={${tags.map((t) => `"${t}"`).join(",")}},
295
+ speed=${speed / 50},
296
+ hp=${this.getComponentProperty(entity, "health", "max", 3)},
297
+ max_hp=${this.getComponentProperty(entity, "health", "max", 3)},
298
+
299
+ init=function(self)
300
+ -- custom init
301
+ end,
302
+
303
+ update=function(self)
304
+ -- movement
305
+ self.x+=self.dx
306
+ self.y+=self.dy
307
+
308
+ -- friction
309
+ self.dx*=0.9
310
+ self.dy*=0.9
311
+
312
+ -- animation
313
+ if self.anim.speed>0 then
314
+ self.anim.t+=self.anim.speed
315
+ if self.anim.t>=1 then
316
+ self.anim.t=0
317
+ self.anim.i+=1
318
+ if self.anim.i>#self.anim.frames then
319
+ self.anim.i=1
320
+ end
321
+ self.spr=self.anim.frames[self.anim.i]
322
+ end
323
+ end
324
+ end,
325
+
326
+ draw=function(self)
327
+ spr(self.spr,self.x,self.y,1,1,self.flip_x)
328
+ end,
329
+
330
+ on_collision=function(self,other)
331
+ -- handle collision
332
+ end,
333
+
334
+ hurt=function(self,dmg)
335
+ self.hp-=(dmg or 1)
336
+ if self.hp<=0 then
337
+ self:die()
338
+ end
339
+ end,
340
+
341
+ die=function(self)
342
+ -- spawn particles
343
+ for i=1,4 do
344
+ spawn_particle(self.x+4,self.y+4,7)
345
+ end
346
+ kill_entity(self)
347
+ end
348
+ }
349
+
281
350
  `;
351
+ }
352
+ getEntitySpriteIndex(entity) {
353
+ const name = (entity.name ?? "entity").toLowerCase();
354
+ if (name.includes("player")) {
355
+ return 1;
282
356
  }
283
- generateEntityDefinitions(project, _options) {
284
- const lines = [];
285
- lines.push('');
286
- lines.push('-- entity types');
287
- lines.push('entity_types={}');
288
- lines.push('');
289
- // Generate entity types from prefabs and entities
290
- const entityTypes = new Map();
291
- for (const prefab of project.prefabs) {
292
- entityTypes.set(prefab.name.toLowerCase().replace(/[^a-z0-9_]/g, '_'), prefab.entity);
293
- }
294
- for (const scene of project.scenes) {
295
- for (const entity of scene.entities) {
296
- const typeName = (entity.name ?? entity.id).toLowerCase().replace(/[^a-z0-9_]/g, '_');
297
- if (!entityTypes.has(typeName)) {
298
- entityTypes.set(typeName, entity);
299
- }
300
- }
301
- }
302
- for (const [typeName, entity] of entityTypes) {
303
- lines.push(this.entityTypeToLua(typeName, entity));
304
- }
305
- return lines.join('\n');
357
+ if (name.includes("enemy")) {
358
+ return 16;
306
359
  }
307
- entityTypeToLua(typeName, entity) {
308
- const tags = entity.tags ?? [];
309
- entity.components.some((c) => c.type === 'sprite');
310
- const hasPhysics = entity.components.some((c) => c.type === 'rigidbody');
311
- entity.components.some((c) => c.type === 'script');
312
- const sprIndex = this.getEntitySpriteIndex(entity);
313
- const speed = this.getComponentProperty(entity, 'movement', 'speed', 1);
314
- return `entity_types.${typeName}={
315
- spr=${sprIndex},
316
- w=8,h=8,
317
- solid=${hasPhysics},
318
- tags={${tags.map((t) => `"${t}"`).join(',')}},
319
- speed=${speed / 50},
320
- hp=${this.getComponentProperty(entity, 'health', 'max', 3)},
321
- max_hp=${this.getComponentProperty(entity, 'health', 'max', 3)},
322
-
323
- init=function(self)
324
- -- custom init
325
- end,
326
-
327
- update=function(self)
328
- -- movement
329
- self.x+=self.dx
330
- self.y+=self.dy
331
-
332
- -- friction
333
- self.dx*=0.9
334
- self.dy*=0.9
335
-
336
- -- animation
337
- if self.anim.speed>0 then
338
- self.anim.t+=self.anim.speed
339
- if self.anim.t>=1 then
340
- self.anim.t=0
341
- self.anim.i+=1
342
- if self.anim.i>#self.anim.frames then
343
- self.anim.i=1
344
- end
345
- self.spr=self.anim.frames[self.anim.i]
346
- end
347
- end
348
- end,
349
-
350
- draw=function(self)
351
- spr(self.spr,self.x,self.y,1,1,self.flip_x)
352
- end,
353
-
354
- on_collision=function(self,other)
355
- -- handle collision
356
- end,
357
-
358
- hurt=function(self,dmg)
359
- self.hp-=(dmg or 1)
360
- if self.hp<=0 then
361
- self:die()
362
- end
363
- end,
364
-
365
- die=function(self)
366
- -- spawn particles
367
- for i=1,4 do
368
- spawn_particle(self.x+4,self.y+4,7)
369
- end
370
- kill_entity(self)
371
- end
372
- }
373
-
374
- `;
360
+ if (name.includes("item")) {
361
+ return 32;
375
362
  }
376
- getEntitySpriteIndex(entity) {
377
- // Map entity types to sprite indices (placeholder logic)
378
- const name = (entity.name ?? 'entity').toLowerCase();
379
- if (name.includes('player')) {
380
- return 1;
381
- }
382
- if (name.includes('enemy')) {
383
- return 16;
384
- }
385
- if (name.includes('item')) {
386
- return 32;
387
- }
388
- if (name.includes('bullet') || name.includes('projectile')) {
389
- return 48;
390
- }
391
- return 0;
363
+ if (name.includes("bullet") || name.includes("projectile")) {
364
+ return 48;
392
365
  }
393
- getComponentProperty(entity, componentType, property, defaultValue) {
394
- const comp = entity.components.find((c) => c.type === componentType);
395
- if (comp && comp.properties && property in comp.properties) {
396
- return comp.properties[property];
397
- }
398
- return defaultValue;
366
+ return 0;
367
+ }
368
+ getComponentProperty(entity, componentType, property, defaultValue) {
369
+ const comp = entity.components.find((c) => c.type === componentType);
370
+ if (comp && comp.properties && property in comp.properties) {
371
+ return comp.properties[property];
399
372
  }
400
- generateSceneSetup(project, _options) {
401
- const lines = [];
402
- lines.push('');
403
- lines.push('-- scenes');
404
- lines.push('scenes={}');
405
- lines.push('');
406
- for (let i = 0; i < project.scenes.length; i++) {
407
- const scene = project.scenes[i];
408
- const sceneName = scene.name.toLowerCase().replace(/[^a-z0-9_]/g, '_');
409
- lines.push(`scenes[${i + 1}]={`);
410
- lines.push(` name="${sceneName}",`);
411
- lines.push(` entities={`);
412
- for (const entity of scene.entities) {
413
- const typeName = (entity.name ?? entity.id).toLowerCase().replace(/[^a-z0-9_]/g, '_');
414
- const pos = entity.position ?? { x: 0, y: 0 };
415
- // Scale position for PICO-8 (128x128)
416
- const x = Math.floor((pos.x / project.settings.resolution.width) * 128);
417
- const y = Math.floor((pos.y / project.settings.resolution.height) * 128);
418
- lines.push(` {type="${typeName}",x=${x},y=${y}},`);
419
- }
420
- lines.push(` }`);
421
- lines.push(`}`);
422
- lines.push('');
423
- }
424
- lines.push('function load_scene(n)');
425
- lines.push(' game.entities={}');
426
- lines.push(' local s=scenes[n]');
427
- lines.push(' if s then');
428
- lines.push(' for e in all(s.entities) do');
429
- lines.push(' make_entity(e.type,e.x,e.y)');
430
- lines.push(' end');
431
- lines.push(' end');
432
- lines.push('end');
433
- return lines.join('\n');
373
+ return defaultValue;
374
+ }
375
+ generateSceneSetup(project, _options) {
376
+ const lines = [];
377
+ lines.push("");
378
+ lines.push("-- scenes");
379
+ lines.push("scenes={}");
380
+ lines.push("");
381
+ for (let i = 0; i < project.scenes.length; i++) {
382
+ const scene = project.scenes[i];
383
+ const sceneName = scene.name.toLowerCase().replace(/[^a-z0-9_]/g, "_");
384
+ lines.push(`scenes[${i + 1}]={`);
385
+ lines.push(` name="${sceneName}",`);
386
+ lines.push(` entities={`);
387
+ for (const entity of scene.entities) {
388
+ const typeName = (entity.name ?? entity.id).toLowerCase().replace(/[^a-z0-9_]/g, "_");
389
+ const pos = entity.position ?? { x: 0, y: 0 };
390
+ const x = Math.floor(pos.x / project.settings.resolution.width * 128);
391
+ const y = Math.floor(pos.y / project.settings.resolution.height * 128);
392
+ lines.push(` {type="${typeName}",x=${x},y=${y}},`);
393
+ }
394
+ lines.push(` }`);
395
+ lines.push(`}`);
396
+ lines.push("");
434
397
  }
435
- generateUtilityFunctions(optimizeTokens) {
436
- if (optimizeTokens) {
437
- return `
438
- -- utils (optimized)
439
- function v(x,y) return {x=x,y=y} end
440
- function dist(a,b) return sqrt((b.x-a.x)^2+(b.y-a.y)^2) end
441
- function lerp(a,b,t) return a+(b-a)*t end
442
- function clamp(v,mn,mx) return max(mn,min(mx,v)) end
443
- function rnd_range(a,b) return a+rnd(b-a) end
444
- function sign(v) return v>0 and 1 or v<0 and -1 or 0 end
445
-
446
- function sort_entities()
447
- for i=1,#game.entities do
448
- local j=i
449
- while j>1 and game.entities[j-1].y>game.entities[j].y do
450
- game.entities[j],game.entities[j-1]=game.entities[j-1],game.entities[j]
451
- j-=1
452
- end
453
- end
454
- end
455
-
456
- function spawn_particle(x,y,c)
457
- local p={x=x,y=y,dx=rnd(2)-1,dy=rnd(2)-1,c=c,life=15+rnd(10),draw=function(s) pset(s.x,s.y,s.c) end,update=function(s) s.x+=s.dx s.y+=s.dy s.life-=1 if s.life<=0 then s.dead=true end end}
458
- add(game.entities,p)
459
- end
460
-
461
- function draw_ui()
462
- -- hud here
463
- end
464
- `;
465
- }
466
- return `
467
- -- utility functions
468
- function vec(x,y)
469
- return {x=x,y=y}
470
- end
471
-
472
- function dist(a,b)
473
- local dx=b.x-a.x
474
- local dy=b.y-a.y
475
- return sqrt(dx*dx+dy*dy)
476
- end
477
-
478
- function lerp(a,b,t)
479
- return a+(b-a)*t
480
- end
481
-
482
- function clamp(val,min_val,max_val)
483
- return max(min_val,min(max_val,val))
484
- end
485
-
486
- function rnd_range(min_val,max_val)
487
- return min_val+rnd(max_val-min_val)
488
- end
489
-
490
- function sign(val)
491
- if val>0 then return 1 end
492
- if val<0 then return -1 end
493
- return 0
494
- end
495
-
496
- function sort_entities()
497
- -- insertion sort by y
498
- for i=1,#game.entities do
499
- local j=i
500
- while j>1 and game.entities[j-1].y>game.entities[j].y do
501
- game.entities[j],game.entities[j-1]=game.entities[j-1],game.entities[j]
502
- j-=1
503
- end
504
- end
505
- end
506
-
507
- function spawn_particle(x,y,color)
508
- local p={
509
- x=x,
510
- y=y,
511
- dx=rnd(2)-1,
512
- dy=rnd(2)-1,
513
- c=color,
514
- life=15+rnd(10),
515
- dead=false,
516
- draw=function(self)
517
- pset(self.x,self.y,self.c)
518
- end,
519
- update=function(self)
520
- self.x+=self.dx
521
- self.y+=self.dy
522
- self.dy+=0.05 -- gravity
523
- self.life-=1
524
- if self.life<=0 then
525
- self.dead=true
526
- end
527
- end
528
- }
529
- add(game.entities,p)
530
- end
531
-
532
- function screensh()
533
- -- screenshake
534
- if game.shake and game.shake>0 then
535
- game.cam.x=rnd(game.shake)-game.shake/2
536
- game.cam.y=rnd(game.shake)-game.shake/2
537
- game.shake-=0.5
538
- else
539
- game.shake=0
540
- game.cam.x=0
541
- game.cam.y=0
542
- end
543
- end
544
-
545
- function shake(amount)
546
- game.shake=(game.shake or 0)+amount
547
- end
548
-
549
- function draw_ui()
550
- -- hud
551
- print("nice2dev",1,1,7)
552
- end
553
-
554
- -- input helpers
555
- function btn_pressed(b)
556
- return btn(b) and not btnp(b)
557
- end
398
+ lines.push("function load_scene(n)");
399
+ lines.push(" game.entities={}");
400
+ lines.push(" local s=scenes[n]");
401
+ lines.push(" if s then");
402
+ lines.push(" for e in all(s.entities) do");
403
+ lines.push(" make_entity(e.type,e.x,e.y)");
404
+ lines.push(" end");
405
+ lines.push(" end");
406
+ lines.push("end");
407
+ return lines.join("\n");
408
+ }
409
+ generateUtilityFunctions(optimizeTokens) {
410
+ if (optimizeTokens) {
411
+ return `
412
+ -- utils (optimized)
413
+ function v(x,y) return {x=x,y=y} end
414
+ function dist(a,b) return sqrt((b.x-a.x)^2+(b.y-a.y)^2) end
415
+ function lerp(a,b,t) return a+(b-a)*t end
416
+ function clamp(v,mn,mx) return max(mn,min(mx,v)) end
417
+ function rnd_range(a,b) return a+rnd(b-a) end
418
+ function sign(v) return v>0 and 1 or v<0 and -1 or 0 end
419
+
420
+ function sort_entities()
421
+ for i=1,#game.entities do
422
+ local j=i
423
+ while j>1 and game.entities[j-1].y>game.entities[j].y do
424
+ game.entities[j],game.entities[j-1]=game.entities[j-1],game.entities[j]
425
+ j-=1
426
+ end
427
+ end
428
+ end
429
+
430
+ function spawn_particle(x,y,c)
431
+ local p={x=x,y=y,dx=rnd(2)-1,dy=rnd(2)-1,c=c,life=15+rnd(10),draw=function(s) pset(s.x,s.y,s.c) end,update=function(s) s.x+=s.dx s.y+=s.dy s.life-=1 if s.life<=0 then s.dead=true end end}
432
+ add(game.entities,p)
433
+ end
434
+
435
+ function draw_ui()
436
+ -- hud here
437
+ end
558
438
  `;
559
439
  }
560
- generateDebugOverlay() {
561
- return `
562
- -- debug overlay
563
- function draw_debug()
564
- local mem=flr(stat(0)/1024*100)/100
565
- local cpu=flr(stat(1)*100)
566
-
567
- rectfill(0,0,127,12,0)
568
- print("fps:"..stat(7).." cpu:"..cpu.."%",1,1,7)
569
- print("mem:"..mem.."kb ent:"..#game.entities,1,7,7)
570
-
571
- -- draw hitboxes
572
- for e in all(game.entities) do
573
- if e.solid then
574
- rect(e.x,e.y,e.x+e.w-1,e.y+e.h-1,8)
575
- end
576
- end
577
- end
440
+ return `
441
+ -- utility functions
442
+ function vec(x,y)
443
+ return {x=x,y=y}
444
+ end
445
+
446
+ function dist(a,b)
447
+ local dx=b.x-a.x
448
+ local dy=b.y-a.y
449
+ return sqrt(dx*dx+dy*dy)
450
+ end
451
+
452
+ function lerp(a,b,t)
453
+ return a+(b-a)*t
454
+ end
455
+
456
+ function clamp(val,min_val,max_val)
457
+ return max(min_val,min(max_val,val))
458
+ end
459
+
460
+ function rnd_range(min_val,max_val)
461
+ return min_val+rnd(max_val-min_val)
462
+ end
463
+
464
+ function sign(val)
465
+ if val>0 then return 1 end
466
+ if val<0 then return -1 end
467
+ return 0
468
+ end
469
+
470
+ function sort_entities()
471
+ -- insertion sort by y
472
+ for i=1,#game.entities do
473
+ local j=i
474
+ while j>1 and game.entities[j-1].y>game.entities[j].y do
475
+ game.entities[j],game.entities[j-1]=game.entities[j-1],game.entities[j]
476
+ j-=1
477
+ end
478
+ end
479
+ end
480
+
481
+ function spawn_particle(x,y,color)
482
+ local p={
483
+ x=x,
484
+ y=y,
485
+ dx=rnd(2)-1,
486
+ dy=rnd(2)-1,
487
+ c=color,
488
+ life=15+rnd(10),
489
+ dead=false,
490
+ draw=function(self)
491
+ pset(self.x,self.y,self.c)
492
+ end,
493
+ update=function(self)
494
+ self.x+=self.dx
495
+ self.y+=self.dy
496
+ self.dy+=0.05 -- gravity
497
+ self.life-=1
498
+ if self.life<=0 then
499
+ self.dead=true
500
+ end
501
+ end
502
+ }
503
+ add(game.entities,p)
504
+ end
505
+
506
+ function screensh()
507
+ -- screenshake
508
+ if game.shake and game.shake>0 then
509
+ game.cam.x=rnd(game.shake)-game.shake/2
510
+ game.cam.y=rnd(game.shake)-game.shake/2
511
+ game.shake-=0.5
512
+ else
513
+ game.shake=0
514
+ game.cam.x=0
515
+ game.cam.y=0
516
+ end
517
+ end
518
+
519
+ function shake(amount)
520
+ game.shake=(game.shake or 0)+amount
521
+ end
522
+
523
+ function draw_ui()
524
+ -- hud
525
+ print("nice2dev",1,1,7)
526
+ end
527
+
528
+ -- input helpers
529
+ function btn_pressed(b)
530
+ return btn(b) and not btnp(b)
531
+ end
578
532
  `;
579
- }
580
- /* ── Data Sections ──────────────────────────────────────────── */
581
- generateGfxSection(_project, _options) {
582
- // Generate placeholder sprite sheet (128x128 = 256 lines of 128 hex chars)
583
- // Each pixel is 4 bits (one hex char)
584
- const lines = [];
585
- // Basic placeholder sprites
586
- // Sprite 0: Empty
587
- // Sprite 1: Player placeholder (simple face)
588
- // Sprite 16: Enemy placeholder
589
- // Sprite 32: Item placeholder
590
- for (let row = 0; row < 128; row++) {
591
- let line = '';
592
- for (let col = 0; col < 128; col++) {
593
- const spriteX = col % 8;
594
- const spriteY = row % 8;
595
- const spriteIndex = Math.floor(col / 8) + Math.floor(row / 8) * 16;
596
- let pixel = 0;
597
- // Sprite 1: Player (simple character)
598
- if (spriteIndex === 1) {
599
- // Draw a simple face
600
- if (spriteY === 1 && (spriteX === 2 || spriteX === 5)) {
601
- pixel = 12;
602
- } // eyes (blue)
603
- else if (spriteY === 3 && spriteX >= 2 && spriteX <= 5) {
604
- pixel = 8;
605
- } // mouth (red)
606
- else if (spriteY >= 1 && spriteY <= 5 && spriteX >= 1 && spriteX <= 6) {
607
- pixel = 15;
608
- } // face (peach)
609
- else if ((spriteY === 0 || spriteY === 6) && spriteX >= 2 && spriteX <= 5) {
610
- pixel = 4;
611
- } // hair
612
- else if ((spriteX === 0 || spriteX === 7) && spriteY >= 1 && spriteY <= 5) {
613
- pixel = 4;
614
- } // hair sides
615
- }
616
- // Sprite 16: Enemy (red square)
617
- else if (spriteIndex === 16) {
618
- if (spriteX >= 1 && spriteX <= 6 && spriteY >= 1 && spriteY <= 6) {
619
- pixel = 8;
620
- } // red body
621
- if (spriteY === 2 && (spriteX === 2 || spriteX === 5)) {
622
- pixel = 7;
623
- } // eyes
624
- }
625
- // Sprite 32: Item (yellow coin)
626
- else if (spriteIndex === 32) {
627
- if (spriteX >= 2 && spriteX <= 5 && spriteY >= 1 && spriteY <= 6) {
628
- pixel = 10;
629
- } // yellow
630
- if (spriteY >= 2 && spriteY <= 5 && (spriteX === 1 || spriteX === 6)) {
631
- pixel = 10;
632
- }
633
- if (spriteX >= 3 && spriteX <= 4 && spriteY >= 3 && spriteY <= 4) {
634
- pixel = 9;
635
- } // orange center
636
- }
637
- line += pixel.toString(16);
638
- }
639
- lines.push(line);
533
+ }
534
+ generateDebugOverlay() {
535
+ return `
536
+ -- debug overlay
537
+ function draw_debug()
538
+ local mem=flr(stat(0)/1024*100)/100
539
+ local cpu=flr(stat(1)*100)
540
+
541
+ rectfill(0,0,127,12,0)
542
+ print("fps:"..stat(7).." cpu:"..cpu.."%",1,1,7)
543
+ print("mem:"..mem.."kb ent:"..#game.entities,1,7,7)
544
+
545
+ -- draw hitboxes
546
+ for e in all(game.entities) do
547
+ if e.solid then
548
+ rect(e.x,e.y,e.x+e.w-1,e.y+e.h-1,8)
549
+ end
550
+ end
551
+ end
552
+ `;
553
+ }
554
+ /* ── Data Sections ──────────────────────────────────────────── */
555
+ generateGfxSection(_project, _options) {
556
+ const lines = [];
557
+ for (let row = 0; row < 128; row++) {
558
+ let line = "";
559
+ for (let col = 0; col < 128; col++) {
560
+ const spriteX = col % 8;
561
+ const spriteY = row % 8;
562
+ const spriteIndex = Math.floor(col / 8) + Math.floor(row / 8) * 16;
563
+ let pixel = 0;
564
+ if (spriteIndex === 1) {
565
+ if (spriteY === 1 && (spriteX === 2 || spriteX === 5)) {
566
+ pixel = 12;
567
+ } else if (spriteY === 3 && spriteX >= 2 && spriteX <= 5) {
568
+ pixel = 8;
569
+ } else if (spriteY >= 1 && spriteY <= 5 && spriteX >= 1 && spriteX <= 6) {
570
+ pixel = 15;
571
+ } else if ((spriteY === 0 || spriteY === 6) && spriteX >= 2 && spriteX <= 5) {
572
+ pixel = 4;
573
+ } else if ((spriteX === 0 || spriteX === 7) && spriteY >= 1 && spriteY <= 5) {
574
+ pixel = 4;
575
+ }
576
+ } else if (spriteIndex === 16) {
577
+ if (spriteX >= 1 && spriteX <= 6 && spriteY >= 1 && spriteY <= 6) {
578
+ pixel = 8;
579
+ }
580
+ if (spriteY === 2 && (spriteX === 2 || spriteX === 5)) {
581
+ pixel = 7;
582
+ }
583
+ } else if (spriteIndex === 32) {
584
+ if (spriteX >= 2 && spriteX <= 5 && spriteY >= 1 && spriteY <= 6) {
585
+ pixel = 10;
586
+ }
587
+ if (spriteY >= 2 && spriteY <= 5 && (spriteX === 1 || spriteX === 6)) {
588
+ pixel = 10;
589
+ }
590
+ if (spriteX >= 3 && spriteX <= 4 && spriteY >= 3 && spriteY <= 4) {
591
+ pixel = 9;
592
+ }
640
593
  }
641
- return lines.join('\n');
594
+ line += pixel.toString(16);
595
+ }
596
+ lines.push(line);
642
597
  }
643
- generateGffSection(_project) {
644
- // Sprite flags: 256 bytes (2 per line, 128 lines)
645
- // All zeros for placeholder
646
- const lines = [];
647
- for (let i = 0; i < 2; i++) {
648
- lines.push('0'.repeat(256));
649
- }
650
- return lines.join('\n');
598
+ return lines.join("\n");
599
+ }
600
+ generateGffSection(_project) {
601
+ const lines = [];
602
+ for (let i = 0; i < 2; i++) {
603
+ lines.push("0".repeat(256));
651
604
  }
652
- generateMapSection(_project) {
653
- // Map: 128x64 tiles, stored as 128 bytes per row, 64 rows
654
- // Actually stored as 128x32 in __map__ section
655
- const lines = [];
656
- for (let i = 0; i < 32; i++) {
657
- lines.push('0'.repeat(256));
658
- }
659
- return lines.join('\n');
605
+ return lines.join("\n");
606
+ }
607
+ generateMapSection(_project) {
608
+ const lines = [];
609
+ for (let i = 0; i < 32; i++) {
610
+ lines.push("0".repeat(256));
660
611
  }
661
- generateSfxSection(project, options) {
662
- const platformOpts = options.platformOptions ?? {};
663
- if (!platformOpts.sfxPlaceholders) {
664
- // Empty sfx section
665
- return '';
666
- }
667
- // Placeholder sound effects
668
- const lines = [];
669
- // SFX 0: Jump sound
670
- lines.push('000100000c0500c0500b0500a050090500805007050060500505004050030500205001050000500005000050000500005000050000500005000050000500005');
671
- // SFX 1: Hit sound
672
- lines.push('001000001805018050170501605015050140501305012050110501005010050100500005000050000500005000050000500005000050000500005000050');
673
- // SFX 2: Pickup sound
674
- lines.push('000600002405024050260502805030050320503305034050350503605036050350503405033050300502705024050000500005000050000500005000050');
675
- // Fill rest with empty
676
- for (let i = 3; i < 64; i++) {
677
- lines.push('001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000');
678
- }
679
- return lines.join('\n');
612
+ return lines.join("\n");
613
+ }
614
+ generateSfxSection(project, options) {
615
+ const platformOpts = options.platformOptions ?? {};
616
+ if (!platformOpts.sfxPlaceholders) {
617
+ return "";
680
618
  }
681
- generateMusicSection(project, options) {
682
- const platformOpts = options.platformOptions ?? {};
683
- if (!platformOpts.musicPatterns) {
684
- return '';
685
- }
686
- // Placeholder music patterns
687
- const lines = [];
688
- // Pattern 0: Simple loop
689
- lines.push('00 41424344');
690
- // Fill rest with empty
691
- for (let i = 1; i < 64; i++) {
692
- lines.push('00 41424344'.replace(/\d/g, '4'));
693
- }
694
- return lines.join('\n');
619
+ const lines = [];
620
+ lines.push(
621
+ "000100000c0500c0500b0500a050090500805007050060500505004050030500205001050000500005000050000500005000050000500005000050000500005"
622
+ );
623
+ lines.push(
624
+ "001000001805018050170501605015050140501305012050110501005010050100500005000050000500005000050000500005000050000500005000050"
625
+ );
626
+ lines.push(
627
+ "000600002405024050260502805030050320503305034050350503605036050350503405033050300502705024050000500005000050000500005000050"
628
+ );
629
+ for (let i = 3; i < 64; i++) {
630
+ lines.push(
631
+ "001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
632
+ );
695
633
  }
696
- /* ── Lua Source ─────────────────────────────────────────────── */
697
- async generateLuaSource(project, options) {
698
- const code = this.generateCode(project, options);
699
- this.addTextFile('source.lua', `-- ${project.name} - Source Code\n-- For reference only (use .p8 file in PICO-8)\n\n${code}`);
634
+ return lines.join("\n");
635
+ }
636
+ generateMusicSection(project, options) {
637
+ const platformOpts = options.platformOptions ?? {};
638
+ if (!platformOpts.musicPatterns) {
639
+ return "";
700
640
  }
701
- /* ── Color Utilities ────────────────────────────────────────── */
702
- getClosestPico8Color(hex) {
703
- const cleanHex = hex.replace('#', '').toLowerCase();
704
- const r = parseInt(cleanHex.substring(0, 2), 16);
705
- const g = parseInt(cleanHex.substring(2, 4), 16);
706
- const b = parseInt(cleanHex.substring(4, 6), 16);
707
- let closestIndex = 0;
708
- let closestDist = Infinity;
709
- for (let i = 0; i < PICO8_PALETTE.length; i++) {
710
- const palHex = PICO8_PALETTE[i].replace('#', '');
711
- const pr = parseInt(palHex.substring(0, 2), 16);
712
- const pg = parseInt(palHex.substring(2, 4), 16);
713
- const pb = parseInt(palHex.substring(4, 6), 16);
714
- const dist = Math.sqrt(Math.pow(r - pr, 2) + Math.pow(g - pg, 2) + Math.pow(b - pb, 2));
715
- if (dist < closestDist) {
716
- closestDist = dist;
717
- closestIndex = i;
718
- }
719
- }
720
- return closestIndex;
641
+ const lines = [];
642
+ lines.push("00 41424344");
643
+ for (let i = 1; i < 64; i++) {
644
+ lines.push("00 41424344".replace(/\d/g, "4"));
721
645
  }
722
- /* ── README ─────────────────────────────────────────────────── */
723
- async generateReadme(project, options) {
724
- const safeName = (options.projectName ?? project.name)
725
- .toLowerCase()
726
- .replace(/[^a-z0-9_]/g, '_');
727
- const readme = `# ${project.name} - PICO-8 Export
728
-
729
- Generated from Nice2Dev project v${project.version}
730
-
731
- ## Requirements
732
-
733
- - PICO-8 ($15 from https://www.lexaloffle.com/pico-8.php)
734
-
735
- ## Installation
736
-
737
- 1. Open PICO-8
738
- 2. Type: \`load ${safeName}\`
739
- 3. Press Ctrl+R or type \`run\`
740
-
741
- ## Files
742
-
743
- - \`${safeName}.p8\` - PICO-8 cartridge file
744
- - \`source.lua\` - Extracted Lua source (for reference)
745
-
746
- ## PICO-8 Constraints
747
-
748
- This export is designed for PICO-8's limitations:
749
- - **Display**: 128x128 pixels
750
- - **Colors**: 16 color palette
751
- - **Code**: 8192 tokens max
752
- - **Memory**: 32KB cartridge
753
- - **Sprites**: 128 8x8 sprites
754
- - **Map**: 128x64 tiles
755
- - **Sound**: 64 SFX slots
756
- - **Music**: 64 patterns
757
-
758
- ## Controls
759
-
760
- - ⬅️➡️⬆️⬇️ / ESDF: Move
761
- - 🅾️ (Z/C): Action 1
762
- - ❎ (X/V): Action 2
763
- - P: Pause menu
764
-
765
- ## Code Structure
766
-
767
- \`\`\`lua
768
- -- _init() - Called once at start
769
- -- _update60() - Called 60 times per second
770
- -- _draw() - Called after update for rendering
771
- \`\`\`
772
-
773
- ### Entity System
774
-
775
- \`\`\`lua
776
- -- Create entity
777
- local e = make_entity("player", 64, 64)
778
-
779
- -- Kill entity
780
- kill_entity(e)
781
-
782
- -- Check tag
783
- if has_tag(e, "enemy") then
784
- -- ...
785
- end
786
- \`\`\`
787
-
788
- ### Scenes
789
-
790
- ${project.scenes.map((s, i) => `- Scene ${i + 1}: ${s.name} (${s.entities.length} entities)`).join('\n')}
791
-
792
- Load scene with: \`load_scene(1)\`
793
-
794
- ## Customization
795
-
796
- ### Adding Sprites
797
-
798
- 1. In PICO-8, press Ctrl+S to open sprite editor
799
- 2. Draw your sprites (8x8 pixels each)
800
- 3. Update entity_types sprite indices
801
-
802
- ### Adding Sounds
803
-
804
- 1. Press Ctrl+N for SFX editor
805
- 2. Create sounds in slots 0-63
806
- 3. Play with: \`sfx(0)\`
807
-
808
- ### Adding Music
809
-
810
- 1. Press Ctrl+M for music editor
811
- 2. Create patterns using SFX
812
- 3. Play with: \`music(0)\`
813
-
814
- ## Debug Mode
815
-
816
- Set \`game.debug=true\` to show:
817
- - FPS counter
818
- - CPU usage
819
- - Memory usage
820
- - Entity hitboxes
821
-
822
- ## Tips
823
-
824
- - Keep code under 8192 tokens
825
- - Use shorter variable names to save tokens
826
- - Reuse sprites with flip flags
827
- - Use map for static backgrounds
828
- - Pool entities to avoid garbage
829
-
830
- ## Links
831
-
832
- - PICO-8 Manual: https://www.lexaloffle.com/dl/docs/pico-8_manual.html
833
- - PICO-8 Wiki: https://pico-8.fandom.com/
834
- - Splore: Built-in game browser (type \`splore\`)
835
- `;
836
- this.addTextFile('README.md', readme);
646
+ return lines.join("\n");
647
+ }
648
+ /* ── Lua Source ─────────────────────────────────────────────── */
649
+ async generateLuaSource(project, options) {
650
+ const code = this.generateCode(project, options);
651
+ this.addTextFile(
652
+ "source.lua",
653
+ `-- ${project.name} - Source Code
654
+ -- For reference only (use .p8 file in PICO-8)
655
+
656
+ ${code}`
657
+ );
658
+ }
659
+ /* ── Color Utilities ────────────────────────────────────────── */
660
+ getClosestPico8Color(hex) {
661
+ const cleanHex = hex.replace("#", "").toLowerCase();
662
+ const r = parseInt(cleanHex.substring(0, 2), 16);
663
+ const g = parseInt(cleanHex.substring(2, 4), 16);
664
+ const b = parseInt(cleanHex.substring(4, 6), 16);
665
+ let closestIndex = 0;
666
+ let closestDist = Infinity;
667
+ for (let i = 0; i < PICO8_PALETTE.length; i++) {
668
+ const palHex = PICO8_PALETTE[i].replace("#", "");
669
+ const pr = parseInt(palHex.substring(0, 2), 16);
670
+ const pg = parseInt(palHex.substring(2, 4), 16);
671
+ const pb = parseInt(palHex.substring(4, 6), 16);
672
+ const dist = Math.sqrt(Math.pow(r - pr, 2) + Math.pow(g - pg, 2) + Math.pow(b - pb, 2));
673
+ if (dist < closestDist) {
674
+ closestDist = dist;
675
+ closestIndex = i;
676
+ }
837
677
  }
678
+ return closestIndex;
679
+ }
680
+ /* ── README ─────────────────────────────────────────────────── */
681
+ async generateReadme(project, options) {
682
+ const safeName = (options.projectName ?? project.name).toLowerCase().replace(/[^a-z0-9_]/g, "_");
683
+ const readme = `# ${project.name} - PICO-8 Export
684
+
685
+ Generated from Nice2Dev project v${project.version}
686
+
687
+ ## Requirements
688
+
689
+ - PICO-8 ($15 from https://www.lexaloffle.com/pico-8.php)
690
+
691
+ ## Installation
692
+
693
+ 1. Open PICO-8
694
+ 2. Type: \`load ${safeName}\`
695
+ 3. Press Ctrl+R or type \`run\`
696
+
697
+ ## Files
698
+
699
+ - \`${safeName}.p8\` - PICO-8 cartridge file
700
+ - \`source.lua\` - Extracted Lua source (for reference)
701
+
702
+ ## PICO-8 Constraints
703
+
704
+ This export is designed for PICO-8's limitations:
705
+ - **Display**: 128x128 pixels
706
+ - **Colors**: 16 color palette
707
+ - **Code**: 8192 tokens max
708
+ - **Memory**: 32KB cartridge
709
+ - **Sprites**: 128 8x8 sprites
710
+ - **Map**: 128x64 tiles
711
+ - **Sound**: 64 SFX slots
712
+ - **Music**: 64 patterns
713
+
714
+ ## Controls
715
+
716
+ - ⬅️➡️⬆️⬇️ / ESDF: Move
717
+ - 🅾️ (Z/C): Action 1
718
+ - ❎ (X/V): Action 2
719
+ - P: Pause menu
720
+
721
+ ## Code Structure
722
+
723
+ \`\`\`lua
724
+ -- _init() - Called once at start
725
+ -- _update60() - Called 60 times per second
726
+ -- _draw() - Called after update for rendering
727
+ \`\`\`
728
+
729
+ ### Entity System
730
+
731
+ \`\`\`lua
732
+ -- Create entity
733
+ local e = make_entity("player", 64, 64)
734
+
735
+ -- Kill entity
736
+ kill_entity(e)
737
+
738
+ -- Check tag
739
+ if has_tag(e, "enemy") then
740
+ -- ...
741
+ end
742
+ \`\`\`
743
+
744
+ ### Scenes
745
+
746
+ ${project.scenes.map((s, i) => `- Scene ${i + 1}: ${s.name} (${s.entities.length} entities)`).join("\n")}
747
+
748
+ Load scene with: \`load_scene(1)\`
749
+
750
+ ## Customization
751
+
752
+ ### Adding Sprites
753
+
754
+ 1. In PICO-8, press Ctrl+S to open sprite editor
755
+ 2. Draw your sprites (8x8 pixels each)
756
+ 3. Update entity_types sprite indices
757
+
758
+ ### Adding Sounds
759
+
760
+ 1. Press Ctrl+N for SFX editor
761
+ 2. Create sounds in slots 0-63
762
+ 3. Play with: \`sfx(0)\`
763
+
764
+ ### Adding Music
765
+
766
+ 1. Press Ctrl+M for music editor
767
+ 2. Create patterns using SFX
768
+ 3. Play with: \`music(0)\`
769
+
770
+ ## Debug Mode
771
+
772
+ Set \`game.debug=true\` to show:
773
+ - FPS counter
774
+ - CPU usage
775
+ - Memory usage
776
+ - Entity hitboxes
777
+
778
+ ## Tips
779
+
780
+ - Keep code under 8192 tokens
781
+ - Use shorter variable names to save tokens
782
+ - Reuse sprites with flip flags
783
+ - Use map for static backgrounds
784
+ - Pool entities to avoid garbage
785
+
786
+ ## Links
787
+
788
+ - PICO-8 Manual: https://www.lexaloffle.com/dl/docs/pico-8_manual.html
789
+ - PICO-8 Wiki: https://pico-8.fandom.com/
790
+ - Splore: Built-in game browser (type \`splore\`)
791
+ `;
792
+ this.addTextFile("README.md", readme);
793
+ }
838
794
  }
839
- /* ── Factory ──────────────────────────────────────────────────── */
840
795
  function createPico8Exporter() {
841
- return new Pico8Exporter();
796
+ return new Pico8Exporter();
842
797
  }
843
-
844
798
  exports.Pico8Exporter = Pico8Exporter;
845
799
  exports.createPico8Exporter = createPico8Exporter;