@nice2dev/game-engine 1.3.15 → 1.3.17

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,1102 +1,1064 @@
1
- import { PlatformExporter } from './PlatformExporter.js';
2
-
3
- /* ────────────────────────────────────────────────────────────────
4
- Defold Exporter — Defold Game Engine Export
5
-
6
- Exports Nice2Dev projects to Defold format:
7
- - Project file (game.project)
8
- - Collection files (.collection)
9
- - Game object files (.go)
10
- - Lua scripts
11
- - GUI files
12
- - Atlas definitions
13
- ──────────────────────────────────────────────────────────────── */
14
- /* ── Defold Component Mappings ────────────────────────────────── */
1
+ import { PlatformExporter } from "./PlatformExporter.js";
15
2
  const DEFOLD_COMPONENT_MAP = {
16
- sprite: (comp, entity) => {
17
- comp.properties?.['texture'] ?? 'main';
18
- return `components {
19
- id: "sprite"
20
- component: "/main/sprites/${(entity.name ?? entity.id).toLowerCase()}.sprite"
21
- position {
22
- x: 0.0
23
- y: 0.0
24
- z: 0.0
25
- }
26
- rotation {
27
- x: 0.0
28
- y: 0.0
29
- z: 0.0
30
- w: 1.0
31
- }
3
+ sprite: (comp, entity) => {
4
+ comp.properties?.["texture"] ?? "main";
5
+ return `components {
6
+ id: "sprite"
7
+ component: "/main/sprites/${(entity.name ?? entity.id).toLowerCase()}.sprite"
8
+ position {
9
+ x: 0.0
10
+ y: 0.0
11
+ z: 0.0
12
+ }
13
+ rotation {
14
+ x: 0.0
15
+ y: 0.0
16
+ z: 0.0
17
+ w: 1.0
18
+ }
32
19
  }`;
33
- },
34
- rigidbody: (comp, entity) => {
35
- comp.properties?.['mass'] ?? 1;
36
- comp.properties?.['linearDamping'] ?? 0;
37
- comp.properties?.['angularDamping'] ?? 0;
38
- return `components {
39
- id: "collisionobject"
40
- component: "/main/collision/${(entity.name ?? entity.id).toLowerCase()}.collisionobject"
41
- position {
42
- x: 0.0
43
- y: 0.0
44
- z: 0.0
45
- }
46
- rotation {
47
- x: 0.0
48
- y: 0.0
49
- z: 0.0
50
- w: 1.0
51
- }
20
+ },
21
+ rigidbody: (comp, entity) => {
22
+ comp.properties?.["mass"] ?? 1;
23
+ comp.properties?.["linearDamping"] ?? 0;
24
+ comp.properties?.["angularDamping"] ?? 0;
25
+ return `components {
26
+ id: "collisionobject"
27
+ component: "/main/collision/${(entity.name ?? entity.id).toLowerCase()}.collisionobject"
28
+ position {
29
+ x: 0.0
30
+ y: 0.0
31
+ z: 0.0
32
+ }
33
+ rotation {
34
+ x: 0.0
35
+ y: 0.0
36
+ z: 0.0
37
+ w: 1.0
38
+ }
52
39
  }`;
53
- },
54
- script: (comp, entity) => {
55
- return `components {
56
- id: "script"
57
- component: "/main/scripts/${(entity.name ?? entity.id).toLowerCase()}.script"
58
- position {
59
- x: 0.0
60
- y: 0.0
61
- z: 0.0
62
- }
63
- rotation {
64
- x: 0.0
65
- y: 0.0
66
- z: 0.0
67
- w: 1.0
68
- }
40
+ },
41
+ script: (comp, entity) => {
42
+ return `components {
43
+ id: "script"
44
+ component: "/main/scripts/${(entity.name ?? entity.id).toLowerCase()}.script"
45
+ position {
46
+ x: 0.0
47
+ y: 0.0
48
+ z: 0.0
49
+ }
50
+ rotation {
51
+ x: 0.0
52
+ y: 0.0
53
+ z: 0.0
54
+ w: 1.0
55
+ }
69
56
  }`;
70
- },
57
+ }
71
58
  };
72
- /* ── Exporter Implementation ──────────────────────────────────── */
73
59
  class DefoldExporter extends PlatformExporter {
74
- constructor() {
75
- super(...arguments);
76
- this.platformId = 'defold';
77
- this.platformInfo = {
78
- id: 'defold',
79
- name: 'Defold',
80
- description: 'Defold - Cross-platform game engine by King',
81
- website: 'https://defold.com/',
82
- features: [
83
- '2d-rendering',
84
- '3d-rendering',
85
- 'physics-2d',
86
- 'physics-3d',
87
- 'audio',
88
- 'particles',
89
- 'ui-system',
90
- 'animation',
91
- ],
92
- supportedAssets: [
93
- 'texture',
94
- 'audio',
95
- 'tilemap',
96
- 'animation',
97
- 'prefab',
98
- 'scene',
99
- 'data',
100
- 'script',
101
- ],
102
- exportFormats: ['.project', '.collection', '.go', '.script', '.gui'],
103
- };
60
+ constructor() {
61
+ super(...arguments);
62
+ this.platformId = "defold";
63
+ this.platformInfo = {
64
+ id: "defold",
65
+ name: "Defold",
66
+ description: "Defold - Cross-platform game engine by King",
67
+ website: "https://defold.com/",
68
+ features: [
69
+ "2d-rendering",
70
+ "3d-rendering",
71
+ "physics-2d",
72
+ "physics-3d",
73
+ "audio",
74
+ "particles",
75
+ "ui-system",
76
+ "animation"
77
+ ],
78
+ supportedAssets: [
79
+ "texture",
80
+ "audio",
81
+ "tilemap",
82
+ "animation",
83
+ "prefab",
84
+ "scene",
85
+ "data",
86
+ "script"
87
+ ],
88
+ exportFormats: [".project", ".collection", ".go", ".script", ".gui"]
89
+ };
90
+ }
91
+ async doExport(project, options) {
92
+ const platformOpts = options.platformOptions ?? {};
93
+ await this.generateProjectFile(project, options);
94
+ await this.generateMainCollection(project, options);
95
+ for (const scene of project.scenes) {
96
+ await this.exportScene(scene, project, options);
104
97
  }
105
- async doExport(project, options) {
106
- const platformOpts = options.platformOptions ?? {};
107
- // Generate main project file
108
- await this.generateProjectFile(project, options);
109
- // Generate main collection (bootstrap)
110
- await this.generateMainCollection(project, options);
111
- // Generate scenes as collections
112
- for (const scene of project.scenes) {
113
- await this.exportScene(scene, project, options);
114
- }
115
- // Generate prefabs as game objects
116
- for (const prefab of project.prefabs) {
117
- await this.exportPrefab(prefab, options);
118
- }
119
- // Generate shared scripts
120
- await this.generateSharedScripts(project, options);
121
- // Generate app manifest for HTML5
122
- if (platformOpts.html5Manifest !== false) {
123
- await this.generateAppManifest(project, options);
124
- }
125
- // Generate README
126
- await this.generateReadme(project, options);
98
+ for (const prefab of project.prefabs) {
99
+ await this.exportPrefab(prefab, options);
127
100
  }
128
- /* ── Project File ───────────────────────────────────────────── */
129
- async generateProjectFile(project, options) {
130
- const safeName = (options.projectName ?? project.name)
131
- .toLowerCase()
132
- .replace(/[^a-z0-9_]/g, '_');
133
- const platformOpts = options.platformOptions ?? {};
134
- const projectContent = `[project]
135
- title = ${project.name}
136
- version = ${project.version}
137
- write_log = 0
138
- compress_archive = 1
139
- publisher = Nice2Dev
140
- developer = Nice2Dev
141
-
142
- [display]
143
- width = ${project.settings.resolution.width}
144
- height = ${project.settings.resolution.height}
145
- high_dpi = 1
146
- samples = 0
147
- fullscreen = 0
148
- update_frequency = 0
149
- swap_interval = 1
150
- vsync = 1
151
- display_profiles = /builtins/render/default.display_profilesc
152
- dynamic_orientation = 0
153
-
154
- [render]
155
- clear_color_red = 0
156
- clear_color_green = 0
157
- clear_color_blue = 0
158
- clear_color_alpha = 0
159
-
160
- [physics]
161
- type = ${platformOpts.usePhysics3D ? '3D' : '2D'}
162
- max_collision_object_count = 128
163
- use_fixed_timestep = 0
164
- gravity_y = ${project.settings.physics.gravity.y}
165
- gravity_x = ${project.settings.physics.gravity.x}
166
- gravity_z = 0
167
- debug = 0
168
- debug_alpha = 0.9
169
- world_count = 4
170
- scale = 0.02
171
-
172
- [bootstrap]
173
- main_collection = /main/main.collectionc
174
- render = /builtins/render/default.renderc
175
-
176
- [graphics]
177
- default_texture_min_filter = linear
178
- default_texture_mag_filter = linear
179
- max_draw_calls = 1024
180
- max_characters = 8192
181
- max_font_batches = 4
182
- max_debug_vertices = 10000
183
- texture_profiles = /builtins/graphics/default.texture_profiles
184
-
185
- [shader]
186
- output_spirv = 0
187
-
188
- [sound]
189
- gain = ${project.settings.audio.masterVolume}
190
- max_sound_data = 128
191
- max_sound_buffers = 32
192
- max_sound_sources = 16
193
- max_sound_instances = 256
194
- max_component_count = 32
195
- use_thread = 1
196
-
197
- [resource]
198
- http_cache = 0
199
- max_resources = 1024
200
-
201
- [input]
202
- repeat_delay = 0.5
203
- repeat_interval = 0.2
204
- gamepads = /builtins/input/default.gamepadsc
205
- game_binding = /input/game.input_bindingc
206
- use_accelerometer = 1
207
-
208
- [sprite]
209
- max_count = 128
210
- subpixels = 1
211
-
212
- [model]
213
- max_count = 128
214
-
215
- [mesh]
216
- max_count = 128
217
-
218
- [gui]
219
- max_count = 64
220
- max_particlefx_count = 64
221
- max_particle_count = 1024
222
-
223
- [collection]
224
- max_instances = 1024
225
- max_input_stack_entries = 16
226
-
227
- [collection_proxy]
228
- max_count = 8
229
-
230
- [collectionfactory]
231
- max_count = 128
232
-
233
- [factory]
234
- max_count = 128
235
-
236
- [ios]
237
- launch_screen = /builtins/manifests/ios/LaunchScreen.storyboardc
238
- infoplist = /builtins/manifests/ios/Info.plist
239
- default_language = en
240
- localizations = en
241
-
242
- [android]
243
- version_code = 1
244
- minimum_sdk_version = 19
245
- target_sdk_version = 33
246
- package = com.nice2dev.${safeName}
247
- manifest = /builtins/manifests/android/AndroidManifest.xml
248
- iap_provider = GooglePlay
249
- input_method = HiddenInputField
250
- immersive_mode = 0
251
- display_cutout = 1
252
- debuggable = 0
253
-
254
- [osx]
255
- infoplist = /builtins/manifests/osx/Info.plist
256
- bundle_identifier = com.nice2dev.${safeName}
257
- default_language = en
258
- localizations = en
259
-
260
- [windows]
261
- icon = /builtins/manifests/windows/game.ico
262
-
263
- [html5]
264
- custom_heap_size = 0
265
- heap_size = 256
266
- htmlfile = /builtins/manifests/web/engine_template.html
267
- cssfile = /builtins/manifests/web/light_theme.css
268
- splash_image = /builtins/manifests/web/splash.png
269
- archive_location_prefix = archive
270
- archive_location_suffix =
271
- engine_arguments = --verify-graphics-calls=false
272
- wasm_streaming = 0
273
- show_fullscreen_button = 1
274
- show_made_with_defold = 1
275
- show_console_banner = 1
276
- scale_mode = fit
277
- power_preference = default
278
-
279
- [particle_fx]
280
- max_count = 64
281
- max_emitter_count = 64
282
- max_particle_count = 1024
283
-
284
- [iap]
285
- auto_finish_transactions = 1
286
-
287
- [network]
288
- http_timeout = 0
289
- ssl_certificates = /builtins/network/ssl_certificates.pem
290
- http_thread_count = 4
291
-
292
- [library]
293
- include_dirs =
294
-
295
- [script]
296
- shared_state = 0
297
-
298
- [label]
299
- max_count = 64
300
- subpixels = 1
301
-
302
- [profiler]
303
- track_cpu = 0
304
- sleep_between_server_updates = 0
305
-
306
- [liveupdate]
307
- settings = /liveupdate.settings
308
- enabled = 1
309
-
310
- [tilemap]
311
- max_count = 16
312
- max_tile_count = 2048
313
-
314
- [engine]
315
- run_while_iconified = 0
316
- fixed_update_frequency = 60
317
-
318
- [native_extension]
319
- _plugins =
320
- `;
321
- this.addTextFile('game.project', projectContent);
101
+ await this.generateSharedScripts(project, options);
102
+ if (platformOpts.html5Manifest !== false) {
103
+ await this.generateAppManifest(project, options);
322
104
  }
323
- /* ── Main Collection ────────────────────────────────────────── */
324
- async generateMainCollection(project, _options) {
325
- const firstScene = project.scenes[0];
326
- const sceneName = firstScene
327
- ? firstScene.name.toLowerCase().replace(/[^a-z0-9_]/g, '_')
328
- : 'level1';
329
- const mainCollection = `name: "main"
330
- scale_along_z: 0
331
- embedded_instances {
332
- id: "game_manager"
333
- data: "components {\\n"
334
- " id: \\"game_manager\\"\\n"
335
- " component: \\"/main/scripts/game_manager.script\\"\\n"
336
- " position {\\n"
337
- " x: 0.0\\n"
338
- " y: 0.0\\n"
339
- " z: 0.0\\n"
340
- " }\\n"
341
- " rotation {\\n"
342
- " x: 0.0\\n"
343
- " y: 0.0\\n"
344
- " z: 0.0\\n"
345
- " w: 1.0\\n"
346
- " }\\n"
347
- "}\\n"
348
- ""
349
- position {
350
- x: 0.0
351
- y: 0.0
352
- z: 0.0
353
- }
354
- rotation {
355
- x: 0.0
356
- y: 0.0
357
- z: 0.0
358
- w: 1.0
359
- }
360
- scale3 {
361
- x: 1.0
362
- y: 1.0
363
- z: 1.0
364
- }
365
- }
366
- collection_instances {
367
- id: "level"
368
- collection: "/main/scenes/${sceneName}.collection"
369
- position {
370
- x: 0.0
371
- y: 0.0
372
- z: 0.0
373
- }
374
- rotation {
375
- x: 0.0
376
- y: 0.0
377
- z: 0.0
378
- w: 1.0
379
- }
380
- scale3 {
381
- x: 1.0
382
- y: 1.0
383
- z: 1.0
384
- }
385
- }
105
+ await this.generateReadme(project, options);
106
+ }
107
+ /* ── Project File ───────────────────────────────────────────── */
108
+ async generateProjectFile(project, options) {
109
+ const safeName = (options.projectName ?? project.name).toLowerCase().replace(/[^a-z0-9_]/g, "_");
110
+ const platformOpts = options.platformOptions ?? {};
111
+ const projectContent = `[project]
112
+ title = ${project.name}
113
+ version = ${project.version}
114
+ write_log = 0
115
+ compress_archive = 1
116
+ publisher = Nice2Dev
117
+ developer = Nice2Dev
118
+
119
+ [display]
120
+ width = ${project.settings.resolution.width}
121
+ height = ${project.settings.resolution.height}
122
+ high_dpi = 1
123
+ samples = 0
124
+ fullscreen = 0
125
+ update_frequency = 0
126
+ swap_interval = 1
127
+ vsync = 1
128
+ display_profiles = /builtins/render/default.display_profilesc
129
+ dynamic_orientation = 0
130
+
131
+ [render]
132
+ clear_color_red = 0
133
+ clear_color_green = 0
134
+ clear_color_blue = 0
135
+ clear_color_alpha = 0
136
+
137
+ [physics]
138
+ type = ${platformOpts.usePhysics3D ? "3D" : "2D"}
139
+ max_collision_object_count = 128
140
+ use_fixed_timestep = 0
141
+ gravity_y = ${project.settings.physics.gravity.y}
142
+ gravity_x = ${project.settings.physics.gravity.x}
143
+ gravity_z = 0
144
+ debug = 0
145
+ debug_alpha = 0.9
146
+ world_count = 4
147
+ scale = 0.02
148
+
149
+ [bootstrap]
150
+ main_collection = /main/main.collectionc
151
+ render = /builtins/render/default.renderc
152
+
153
+ [graphics]
154
+ default_texture_min_filter = linear
155
+ default_texture_mag_filter = linear
156
+ max_draw_calls = 1024
157
+ max_characters = 8192
158
+ max_font_batches = 4
159
+ max_debug_vertices = 10000
160
+ texture_profiles = /builtins/graphics/default.texture_profiles
161
+
162
+ [shader]
163
+ output_spirv = 0
164
+
165
+ [sound]
166
+ gain = ${project.settings.audio.masterVolume}
167
+ max_sound_data = 128
168
+ max_sound_buffers = 32
169
+ max_sound_sources = 16
170
+ max_sound_instances = 256
171
+ max_component_count = 32
172
+ use_thread = 1
173
+
174
+ [resource]
175
+ http_cache = 0
176
+ max_resources = 1024
177
+
178
+ [input]
179
+ repeat_delay = 0.5
180
+ repeat_interval = 0.2
181
+ gamepads = /builtins/input/default.gamepadsc
182
+ game_binding = /input/game.input_bindingc
183
+ use_accelerometer = 1
184
+
185
+ [sprite]
186
+ max_count = 128
187
+ subpixels = 1
188
+
189
+ [model]
190
+ max_count = 128
191
+
192
+ [mesh]
193
+ max_count = 128
194
+
195
+ [gui]
196
+ max_count = 64
197
+ max_particlefx_count = 64
198
+ max_particle_count = 1024
199
+
200
+ [collection]
201
+ max_instances = 1024
202
+ max_input_stack_entries = 16
203
+
204
+ [collection_proxy]
205
+ max_count = 8
206
+
207
+ [collectionfactory]
208
+ max_count = 128
209
+
210
+ [factory]
211
+ max_count = 128
212
+
213
+ [ios]
214
+ launch_screen = /builtins/manifests/ios/LaunchScreen.storyboardc
215
+ infoplist = /builtins/manifests/ios/Info.plist
216
+ default_language = en
217
+ localizations = en
218
+
219
+ [android]
220
+ version_code = 1
221
+ minimum_sdk_version = 19
222
+ target_sdk_version = 33
223
+ package = com.nice2dev.${safeName}
224
+ manifest = /builtins/manifests/android/AndroidManifest.xml
225
+ iap_provider = GooglePlay
226
+ input_method = HiddenInputField
227
+ immersive_mode = 0
228
+ display_cutout = 1
229
+ debuggable = 0
230
+
231
+ [osx]
232
+ infoplist = /builtins/manifests/osx/Info.plist
233
+ bundle_identifier = com.nice2dev.${safeName}
234
+ default_language = en
235
+ localizations = en
236
+
237
+ [windows]
238
+ icon = /builtins/manifests/windows/game.ico
239
+
240
+ [html5]
241
+ custom_heap_size = 0
242
+ heap_size = 256
243
+ htmlfile = /builtins/manifests/web/engine_template.html
244
+ cssfile = /builtins/manifests/web/light_theme.css
245
+ splash_image = /builtins/manifests/web/splash.png
246
+ archive_location_prefix = archive
247
+ archive_location_suffix =
248
+ engine_arguments = --verify-graphics-calls=false
249
+ wasm_streaming = 0
250
+ show_fullscreen_button = 1
251
+ show_made_with_defold = 1
252
+ show_console_banner = 1
253
+ scale_mode = fit
254
+ power_preference = default
255
+
256
+ [particle_fx]
257
+ max_count = 64
258
+ max_emitter_count = 64
259
+ max_particle_count = 1024
260
+
261
+ [iap]
262
+ auto_finish_transactions = 1
263
+
264
+ [network]
265
+ http_timeout = 0
266
+ ssl_certificates = /builtins/network/ssl_certificates.pem
267
+ http_thread_count = 4
268
+
269
+ [library]
270
+ include_dirs =
271
+
272
+ [script]
273
+ shared_state = 0
274
+
275
+ [label]
276
+ max_count = 64
277
+ subpixels = 1
278
+
279
+ [profiler]
280
+ track_cpu = 0
281
+ sleep_between_server_updates = 0
282
+
283
+ [liveupdate]
284
+ settings = /liveupdate.settings
285
+ enabled = 1
286
+
287
+ [tilemap]
288
+ max_count = 16
289
+ max_tile_count = 2048
290
+
291
+ [engine]
292
+ run_while_iconified = 0
293
+ fixed_update_frequency = 60
294
+
295
+ [native_extension]
296
+ _plugins =
386
297
  `;
387
- this.addTextFile('main/main.collection', mainCollection);
388
- }
389
- /* ── Scene Export ───────────────────────────────────────────── */
390
- async exportScene(scene, project, options) {
391
- const sceneName = scene.name.toLowerCase().replace(/[^a-z0-9_]/g, '_');
392
- // Generate collection
393
- let collectionContent = `name: "${sceneName}"
394
- scale_along_z: 0
298
+ this.addTextFile("game.project", projectContent);
299
+ }
300
+ /* ── Main Collection ────────────────────────────────────────── */
301
+ async generateMainCollection(project, _options) {
302
+ const firstScene = project.scenes[0];
303
+ const sceneName = firstScene ? firstScene.name.toLowerCase().replace(/[^a-z0-9_]/g, "_") : "level1";
304
+ const mainCollection = `name: "main"
305
+ scale_along_z: 0
306
+ embedded_instances {
307
+ id: "game_manager"
308
+ data: "components {\\n"
309
+ " id: \\"game_manager\\"\\n"
310
+ " component: \\"/main/scripts/game_manager.script\\"\\n"
311
+ " position {\\n"
312
+ " x: 0.0\\n"
313
+ " y: 0.0\\n"
314
+ " z: 0.0\\n"
315
+ " }\\n"
316
+ " rotation {\\n"
317
+ " x: 0.0\\n"
318
+ " y: 0.0\\n"
319
+ " z: 0.0\\n"
320
+ " w: 1.0\\n"
321
+ " }\\n"
322
+ "}\\n"
323
+ ""
324
+ position {
325
+ x: 0.0
326
+ y: 0.0
327
+ z: 0.0
328
+ }
329
+ rotation {
330
+ x: 0.0
331
+ y: 0.0
332
+ z: 0.0
333
+ w: 1.0
334
+ }
335
+ scale3 {
336
+ x: 1.0
337
+ y: 1.0
338
+ z: 1.0
339
+ }
340
+ }
341
+ collection_instances {
342
+ id: "level"
343
+ collection: "/main/scenes/${sceneName}.collection"
344
+ position {
345
+ x: 0.0
346
+ y: 0.0
347
+ z: 0.0
348
+ }
349
+ rotation {
350
+ x: 0.0
351
+ y: 0.0
352
+ z: 0.0
353
+ w: 1.0
354
+ }
355
+ scale3 {
356
+ x: 1.0
357
+ y: 1.0
358
+ z: 1.0
359
+ }
360
+ }
395
361
  `;
396
- // Add entities as embedded instances
397
- for (const entity of scene.entities) {
398
- collectionContent += this.entityToEmbeddedInstance(entity);
399
- }
400
- this.addTextFile(`main/scenes/${sceneName}.collection`, collectionContent);
401
- // Generate game objects for each entity
402
- for (const entity of scene.entities) {
403
- await this.generateGameObject(entity, options);
404
- }
405
- // Generate scene script
406
- const sceneScript = this.generateSceneScript(scene, project);
407
- this.addTextFile(`main/scripts/${sceneName}_controller.script`, sceneScript);
408
- }
409
- entityToEmbeddedInstance(entity) {
410
- const name = (entity.name ?? entity.id).toLowerCase().replace(/[^a-z0-9_]/g, '_');
411
- const pos = entity.position ?? { x: 0, y: 0 };
412
- const scale = entity.scale ?? { x: 1, y: 1 };
413
- const rotation = entity.rotation ?? 0;
414
- // Calculate quaternion from rotation angle
415
- const radians = (rotation * Math.PI) / 180;
416
- const qz = Math.sin(radians / 2);
417
- const qw = Math.cos(radians / 2);
418
- return `embedded_instances {
419
- id: "${name}"
420
- data: ""
421
- position {
422
- x: ${pos.x}
423
- y: ${pos.y}
424
- z: 0.0
425
- }
426
- rotation {
427
- x: 0.0
428
- y: 0.0
429
- z: ${qz.toFixed(6)}
430
- w: ${qw.toFixed(6)}
431
- }
432
- scale3 {
433
- x: ${scale.x}
434
- y: ${scale.y}
435
- z: 1.0
436
- }
437
- }
362
+ this.addTextFile("main/main.collection", mainCollection);
363
+ }
364
+ /* ── Scene Export ───────────────────────────────────────────── */
365
+ async exportScene(scene, project, options) {
366
+ const sceneName = scene.name.toLowerCase().replace(/[^a-z0-9_]/g, "_");
367
+ let collectionContent = `name: "${sceneName}"
368
+ scale_along_z: 0
438
369
  `;
370
+ for (const entity of scene.entities) {
371
+ collectionContent += this.entityToEmbeddedInstance(entity);
439
372
  }
440
- async generateGameObject(entity, _options) {
441
- const name = (entity.name ?? entity.id).toLowerCase().replace(/[^a-z0-9_]/g, '_');
442
- let goContent = '';
443
- // Add components
444
- for (const comp of entity.components) {
445
- const mapper = DEFOLD_COMPONENT_MAP[comp.type];
446
- if (mapper) {
447
- goContent += mapper(comp, entity) + '\n';
448
- }
449
- }
450
- // Always add a script component
451
- goContent += `components {
452
- id: "script"
453
- component: "/main/scripts/${name}.script"
454
- position {
455
- x: 0.0
456
- y: 0.0
457
- z: 0.0
458
- }
459
- rotation {
460
- x: 0.0
461
- y: 0.0
462
- z: 0.0
463
- w: 1.0
464
- }
465
- }
373
+ this.addTextFile(`main/scenes/${sceneName}.collection`, collectionContent);
374
+ for (const entity of scene.entities) {
375
+ await this.generateGameObject(entity, options);
376
+ }
377
+ const sceneScript = this.generateSceneScript(scene, project);
378
+ this.addTextFile(`main/scripts/${sceneName}_controller.script`, sceneScript);
379
+ }
380
+ entityToEmbeddedInstance(entity) {
381
+ const name = (entity.name ?? entity.id).toLowerCase().replace(/[^a-z0-9_]/g, "_");
382
+ const pos = entity.position ?? { x: 0, y: 0 };
383
+ const scale = entity.scale ?? { x: 1, y: 1 };
384
+ const rotation = entity.rotation ?? 0;
385
+ const radians = rotation * Math.PI / 180;
386
+ const qz = Math.sin(radians / 2);
387
+ const qw = Math.cos(radians / 2);
388
+ return `embedded_instances {
389
+ id: "${name}"
390
+ data: ""
391
+ position {
392
+ x: ${pos.x}
393
+ y: ${pos.y}
394
+ z: 0.0
395
+ }
396
+ rotation {
397
+ x: 0.0
398
+ y: 0.0
399
+ z: ${qz.toFixed(6)}
400
+ w: ${qw.toFixed(6)}
401
+ }
402
+ scale3 {
403
+ x: ${scale.x}
404
+ y: ${scale.y}
405
+ z: 1.0
406
+ }
407
+ }
466
408
  `;
467
- this.addTextFile(`main/go/${name}.go`, goContent);
468
- // Generate entity script
469
- const entityScript = this.generateEntityScript(entity);
470
- this.addTextFile(`main/scripts/${name}.script`, entityScript);
471
- // Generate sprite definition if has sprite component
472
- const hasSprite = entity.components.some((c) => c.type === 'sprite');
473
- if (hasSprite) {
474
- await this.generateSpriteDefinition(entity);
475
- }
476
- // Generate collision object if has physics
477
- const hasPhysics = entity.components.some((c) => c.type === 'rigidbody' || c.type.includes('Collider'));
478
- if (hasPhysics) {
479
- await this.generateCollisionObject(entity);
480
- }
409
+ }
410
+ async generateGameObject(entity, _options) {
411
+ const name = (entity.name ?? entity.id).toLowerCase().replace(/[^a-z0-9_]/g, "_");
412
+ let goContent = "";
413
+ for (const comp of entity.components) {
414
+ const mapper = DEFOLD_COMPONENT_MAP[comp.type];
415
+ if (mapper) {
416
+ goContent += mapper(comp, entity) + "\n";
417
+ }
481
418
  }
482
- generateEntityScript(entity) {
483
- const name = entity.name ?? entity.id;
484
- const tags = entity.tags ?? [];
485
- return `-- ${name} Entity Script
486
- -- Generated from Nice2Dev
487
-
488
- -- Properties
489
- go.property("speed", ${this.getComponentProperty(entity, 'movement', 'speed', 200)})
490
- go.property("health", ${this.getComponentProperty(entity, 'health', 'max', 100)})
491
- go.property("max_health", ${this.getComponentProperty(entity, 'health', 'max', 100)})
492
-
493
- -- Tags: ${tags.join(', ') || 'none'}
494
-
495
- -- Initialize
496
- function init(self)
497
- self.velocity = vmath.vector3(0, 0, 0)
498
- self.is_alive = true
499
- self.tags = {${tags.map((t) => `["${t}"] = true`).join(', ')}}
500
-
501
- -- Register with game manager
502
- msg.post("/game_manager#game_manager", "register_entity", {
503
- id = go.get_id(),
504
- name = "${name}",
505
- tags = self.tags,
506
- })
507
- end
508
-
509
- -- Update (called every frame)
510
- function update(self, dt)
511
- if not self.is_alive then return end
512
-
513
- -- Apply velocity
514
- if vmath.length(self.velocity) > 0 then
515
- local pos = go.get_position()
516
- pos = pos + self.velocity * dt
517
- go.set_position(pos)
518
- end
519
- end
520
-
521
- -- Fixed update (physics)
522
- function fixed_update(self, dt)
523
- -- Physics updates here
524
- end
525
-
526
- -- Handle messages
527
- function on_message(self, message_id, message, sender)
528
- if message_id == hash("take_damage") then
529
- self.health = self.health - (message.amount or 10)
530
- if self.health <= 0 then
531
- self:die()
532
- end
533
- elseif message_id == hash("heal") then
534
- self.health = math.min(self.health + (message.amount or 10), self.max_health)
535
- elseif message_id == hash("set_velocity") then
536
- self.velocity = message.velocity or vmath.vector3(0, 0, 0)
537
- elseif message_id == hash("destroy") then
538
- self:die()
539
- end
540
- end
541
-
542
- -- Handle input (if enabled)
543
- function on_input(self, action_id, action)
544
- -- Input handling here
545
- return false
546
- end
547
-
548
- -- Cleanup
549
- function final(self)
550
- msg.post("/game_manager#game_manager", "unregister_entity", {
551
- id = go.get_id(),
552
- })
553
- end
554
-
555
- -- Custom methods
556
- function die(self)
557
- self.is_alive = false
558
- -- Play death animation/effect
559
- -- Then delete
560
- go.delete()
561
- end
562
-
563
- function has_tag(self, tag)
564
- return self.tags[tag] == true
565
- end
419
+ goContent += `components {
420
+ id: "script"
421
+ component: "/main/scripts/${name}.script"
422
+ position {
423
+ x: 0.0
424
+ y: 0.0
425
+ z: 0.0
426
+ }
427
+ rotation {
428
+ x: 0.0
429
+ y: 0.0
430
+ z: 0.0
431
+ w: 1.0
432
+ }
433
+ }
566
434
  `;
435
+ this.addTextFile(`main/go/${name}.go`, goContent);
436
+ const entityScript = this.generateEntityScript(entity);
437
+ this.addTextFile(`main/scripts/${name}.script`, entityScript);
438
+ const hasSprite = entity.components.some((c) => c.type === "sprite");
439
+ if (hasSprite) {
440
+ await this.generateSpriteDefinition(entity);
567
441
  }
568
- getComponentProperty(entity, componentType, property, defaultValue) {
569
- const comp = entity.components.find((c) => c.type === componentType);
570
- if (comp && comp.properties && property in comp.properties) {
571
- return comp.properties[property];
572
- }
573
- return defaultValue;
442
+ const hasPhysics = entity.components.some(
443
+ (c) => c.type === "rigidbody" || c.type.includes("Collider")
444
+ );
445
+ if (hasPhysics) {
446
+ await this.generateCollisionObject(entity);
574
447
  }
575
- async generateSpriteDefinition(entity) {
576
- const name = (entity.name ?? entity.id).toLowerCase().replace(/[^a-z0-9_]/g, '_');
577
- const spriteContent = `tile_set: "/main/atlases/main.atlas"
578
- default_animation: "default"
579
- material: "/builtins/materials/sprite.material"
580
- blend_mode: BLEND_MODE_ALPHA
448
+ }
449
+ generateEntityScript(entity) {
450
+ const name = entity.name ?? entity.id;
451
+ const tags = entity.tags ?? [];
452
+ return `-- ${name} Entity Script
453
+ -- Generated from Nice2Dev
454
+
455
+ -- Properties
456
+ go.property("speed", ${this.getComponentProperty(entity, "movement", "speed", 200)})
457
+ go.property("health", ${this.getComponentProperty(entity, "health", "max", 100)})
458
+ go.property("max_health", ${this.getComponentProperty(entity, "health", "max", 100)})
459
+
460
+ -- Tags: ${tags.join(", ") || "none"}
461
+
462
+ -- Initialize
463
+ function init(self)
464
+ self.velocity = vmath.vector3(0, 0, 0)
465
+ self.is_alive = true
466
+ self.tags = {${tags.map((t) => `["${t}"] = true`).join(", ")}}
467
+
468
+ -- Register with game manager
469
+ msg.post("/game_manager#game_manager", "register_entity", {
470
+ id = go.get_id(),
471
+ name = "${name}",
472
+ tags = self.tags,
473
+ })
474
+ end
475
+
476
+ -- Update (called every frame)
477
+ function update(self, dt)
478
+ if not self.is_alive then return end
479
+
480
+ -- Apply velocity
481
+ if vmath.length(self.velocity) > 0 then
482
+ local pos = go.get_position()
483
+ pos = pos + self.velocity * dt
484
+ go.set_position(pos)
485
+ end
486
+ end
487
+
488
+ -- Fixed update (physics)
489
+ function fixed_update(self, dt)
490
+ -- Physics updates here
491
+ end
492
+
493
+ -- Handle messages
494
+ function on_message(self, message_id, message, sender)
495
+ if message_id == hash("take_damage") then
496
+ self.health = self.health - (message.amount or 10)
497
+ if self.health <= 0 then
498
+ self:die()
499
+ end
500
+ elseif message_id == hash("heal") then
501
+ self.health = math.min(self.health + (message.amount or 10), self.max_health)
502
+ elseif message_id == hash("set_velocity") then
503
+ self.velocity = message.velocity or vmath.vector3(0, 0, 0)
504
+ elseif message_id == hash("destroy") then
505
+ self:die()
506
+ end
507
+ end
508
+
509
+ -- Handle input (if enabled)
510
+ function on_input(self, action_id, action)
511
+ -- Input handling here
512
+ return false
513
+ end
514
+
515
+ -- Cleanup
516
+ function final(self)
517
+ msg.post("/game_manager#game_manager", "unregister_entity", {
518
+ id = go.get_id(),
519
+ })
520
+ end
521
+
522
+ -- Custom methods
523
+ function die(self)
524
+ self.is_alive = false
525
+ -- Play death animation/effect
526
+ -- Then delete
527
+ go.delete()
528
+ end
529
+
530
+ function has_tag(self, tag)
531
+ return self.tags[tag] == true
532
+ end
581
533
  `;
582
- this.addTextFile(`main/sprites/${name}.sprite`, spriteContent);
534
+ }
535
+ getComponentProperty(entity, componentType, property, defaultValue) {
536
+ const comp = entity.components.find((c) => c.type === componentType);
537
+ if (comp && comp.properties && property in comp.properties) {
538
+ return comp.properties[property];
583
539
  }
584
- async generateCollisionObject(entity) {
585
- const name = (entity.name ?? entity.id).toLowerCase().replace(/[^a-z0-9_]/g, '_');
586
- const hasRigidbody = entity.components.some((c) => c.type === 'rigidbody');
587
- const scale = entity.scale ?? { x: 1, y: 1 };
588
- const collisionContent = `collision_shape: ""
589
- type: ${hasRigidbody ? 'COLLISION_OBJECT_TYPE_DYNAMIC' : 'COLLISION_OBJECT_TYPE_STATIC'}
590
- mass: ${this.getComponentProperty(entity, 'rigidbody', 'mass', 1)}
591
- friction: 0.5
592
- restitution: 0.2
593
- group: "default"
594
- mask: "default"
595
- linear_damping: ${this.getComponentProperty(entity, 'rigidbody', 'linearDamping', 0)}
596
- angular_damping: ${this.getComponentProperty(entity, 'rigidbody', 'angularDamping', 0)}
597
- locked_rotation: false
598
- bullet: false
599
- embedded_collision_shape {
600
- shapes {
601
- shape_type: TYPE_BOX
602
- position {
603
- x: 0.0
604
- y: 0.0
605
- z: 0.0
606
- }
607
- rotation {
608
- x: 0.0
609
- y: 0.0
610
- z: 0.0
611
- w: 1.0
612
- }
613
- index: 0
614
- count: 3
615
- }
616
- data: ${32 * scale.x}
617
- data: ${32 * scale.y}
618
- data: 0.0
619
- }
540
+ return defaultValue;
541
+ }
542
+ async generateSpriteDefinition(entity) {
543
+ const name = (entity.name ?? entity.id).toLowerCase().replace(/[^a-z0-9_]/g, "_");
544
+ const spriteContent = `tile_set: "/main/atlases/main.atlas"
545
+ default_animation: "default"
546
+ material: "/builtins/materials/sprite.material"
547
+ blend_mode: BLEND_MODE_ALPHA
620
548
  `;
621
- this.addTextFile(`main/collision/${name}.collisionobject`, collisionContent);
549
+ this.addTextFile(`main/sprites/${name}.sprite`, spriteContent);
550
+ }
551
+ async generateCollisionObject(entity) {
552
+ const name = (entity.name ?? entity.id).toLowerCase().replace(/[^a-z0-9_]/g, "_");
553
+ const hasRigidbody = entity.components.some((c) => c.type === "rigidbody");
554
+ const scale = entity.scale ?? { x: 1, y: 1 };
555
+ const collisionContent = `collision_shape: ""
556
+ type: ${hasRigidbody ? "COLLISION_OBJECT_TYPE_DYNAMIC" : "COLLISION_OBJECT_TYPE_STATIC"}
557
+ mass: ${this.getComponentProperty(entity, "rigidbody", "mass", 1)}
558
+ friction: 0.5
559
+ restitution: 0.2
560
+ group: "default"
561
+ mask: "default"
562
+ linear_damping: ${this.getComponentProperty(entity, "rigidbody", "linearDamping", 0)}
563
+ angular_damping: ${this.getComponentProperty(entity, "rigidbody", "angularDamping", 0)}
564
+ locked_rotation: false
565
+ bullet: false
566
+ embedded_collision_shape {
567
+ shapes {
568
+ shape_type: TYPE_BOX
569
+ position {
570
+ x: 0.0
571
+ y: 0.0
572
+ z: 0.0
622
573
  }
623
- /* ── Prefab Export ──────────────────────────────────────────── */
624
- async exportPrefab(prefab, options) {
625
- // Prefabs in Defold are just regular game objects that can be spawned
626
- await this.generateGameObject(prefab.entity, options);
627
- // Generate factory for spawning
628
- const name = prefab.name.toLowerCase().replace(/[^a-z0-9_]/g, '_');
629
- const factoryContent = `prototype: "/main/go/${name}.go"
630
- load_dynamically: false
631
- `;
632
- this.addTextFile(`main/factories/${name}.factory`, factoryContent);
574
+ rotation {
575
+ x: 0.0
576
+ y: 0.0
577
+ z: 0.0
578
+ w: 1.0
633
579
  }
634
- /* ── Scene Script ───────────────────────────────────────────── */
635
- generateSceneScript(scene, project) {
636
- const sceneName = scene.name;
637
- return `-- ${sceneName} Scene Controller
638
- -- Generated from Nice2Dev
639
-
640
- -- Properties
641
- go.property("music_volume", ${project.settings.audio.masterVolume})
642
- go.property("sfx_volume", 1.0)
643
-
644
- function init(self)
645
- self.entities = {}
646
- self.is_paused = false
647
-
648
- -- Acquire input focus
649
- msg.post(".", "acquire_input_focus")
650
-
651
- print("[Scene] ${sceneName} initialized")
652
- end
653
-
654
- function update(self, dt)
655
- if self.is_paused then return end
656
-
657
- -- Scene update logic
658
- end
659
-
660
- function on_message(self, message_id, message, sender)
661
- if message_id == hash("pause") then
662
- self.is_paused = true
663
- elseif message_id == hash("resume") then
664
- self.is_paused = false
665
- elseif message_id == hash("entity_spawned") then
666
- self.entities[message.id] = message
667
- elseif message_id == hash("entity_destroyed") then
668
- self.entities[message.id] = nil
669
- end
670
- end
671
-
672
- function on_input(self, action_id, action)
673
- if action_id == hash("pause") and action.pressed then
674
- self.is_paused = not self.is_paused
675
- msg.post("/game_manager#game_manager", self.is_paused and "pause" or "resume")
676
- end
677
- return false
678
- end
679
-
680
- function final(self)
681
- msg.post(".", "release_input_focus")
682
- print("[Scene] ${sceneName} finalized")
683
- end
580
+ index: 0
581
+ count: 3
582
+ }
583
+ data: ${32 * scale.x}
584
+ data: ${32 * scale.y}
585
+ data: 0.0
586
+ }
684
587
  `;
685
- }
686
- /* ── Shared Scripts ─────────────────────────────────────────── */
687
- async generateSharedScripts(project, _options) {
688
- // Game Manager Script
689
- const gameManagerScript = `-- Game Manager
690
- -- Central game state and utility management
691
- -- Generated from Nice2Dev
692
-
693
- -- Settings from Nice2Dev project
694
- local SETTINGS = {
695
- game_width = ${project.settings.resolution.width},
696
- game_height = ${project.settings.resolution.height},
697
- master_volume = ${project.settings.audio.masterVolume},
698
- physics_enabled = ${project.settings.physics.enabled},
699
- gravity_x = ${project.settings.physics.gravity.x},
700
- gravity_y = ${project.settings.physics.gravity.y},
701
- }
702
-
703
- -- Game state
704
- local state = {
705
- is_paused = false,
706
- entities = {},
707
- global_variables = {},
708
- current_scene = nil,
709
- }
710
-
711
- function init(self)
712
- self.state = state
713
- self.settings = SETTINGS
714
-
715
- print("[GameManager] Initialized - ${project.name} v${project.version}")
716
- end
717
-
718
- function update(self, dt)
719
- if self.state.is_paused then return end
720
-
721
- -- Global game update
722
- end
723
-
724
- function on_message(self, message_id, message, sender)
725
- if message_id == hash("pause") then
726
- self.state.is_paused = true
727
- print("[GameManager] Game paused")
728
- elseif message_id == hash("resume") then
729
- self.state.is_paused = false
730
- print("[GameManager] Game resumed")
731
- elseif message_id == hash("register_entity") then
732
- self.state.entities[message.id] = {
733
- id = message.id,
734
- name = message.name,
735
- tags = message.tags,
736
- }
737
- elseif message_id == hash("unregister_entity") then
738
- self.state.entities[message.id] = nil
739
- elseif message_id == hash("set_variable") then
740
- self.state.global_variables[message.key] = message.value
741
- elseif message_id == hash("get_variable") then
742
- msg.post(sender, "variable_value", {
743
- key = message.key,
744
- value = self.state.global_variables[message.key],
745
- })
746
- elseif message_id == hash("load_scene") then
747
- self:load_scene(message.scene)
748
- end
749
- end
750
-
751
- function load_scene(self, scene_name)
752
- if self.state.current_scene then
753
- -- Unload current scene
754
- msg.post("#" .. self.state.current_scene, "unload")
755
- end
756
-
757
- -- Load new scene
758
- self.state.current_scene = scene_name
759
- msg.post("#" .. scene_name, "load")
760
-
761
- print("[GameManager] Loaded scene: " .. scene_name)
762
- end
763
-
764
- -- Utility functions accessible via msg
765
- function get_entities_by_tag(self, tag)
766
- local result = {}
767
- for id, entity in pairs(self.state.entities) do
768
- if entity.tags and entity.tags[tag] then
769
- table.insert(result, entity)
770
- end
771
- end
772
- return result
773
- end
588
+ this.addTextFile(`main/collision/${name}.collisionobject`, collisionContent);
589
+ }
590
+ /* ── Prefab Export ──────────────────────────────────────────── */
591
+ async exportPrefab(prefab, options) {
592
+ await this.generateGameObject(prefab.entity, options);
593
+ const name = prefab.name.toLowerCase().replace(/[^a-z0-9_]/g, "_");
594
+ const factoryContent = `prototype: "/main/go/${name}.go"
595
+ load_dynamically: false
774
596
  `;
775
- this.addTextFile('main/scripts/game_manager.script', gameManagerScript);
776
- // Input bindings
777
- const inputBindings = `key_trigger {
778
- input: KEY_SPACE
779
- action: "jump"
780
- }
781
- key_trigger {
782
- input: KEY_W
783
- action: "up"
784
- }
785
- key_trigger {
786
- input: KEY_S
787
- action: "down"
788
- }
789
- key_trigger {
790
- input: KEY_A
791
- action: "left"
792
- }
793
- key_trigger {
794
- input: KEY_D
795
- action: "right"
796
- }
797
- key_trigger {
798
- input: KEY_UP
799
- action: "up"
800
- }
801
- key_trigger {
802
- input: KEY_DOWN
803
- action: "down"
804
- }
805
- key_trigger {
806
- input: KEY_LEFT
807
- action: "left"
808
- }
809
- key_trigger {
810
- input: KEY_RIGHT
811
- action: "right"
812
- }
813
- key_trigger {
814
- input: KEY_ESC
815
- action: "pause"
816
- }
817
- key_trigger {
818
- input: KEY_P
819
- action: "pause"
820
- }
821
- mouse_trigger {
822
- input: MOUSE_BUTTON_LEFT
823
- action: "click"
824
- }
825
- mouse_trigger {
826
- input: MOUSE_BUTTON_RIGHT
827
- action: "right_click"
828
- }
829
- touch_trigger {
830
- input: TOUCH_MULTI
831
- action: "touch"
832
- }
597
+ this.addTextFile(`main/factories/${name}.factory`, factoryContent);
598
+ }
599
+ /* ── Scene Script ───────────────────────────────────────────── */
600
+ generateSceneScript(scene, project) {
601
+ const sceneName = scene.name;
602
+ return `-- ${sceneName} Scene Controller
603
+ -- Generated from Nice2Dev
604
+
605
+ -- Properties
606
+ go.property("music_volume", ${project.settings.audio.masterVolume})
607
+ go.property("sfx_volume", 1.0)
608
+
609
+ function init(self)
610
+ self.entities = {}
611
+ self.is_paused = false
612
+
613
+ -- Acquire input focus
614
+ msg.post(".", "acquire_input_focus")
615
+
616
+ print("[Scene] ${sceneName} initialized")
617
+ end
618
+
619
+ function update(self, dt)
620
+ if self.is_paused then return end
621
+
622
+ -- Scene update logic
623
+ end
624
+
625
+ function on_message(self, message_id, message, sender)
626
+ if message_id == hash("pause") then
627
+ self.is_paused = true
628
+ elseif message_id == hash("resume") then
629
+ self.is_paused = false
630
+ elseif message_id == hash("entity_spawned") then
631
+ self.entities[message.id] = message
632
+ elseif message_id == hash("entity_destroyed") then
633
+ self.entities[message.id] = nil
634
+ end
635
+ end
636
+
637
+ function on_input(self, action_id, action)
638
+ if action_id == hash("pause") and action.pressed then
639
+ self.is_paused = not self.is_paused
640
+ msg.post("/game_manager#game_manager", self.is_paused and "pause" or "resume")
641
+ end
642
+ return false
643
+ end
644
+
645
+ function final(self)
646
+ msg.post(".", "release_input_focus")
647
+ print("[Scene] ${sceneName} finalized")
648
+ end
833
649
  `;
834
- this.addTextFile('input/game.input_binding', inputBindings);
835
- // Main atlas (placeholder)
836
- const atlasContent = `images {
837
- image: "/main/images/placeholder.png"
838
- }
839
- margin: 0
840
- extrude_borders: 2
841
- inner_padding: 0
650
+ }
651
+ /* ── Shared Scripts ─────────────────────────────────────────── */
652
+ async generateSharedScripts(project, _options) {
653
+ const gameManagerScript = `-- Game Manager
654
+ -- Central game state and utility management
655
+ -- Generated from Nice2Dev
656
+
657
+ -- Settings from Nice2Dev project
658
+ local SETTINGS = {
659
+ game_width = ${project.settings.resolution.width},
660
+ game_height = ${project.settings.resolution.height},
661
+ master_volume = ${project.settings.audio.masterVolume},
662
+ physics_enabled = ${project.settings.physics.enabled},
663
+ gravity_x = ${project.settings.physics.gravity.x},
664
+ gravity_y = ${project.settings.physics.gravity.y},
665
+ }
666
+
667
+ -- Game state
668
+ local state = {
669
+ is_paused = false,
670
+ entities = {},
671
+ global_variables = {},
672
+ current_scene = nil,
673
+ }
674
+
675
+ function init(self)
676
+ self.state = state
677
+ self.settings = SETTINGS
678
+
679
+ print("[GameManager] Initialized - ${project.name} v${project.version}")
680
+ end
681
+
682
+ function update(self, dt)
683
+ if self.state.is_paused then return end
684
+
685
+ -- Global game update
686
+ end
687
+
688
+ function on_message(self, message_id, message, sender)
689
+ if message_id == hash("pause") then
690
+ self.state.is_paused = true
691
+ print("[GameManager] Game paused")
692
+ elseif message_id == hash("resume") then
693
+ self.state.is_paused = false
694
+ print("[GameManager] Game resumed")
695
+ elseif message_id == hash("register_entity") then
696
+ self.state.entities[message.id] = {
697
+ id = message.id,
698
+ name = message.name,
699
+ tags = message.tags,
700
+ }
701
+ elseif message_id == hash("unregister_entity") then
702
+ self.state.entities[message.id] = nil
703
+ elseif message_id == hash("set_variable") then
704
+ self.state.global_variables[message.key] = message.value
705
+ elseif message_id == hash("get_variable") then
706
+ msg.post(sender, "variable_value", {
707
+ key = message.key,
708
+ value = self.state.global_variables[message.key],
709
+ })
710
+ elseif message_id == hash("load_scene") then
711
+ self:load_scene(message.scene)
712
+ end
713
+ end
714
+
715
+ function load_scene(self, scene_name)
716
+ if self.state.current_scene then
717
+ -- Unload current scene
718
+ msg.post("#" .. self.state.current_scene, "unload")
719
+ end
720
+
721
+ -- Load new scene
722
+ self.state.current_scene = scene_name
723
+ msg.post("#" .. scene_name, "load")
724
+
725
+ print("[GameManager] Loaded scene: " .. scene_name)
726
+ end
727
+
728
+ -- Utility functions accessible via msg
729
+ function get_entities_by_tag(self, tag)
730
+ local result = {}
731
+ for id, entity in pairs(self.state.entities) do
732
+ if entity.tags and entity.tags[tag] then
733
+ table.insert(result, entity)
734
+ end
735
+ end
736
+ return result
737
+ end
842
738
  `;
843
- this.addTextFile('main/atlases/main.atlas', atlasContent);
844
- // Utility module
845
- const utilityModule = `-- Nice2Dev Utility Module
846
- -- Common utility functions
847
-
848
- local M = {}
849
-
850
- -- Math utilities
851
- function M.lerp(a, b, t)
852
- return a + (b - a) * math.max(0, math.min(1, t))
853
- end
854
-
855
- function M.lerp_vector(a, b, t)
856
- t = math.max(0, math.min(1, t))
857
- return vmath.vector3(
858
- a.x + (b.x - a.x) * t,
859
- a.y + (b.y - a.y) * t,
860
- a.z + (b.z - a.z) * t
861
- )
862
- end
863
-
864
- function M.distance(a, b)
865
- return vmath.length(b - a)
866
- end
867
-
868
- function M.angle_between(a, b)
869
- local diff = b - a
870
- return math.atan2(diff.y, diff.x)
871
- end
872
-
873
- function M.random_range(min, max)
874
- return min + math.random() * (max - min)
875
- end
876
-
877
- function M.random_int(min, max)
878
- return math.random(min, max)
879
- end
880
-
881
- function M.clamp(value, min, max)
882
- return math.max(min, math.min(max, value))
883
- end
884
-
885
- -- Timer utilities
886
- M.timers = {}
887
-
888
- function M.set_timeout(callback, delay)
889
- local id = tostring(socket.gettime())
890
- M.timers[id] = {
891
- callback = callback,
892
- remaining = delay,
893
- repeat_interval = nil,
894
- }
895
- return id
896
- end
897
-
898
- function M.set_interval(callback, interval)
899
- local id = tostring(socket.gettime())
900
- M.timers[id] = {
901
- callback = callback,
902
- remaining = interval,
903
- repeat_interval = interval,
904
- }
905
- return id
906
- end
907
-
908
- function M.clear_timer(id)
909
- M.timers[id] = nil
910
- end
911
-
912
- function M.update_timers(dt)
913
- for id, timer in pairs(M.timers) do
914
- timer.remaining = timer.remaining - dt
915
- if timer.remaining <= 0 then
916
- timer.callback()
917
- if timer.repeat_interval then
918
- timer.remaining = timer.repeat_interval
919
- else
920
- M.timers[id] = nil
921
- end
922
- end
923
- end
924
- end
925
-
926
- -- Spawn utilities
927
- function M.spawn(factory_url, position, properties)
928
- local id = factory.create(factory_url, position, nil, properties)
929
- return id
930
- end
931
-
932
- function M.spawn_at(factory_url, x, y, z, properties)
933
- return M.spawn(factory_url, vmath.vector3(x, y, z or 0), properties)
934
- end
935
-
936
- return M
739
+ this.addTextFile("main/scripts/game_manager.script", gameManagerScript);
740
+ const inputBindings = `key_trigger {
741
+ input: KEY_SPACE
742
+ action: "jump"
743
+ }
744
+ key_trigger {
745
+ input: KEY_W
746
+ action: "up"
747
+ }
748
+ key_trigger {
749
+ input: KEY_S
750
+ action: "down"
751
+ }
752
+ key_trigger {
753
+ input: KEY_A
754
+ action: "left"
755
+ }
756
+ key_trigger {
757
+ input: KEY_D
758
+ action: "right"
759
+ }
760
+ key_trigger {
761
+ input: KEY_UP
762
+ action: "up"
763
+ }
764
+ key_trigger {
765
+ input: KEY_DOWN
766
+ action: "down"
767
+ }
768
+ key_trigger {
769
+ input: KEY_LEFT
770
+ action: "left"
771
+ }
772
+ key_trigger {
773
+ input: KEY_RIGHT
774
+ action: "right"
775
+ }
776
+ key_trigger {
777
+ input: KEY_ESC
778
+ action: "pause"
779
+ }
780
+ key_trigger {
781
+ input: KEY_P
782
+ action: "pause"
783
+ }
784
+ mouse_trigger {
785
+ input: MOUSE_BUTTON_LEFT
786
+ action: "click"
787
+ }
788
+ mouse_trigger {
789
+ input: MOUSE_BUTTON_RIGHT
790
+ action: "right_click"
791
+ }
792
+ touch_trigger {
793
+ input: TOUCH_MULTI
794
+ action: "touch"
795
+ }
937
796
  `;
938
- this.addTextFile('main/scripts/utility.lua', utilityModule);
939
- }
940
- /* ── App Manifest ───────────────────────────────────────────── */
941
- async generateAppManifest(_project, _options) {
942
- const manifest = `platforms:
943
- x86_64-osx:
944
- context:
945
- excludeLibs: []
946
- excludeSymbols: []
947
- symbols: []
948
- libs: []
949
- linkFlags: []
950
- x86_64-linux:
951
- context:
952
- excludeLibs: []
953
- excludeSymbols: []
954
- symbols: []
955
- libs: []
956
- linkFlags: []
957
- js-web:
958
- context:
959
- excludeLibs: []
960
- excludeJsLibs: []
961
- excludeSymbols: []
962
- symbols: []
963
- libs: []
964
- linkFlags: []
965
- wasm-web:
966
- context:
967
- excludeLibs: []
968
- excludeJsLibs: []
969
- excludeSymbols: []
970
- symbols: []
971
- libs: []
972
- linkFlags: []
973
- x86-win32:
974
- context:
975
- excludeLibs: []
976
- excludeSymbols: []
977
- symbols: []
978
- libs: []
979
- linkFlags: []
980
- x86_64-win32:
981
- context:
982
- excludeLibs: []
983
- excludeSymbols: []
984
- symbols: []
985
- libs: []
986
- linkFlags: []
987
- armv7-android:
988
- context:
989
- excludeLibs: []
990
- excludeJars: []
991
- excludeSymbols: []
992
- symbols: []
993
- libs: []
994
- linkFlags: []
995
- jetifier: true
996
- arm64-android:
997
- context:
998
- excludeLibs: []
999
- excludeJars: []
1000
- excludeSymbols: []
1001
- symbols: []
1002
- libs: []
1003
- linkFlags: []
1004
- jetifier: true
1005
- armv7-ios:
1006
- context:
1007
- excludeLibs: []
1008
- excludeSymbols: []
1009
- symbols: []
1010
- libs: []
1011
- linkFlags: []
1012
- arm64-ios:
1013
- context:
1014
- excludeLibs: []
1015
- excludeSymbols: []
1016
- symbols: []
1017
- libs: []
1018
- linkFlags: []
1019
- x86_64-ios:
1020
- context:
1021
- excludeLibs: []
1022
- excludeSymbols: []
1023
- symbols: []
1024
- libs: []
1025
- linkFlags: []
797
+ this.addTextFile("input/game.input_binding", inputBindings);
798
+ const atlasContent = `images {
799
+ image: "/main/images/placeholder.png"
800
+ }
801
+ margin: 0
802
+ extrude_borders: 2
803
+ inner_padding: 0
1026
804
  `;
1027
- this.addTextFile('app.manifest', manifest);
805
+ this.addTextFile("main/atlases/main.atlas", atlasContent);
806
+ const utilityModule = `-- Nice2Dev Utility Module
807
+ -- Common utility functions
808
+
809
+ local M = {}
810
+
811
+ -- Math utilities
812
+ function M.lerp(a, b, t)
813
+ return a + (b - a) * math.max(0, math.min(1, t))
814
+ end
815
+
816
+ function M.lerp_vector(a, b, t)
817
+ t = math.max(0, math.min(1, t))
818
+ return vmath.vector3(
819
+ a.x + (b.x - a.x) * t,
820
+ a.y + (b.y - a.y) * t,
821
+ a.z + (b.z - a.z) * t
822
+ )
823
+ end
824
+
825
+ function M.distance(a, b)
826
+ return vmath.length(b - a)
827
+ end
828
+
829
+ function M.angle_between(a, b)
830
+ local diff = b - a
831
+ return math.atan2(diff.y, diff.x)
832
+ end
833
+
834
+ function M.random_range(min, max)
835
+ return min + math.random() * (max - min)
836
+ end
837
+
838
+ function M.random_int(min, max)
839
+ return math.random(min, max)
840
+ end
841
+
842
+ function M.clamp(value, min, max)
843
+ return math.max(min, math.min(max, value))
844
+ end
845
+
846
+ -- Timer utilities
847
+ M.timers = {}
848
+
849
+ function M.set_timeout(callback, delay)
850
+ local id = tostring(socket.gettime())
851
+ M.timers[id] = {
852
+ callback = callback,
853
+ remaining = delay,
854
+ repeat_interval = nil,
1028
855
  }
1029
- /* ── README ─────────────────────────────────────────────────── */
1030
- async generateReadme(project, _options) {
1031
- const readme = `# ${project.name} - Defold Export
1032
-
1033
- Generated from Nice2Dev project v${project.version}
1034
-
1035
- ## Installation
1036
-
1037
- 1. Install Defold Editor from https://defold.com/
1038
- 2. Open Defold and create a new project from this folder
1039
- 3. Or copy contents to existing project
1040
-
1041
- ## Project Structure
1042
-
1043
- - \`game.project\` - Main project configuration
1044
- - \`main/main.collection\` - Bootstrap collection
1045
- - \`main/scenes/\` - Scene collections
1046
- - \`main/go/\` - Game object definitions
1047
- - \`main/scripts/\` - Lua scripts
1048
- - \`main/sprites/\` - Sprite definitions
1049
- - \`main/collision/\` - Collision objects
1050
- - \`main/factories/\` - Factory components (for spawning)
1051
- - \`main/atlases/\` - Texture atlases
1052
- - \`input/\` - Input bindings
1053
-
1054
- ## Scenes
1055
-
1056
- ${project.scenes.map((s) => `- ${s.name} (${s.entities.length} entities)`).join('\n')}
1057
-
1058
- ## Key Scripts
1059
-
1060
- ### game_manager.script
1061
- Central game state management:
1062
- - Pause/Resume handling
1063
- - Entity registration
1064
- - Global variables
1065
- - Scene loading
1066
-
1067
- ### utility.lua
1068
- Common utility functions:
1069
- - Math helpers (lerp, distance, clamp)
1070
- - Timer system (setTimeout, setInterval)
1071
- - Spawn utilities
1072
-
1073
- ## Input Bindings
1074
-
1075
- - WASD / Arrow Keys: Movement
1076
- - Space: Jump
1077
- - P / Escape: Pause
1078
- - Mouse: Click, Right-click
1079
- - Touch: Multi-touch support
1080
-
1081
- ## Notes
1082
-
1083
- - Add your textures to \`main/images/\` and update atlases
1084
- - Configure physics in \`game.project\` [physics] section
1085
- - Adjust collision groups as needed
1086
-
1087
- ## Settings
1088
-
1089
- - Resolution: ${project.settings.resolution.width}x${project.settings.resolution.height}
1090
- - Physics: ${project.settings.physics.enabled ? 'Enabled' : 'Disabled'}
1091
- - Gravity: (${project.settings.physics.gravity.x}, ${project.settings.physics.gravity.y})
1092
- - Master Volume: ${project.settings.audio.masterVolume}
1093
- `;
1094
- this.addTextFile('README.md', readme);
856
+ return id
857
+ end
858
+
859
+ function M.set_interval(callback, interval)
860
+ local id = tostring(socket.gettime())
861
+ M.timers[id] = {
862
+ callback = callback,
863
+ remaining = interval,
864
+ repeat_interval = interval,
1095
865
  }
866
+ return id
867
+ end
868
+
869
+ function M.clear_timer(id)
870
+ M.timers[id] = nil
871
+ end
872
+
873
+ function M.update_timers(dt)
874
+ for id, timer in pairs(M.timers) do
875
+ timer.remaining = timer.remaining - dt
876
+ if timer.remaining <= 0 then
877
+ timer.callback()
878
+ if timer.repeat_interval then
879
+ timer.remaining = timer.repeat_interval
880
+ else
881
+ M.timers[id] = nil
882
+ end
883
+ end
884
+ end
885
+ end
886
+
887
+ -- Spawn utilities
888
+ function M.spawn(factory_url, position, properties)
889
+ local id = factory.create(factory_url, position, nil, properties)
890
+ return id
891
+ end
892
+
893
+ function M.spawn_at(factory_url, x, y, z, properties)
894
+ return M.spawn(factory_url, vmath.vector3(x, y, z or 0), properties)
895
+ end
896
+
897
+ return M
898
+ `;
899
+ this.addTextFile("main/scripts/utility.lua", utilityModule);
900
+ }
901
+ /* ── App Manifest ───────────────────────────────────────────── */
902
+ async generateAppManifest(_project, _options) {
903
+ const manifest = `platforms:
904
+ x86_64-osx:
905
+ context:
906
+ excludeLibs: []
907
+ excludeSymbols: []
908
+ symbols: []
909
+ libs: []
910
+ linkFlags: []
911
+ x86_64-linux:
912
+ context:
913
+ excludeLibs: []
914
+ excludeSymbols: []
915
+ symbols: []
916
+ libs: []
917
+ linkFlags: []
918
+ js-web:
919
+ context:
920
+ excludeLibs: []
921
+ excludeJsLibs: []
922
+ excludeSymbols: []
923
+ symbols: []
924
+ libs: []
925
+ linkFlags: []
926
+ wasm-web:
927
+ context:
928
+ excludeLibs: []
929
+ excludeJsLibs: []
930
+ excludeSymbols: []
931
+ symbols: []
932
+ libs: []
933
+ linkFlags: []
934
+ x86-win32:
935
+ context:
936
+ excludeLibs: []
937
+ excludeSymbols: []
938
+ symbols: []
939
+ libs: []
940
+ linkFlags: []
941
+ x86_64-win32:
942
+ context:
943
+ excludeLibs: []
944
+ excludeSymbols: []
945
+ symbols: []
946
+ libs: []
947
+ linkFlags: []
948
+ armv7-android:
949
+ context:
950
+ excludeLibs: []
951
+ excludeJars: []
952
+ excludeSymbols: []
953
+ symbols: []
954
+ libs: []
955
+ linkFlags: []
956
+ jetifier: true
957
+ arm64-android:
958
+ context:
959
+ excludeLibs: []
960
+ excludeJars: []
961
+ excludeSymbols: []
962
+ symbols: []
963
+ libs: []
964
+ linkFlags: []
965
+ jetifier: true
966
+ armv7-ios:
967
+ context:
968
+ excludeLibs: []
969
+ excludeSymbols: []
970
+ symbols: []
971
+ libs: []
972
+ linkFlags: []
973
+ arm64-ios:
974
+ context:
975
+ excludeLibs: []
976
+ excludeSymbols: []
977
+ symbols: []
978
+ libs: []
979
+ linkFlags: []
980
+ x86_64-ios:
981
+ context:
982
+ excludeLibs: []
983
+ excludeSymbols: []
984
+ symbols: []
985
+ libs: []
986
+ linkFlags: []
987
+ `;
988
+ this.addTextFile("app.manifest", manifest);
989
+ }
990
+ /* ── README ─────────────────────────────────────────────────── */
991
+ async generateReadme(project, _options) {
992
+ const readme = `# ${project.name} - Defold Export
993
+
994
+ Generated from Nice2Dev project v${project.version}
995
+
996
+ ## Installation
997
+
998
+ 1. Install Defold Editor from https://defold.com/
999
+ 2. Open Defold and create a new project from this folder
1000
+ 3. Or copy contents to existing project
1001
+
1002
+ ## Project Structure
1003
+
1004
+ - \`game.project\` - Main project configuration
1005
+ - \`main/main.collection\` - Bootstrap collection
1006
+ - \`main/scenes/\` - Scene collections
1007
+ - \`main/go/\` - Game object definitions
1008
+ - \`main/scripts/\` - Lua scripts
1009
+ - \`main/sprites/\` - Sprite definitions
1010
+ - \`main/collision/\` - Collision objects
1011
+ - \`main/factories/\` - Factory components (for spawning)
1012
+ - \`main/atlases/\` - Texture atlases
1013
+ - \`input/\` - Input bindings
1014
+
1015
+ ## Scenes
1016
+
1017
+ ${project.scenes.map((s) => `- ${s.name} (${s.entities.length} entities)`).join("\n")}
1018
+
1019
+ ## Key Scripts
1020
+
1021
+ ### game_manager.script
1022
+ Central game state management:
1023
+ - Pause/Resume handling
1024
+ - Entity registration
1025
+ - Global variables
1026
+ - Scene loading
1027
+
1028
+ ### utility.lua
1029
+ Common utility functions:
1030
+ - Math helpers (lerp, distance, clamp)
1031
+ - Timer system (setTimeout, setInterval)
1032
+ - Spawn utilities
1033
+
1034
+ ## Input Bindings
1035
+
1036
+ - WASD / Arrow Keys: Movement
1037
+ - Space: Jump
1038
+ - P / Escape: Pause
1039
+ - Mouse: Click, Right-click
1040
+ - Touch: Multi-touch support
1041
+
1042
+ ## Notes
1043
+
1044
+ - Add your textures to \`main/images/\` and update atlases
1045
+ - Configure physics in \`game.project\` [physics] section
1046
+ - Adjust collision groups as needed
1047
+
1048
+ ## Settings
1049
+
1050
+ - Resolution: ${project.settings.resolution.width}x${project.settings.resolution.height}
1051
+ - Physics: ${project.settings.physics.enabled ? "Enabled" : "Disabled"}
1052
+ - Gravity: (${project.settings.physics.gravity.x}, ${project.settings.physics.gravity.y})
1053
+ - Master Volume: ${project.settings.audio.masterVolume}
1054
+ `;
1055
+ this.addTextFile("README.md", readme);
1056
+ }
1096
1057
  }
1097
- /* ── Factory ──────────────────────────────────────────────────── */
1098
1058
  function createDefoldExporter() {
1099
- return new DefoldExporter();
1059
+ return new DefoldExporter();
1100
1060
  }
1101
-
1102
- export { DefoldExporter, createDefoldExporter };
1061
+ export {
1062
+ DefoldExporter,
1063
+ createDefoldExporter
1064
+ };