@nice2dev/game-engine 1.0.4 → 1.0.10

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 (721) hide show
  1. package/dist/cjs/accessibility/Accessibility.js +55 -20
  2. package/dist/cjs/accessibility/Accessibility.js.map +1 -1
  3. package/dist/cjs/ai/AI.js +74 -40
  4. package/dist/cjs/ai/AI.js.map +1 -1
  5. package/dist/cjs/ai/BehaviorTree.js +39 -47
  6. package/dist/cjs/ai/BehaviorTree.js.map +1 -1
  7. package/dist/cjs/ai/StateMachine.js +64 -100
  8. package/dist/cjs/ai/StateMachine.js.map +1 -1
  9. package/dist/cjs/animation/Animation.js +58 -34
  10. package/dist/cjs/animation/Animation.js.map +1 -1
  11. package/dist/cjs/audio/AudioAdvanced.js +71 -37
  12. package/dist/cjs/audio/AudioAdvanced.js.map +1 -1
  13. package/dist/cjs/audio/AudioBridge.js +61 -49
  14. package/dist/cjs/audio/AudioBridge.js.map +1 -1
  15. package/dist/cjs/audio/AudioManager.js +45 -29
  16. package/dist/cjs/audio/AudioManager.js.map +1 -1
  17. package/dist/cjs/build-cloud/BuildOrchestration.js +1142 -0
  18. package/dist/cjs/build-cloud/BuildOrchestration.js.map +1 -0
  19. package/dist/cjs/build-cloud/GodotBuildCloud.js +722 -0
  20. package/dist/cjs/build-cloud/GodotBuildCloud.js.map +1 -0
  21. package/dist/cjs/build-cloud/UnityBuildCloud.js +652 -0
  22. package/dist/cjs/build-cloud/UnityBuildCloud.js.map +1 -0
  23. package/dist/cjs/build-cloud/UnrealBuildCloud.js +674 -0
  24. package/dist/cjs/build-cloud/UnrealBuildCloud.js.map +1 -0
  25. package/dist/cjs/core/EventBus.js +2 -1
  26. package/dist/cjs/core/EventBus.js.map +1 -1
  27. package/dist/cjs/core/GameConfig.js +1 -1
  28. package/dist/cjs/core/GameConfig.js.map +1 -1
  29. package/dist/cjs/core/GameLoop.js +6 -3
  30. package/dist/cjs/core/GameLoop.js.map +1 -1
  31. package/dist/cjs/core/ServiceLocator.js +1 -2
  32. package/dist/cjs/core/ServiceLocator.js.map +1 -1
  33. package/dist/cjs/devtools/DevTools.js +73 -43
  34. package/dist/cjs/devtools/DevTools.js.map +1 -1
  35. package/dist/cjs/devtools/DeveloperExperience.js +84 -42
  36. package/dist/cjs/devtools/DeveloperExperience.js.map +1 -1
  37. package/dist/cjs/devtools/GameplayAnalytics.js +71 -43
  38. package/dist/cjs/devtools/GameplayAnalytics.js.map +1 -1
  39. package/dist/cjs/dialogue/DialogueSystem.js +153 -129
  40. package/dist/cjs/dialogue/DialogueSystem.js.map +1 -1
  41. package/dist/cjs/docs/DocGenerator.js +70 -28
  42. package/dist/cjs/docs/DocGenerator.js.map +1 -1
  43. package/dist/cjs/ecs/World.js +159 -33
  44. package/dist/cjs/ecs/World.js.map +1 -1
  45. package/dist/cjs/editor/AchievementEditor.js +650 -0
  46. package/dist/cjs/editor/AchievementEditor.js.map +1 -0
  47. package/dist/cjs/editor/AdvancedEditor.js +95 -23
  48. package/dist/cjs/editor/AdvancedEditor.js.map +1 -1
  49. package/dist/cjs/editor/AnimationRetargeting.js +742 -0
  50. package/dist/cjs/editor/AnimationRetargeting.js.map +1 -0
  51. package/dist/cjs/editor/AssetBrowser.js +1191 -0
  52. package/dist/cjs/editor/AssetBrowser.js.map +1 -0
  53. package/dist/cjs/editor/AssetManager.js +22 -14
  54. package/dist/cjs/editor/AssetManager.js.map +1 -1
  55. package/dist/cjs/editor/ConsolePro.js +1092 -0
  56. package/dist/cjs/editor/ConsolePro.js.map +1 -0
  57. package/dist/cjs/editor/CraftingEditor.js +749 -0
  58. package/dist/cjs/editor/CraftingEditor.js.map +1 -0
  59. package/dist/cjs/editor/DebugTools.js +46 -23
  60. package/dist/cjs/editor/DebugTools.js.map +1 -1
  61. package/dist/cjs/editor/DialogueSystem.js +924 -0
  62. package/dist/cjs/editor/DialogueSystem.js.map +1 -0
  63. package/dist/cjs/editor/LeaderboardSystem.js +496 -0
  64. package/dist/cjs/editor/LeaderboardSystem.js.map +1 -0
  65. package/dist/cjs/editor/NiceGameEditor.js +532 -142
  66. package/dist/cjs/editor/NiceGameEditor.js.map +1 -1
  67. package/dist/cjs/editor/PrefabSystem.js +864 -0
  68. package/dist/cjs/editor/PrefabSystem.js.map +1 -0
  69. package/dist/cjs/editor/ProfilerPanel.js +716 -0
  70. package/dist/cjs/editor/ProfilerPanel.js.map +1 -0
  71. package/dist/cjs/editor/QuestEditor.js +850 -0
  72. package/dist/cjs/editor/QuestEditor.js.map +1 -0
  73. package/dist/cjs/editor/ReplaySystem.js +655 -0
  74. package/dist/cjs/editor/ReplaySystem.js.map +1 -0
  75. package/dist/cjs/editor/SceneEditor.js +33 -13
  76. package/dist/cjs/editor/SceneEditor.js.map +1 -1
  77. package/dist/cjs/editor/ScreenshotMode.js +710 -0
  78. package/dist/cjs/editor/ScreenshotMode.js.map +1 -0
  79. package/dist/cjs/editor/ShaderGraph.js +7 -6
  80. package/dist/cjs/editor/ShaderGraph.js.map +1 -1
  81. package/dist/cjs/editor/TimelineEditor.js +36 -30
  82. package/dist/cjs/editor/TimelineEditor.js.map +1 -1
  83. package/dist/cjs/editor/UndoRedoPro.js +920 -0
  84. package/dist/cjs/editor/UndoRedoPro.js.map +1 -0
  85. package/dist/cjs/editor/VRARMode.js +658 -0
  86. package/dist/cjs/editor/VRARMode.js.map +1 -0
  87. package/dist/cjs/engine/NiceGameEngine.js +12 -10
  88. package/dist/cjs/engine/NiceGameEngine.js.map +1 -1
  89. package/dist/cjs/engine/SaveSystemV2.js +73 -37
  90. package/dist/cjs/engine/SaveSystemV2.js.map +1 -1
  91. package/dist/cjs/enterprise/Enterprise.js +92 -44
  92. package/dist/cjs/enterprise/Enterprise.js.map +1 -1
  93. package/dist/cjs/export/BevyExporter.js +998 -0
  94. package/dist/cjs/export/BevyExporter.js.map +1 -0
  95. package/dist/cjs/export/CocosExporter.js +706 -0
  96. package/dist/cjs/export/CocosExporter.js.map +1 -0
  97. package/dist/cjs/export/Construct3Exporter.js +832 -0
  98. package/dist/cjs/export/Construct3Exporter.js.map +1 -0
  99. package/dist/cjs/export/DefoldExporter.js +1106 -0
  100. package/dist/cjs/export/DefoldExporter.js.map +1 -0
  101. package/dist/cjs/export/GDevelopExporter.js +748 -0
  102. package/dist/cjs/export/GDevelopExporter.js.map +1 -0
  103. package/dist/cjs/export/GameMakerExporter.js +846 -0
  104. package/dist/cjs/export/GameMakerExporter.js.map +1 -0
  105. package/dist/cjs/export/GodotExporter.js +45 -50
  106. package/dist/cjs/export/GodotExporter.js.map +1 -1
  107. package/dist/cjs/export/MinecraftBedrockExporter.js +606 -0
  108. package/dist/cjs/export/MinecraftBedrockExporter.js.map +1 -0
  109. package/dist/cjs/export/MonoGameExporter.js +1334 -0
  110. package/dist/cjs/export/MonoGameExporter.js.map +1 -0
  111. package/dist/cjs/export/Pico8Exporter.js +846 -0
  112. package/dist/cjs/export/Pico8Exporter.js.map +1 -0
  113. package/dist/cjs/export/PlatformExporter.js +4 -5
  114. package/dist/cjs/export/PlatformExporter.js.map +1 -1
  115. package/dist/cjs/export/RPGMakerExporter.js +906 -0
  116. package/dist/cjs/export/RPGMakerExporter.js.map +1 -0
  117. package/dist/cjs/export/RobloxExporter.js +943 -0
  118. package/dist/cjs/export/RobloxExporter.js.map +1 -0
  119. package/dist/cjs/export/Solar2DExporter.js +1283 -0
  120. package/dist/cjs/export/Solar2DExporter.js.map +1 -0
  121. package/dist/cjs/export/ThreeJSExporter.js +52 -55
  122. package/dist/cjs/export/ThreeJSExporter.js.map +1 -1
  123. package/dist/cjs/export/Tic80Exporter.js +1315 -0
  124. package/dist/cjs/export/Tic80Exporter.js.map +1 -0
  125. package/dist/cjs/export/UnityExporter.js +41 -56
  126. package/dist/cjs/export/UnityExporter.js.map +1 -1
  127. package/dist/cjs/export/UnrealExporter.js +962 -0
  128. package/dist/cjs/export/UnrealExporter.js.map +1 -0
  129. package/dist/cjs/export/WebExporter.js +42 -50
  130. package/dist/cjs/export/WebExporter.js.map +1 -1
  131. package/dist/cjs/export/index.js +50 -2
  132. package/dist/cjs/export/index.js.map +1 -1
  133. package/dist/cjs/godot-integration/GodotAssetLibrary.js +716 -0
  134. package/dist/cjs/godot-integration/GodotAssetLibrary.js.map +1 -0
  135. package/dist/cjs/godot-integration/GodotImport.js +1069 -0
  136. package/dist/cjs/godot-integration/GodotImport.js.map +1 -0
  137. package/dist/cjs/godot-integration/GodotLiveLink.js +962 -0
  138. package/dist/cjs/godot-integration/GodotLiveLink.js.map +1 -0
  139. package/dist/cjs/godot-integration/components/GodotProjectBrowser.js +668 -0
  140. package/dist/cjs/godot-integration/components/GodotProjectBrowser.js.map +1 -0
  141. package/dist/cjs/i18n/I18n.js +56 -30
  142. package/dist/cjs/i18n/I18n.js.map +1 -1
  143. package/dist/cjs/i18n/useTranslation.js +4 -4
  144. package/dist/cjs/i18n/useTranslation.js.map +1 -1
  145. package/dist/cjs/import/AsepriteImporter.js +15 -19
  146. package/dist/cjs/import/AsepriteImporter.js.map +1 -1
  147. package/dist/cjs/import/DragonBonesImporter.js +36 -40
  148. package/dist/cjs/import/DragonBonesImporter.js.map +1 -1
  149. package/dist/cjs/import/GameMakerImporter.js +11 -17
  150. package/dist/cjs/import/GameMakerImporter.js.map +1 -1
  151. package/dist/cjs/import/GodotSceneImporter.js +43 -29
  152. package/dist/cjs/import/GodotSceneImporter.js.map +1 -1
  153. package/dist/cjs/import/LDtkImporter.js +16 -17
  154. package/dist/cjs/import/LDtkImporter.js.map +1 -1
  155. package/dist/cjs/import/Live2DImporter.js +16 -19
  156. package/dist/cjs/import/Live2DImporter.js.map +1 -1
  157. package/dist/cjs/import/NdgFormat.js +28 -35
  158. package/dist/cjs/import/NdgFormat.js.map +1 -1
  159. package/dist/cjs/import/OgmoImporter.js +16 -18
  160. package/dist/cjs/import/OgmoImporter.js.map +1 -1
  161. package/dist/cjs/import/RPGMakerImporter.js +5 -6
  162. package/dist/cjs/import/RPGMakerImporter.js.map +1 -1
  163. package/dist/cjs/import/SceneImporter.js +23 -13
  164. package/dist/cjs/import/SceneImporter.js.map +1 -1
  165. package/dist/cjs/import/SpineImporter.js +20 -20
  166. package/dist/cjs/import/SpineImporter.js.map +1 -1
  167. package/dist/cjs/import/SpriterImporter.js +38 -46
  168. package/dist/cjs/import/SpriterImporter.js.map +1 -1
  169. package/dist/cjs/import/TiledMapImporter.js +20 -24
  170. package/dist/cjs/import/TiledMapImporter.js.map +1 -1
  171. package/dist/cjs/import/UnitySceneImporter.js +15 -15
  172. package/dist/cjs/import/UnitySceneImporter.js.map +1 -1
  173. package/dist/cjs/index.js +516 -4
  174. package/dist/cjs/index.js.map +1 -1
  175. package/dist/cjs/input/GamepadNavigation.js +82 -47
  176. package/dist/cjs/input/GamepadNavigation.js.map +1 -1
  177. package/dist/cjs/input/InputManager.js +107 -52
  178. package/dist/cjs/input/InputManager.js.map +1 -1
  179. package/dist/cjs/input/useGamepads.js +35 -29
  180. package/dist/cjs/input/useGamepads.js.map +1 -1
  181. package/dist/cjs/integration/IconSprite.js +39 -21
  182. package/dist/cjs/integration/IconSprite.js.map +1 -1
  183. package/dist/cjs/inventory/InventorySystem.js +218 -127
  184. package/dist/cjs/inventory/InventorySystem.js.map +1 -1
  185. package/dist/cjs/kids/KidMode.js +491 -78
  186. package/dist/cjs/kids/KidMode.js.map +1 -1
  187. package/dist/cjs/kids/KidTools.js +154 -48
  188. package/dist/cjs/kids/KidTools.js.map +1 -1
  189. package/dist/cjs/monetization/Monetization.js +47 -35
  190. package/dist/cjs/monetization/Monetization.js.map +1 -1
  191. package/dist/cjs/multiplayer/LocalMultiplayer.js +48 -26
  192. package/dist/cjs/multiplayer/LocalMultiplayer.js.map +1 -1
  193. package/dist/cjs/multiplayer/MiniGameTypes.js +23 -10
  194. package/dist/cjs/multiplayer/MiniGameTypes.js.map +1 -1
  195. package/dist/cjs/native-engine/AssetPipeline.js +540 -0
  196. package/dist/cjs/native-engine/AssetPipeline.js.map +1 -0
  197. package/dist/cjs/native-engine/AudioEngine.js +825 -0
  198. package/dist/cjs/native-engine/AudioEngine.js.map +1 -0
  199. package/dist/cjs/native-engine/InputSystem.js +1175 -0
  200. package/dist/cjs/native-engine/InputSystem.js.map +1 -0
  201. package/dist/cjs/native-engine/NetworkingSystem.js +825 -0
  202. package/dist/cjs/native-engine/NetworkingSystem.js.map +1 -0
  203. package/dist/cjs/native-engine/PhysicsEngine.js +622 -0
  204. package/dist/cjs/native-engine/PhysicsEngine.js.map +1 -0
  205. package/dist/cjs/native-engine/RenderingEngine.js +371 -0
  206. package/dist/cjs/native-engine/RenderingEngine.js.map +1 -0
  207. package/dist/cjs/native-engine/SceneGraph.js +862 -0
  208. package/dist/cjs/native-engine/SceneGraph.js.map +1 -0
  209. package/dist/cjs/network/MultiplayerTransport.js +63 -33
  210. package/dist/cjs/network/MultiplayerTransport.js.map +1 -1
  211. package/dist/cjs/network/Networking.js +87 -62
  212. package/dist/cjs/network/Networking.js.map +1 -1
  213. package/dist/cjs/pathfinding/Pathfinding.js +71 -26
  214. package/dist/cjs/pathfinding/Pathfinding.js.map +1 -1
  215. package/dist/cjs/performance/AssetStreaming.js +656 -0
  216. package/dist/cjs/performance/AssetStreaming.js.map +1 -0
  217. package/dist/cjs/performance/BenchmarkSuite.js +37 -24
  218. package/dist/cjs/performance/BenchmarkSuite.js.map +1 -1
  219. package/dist/cjs/performance/DeltaCompression.js +566 -0
  220. package/dist/cjs/performance/DeltaCompression.js.map +1 -0
  221. package/dist/cjs/performance/DeterministicPhysics.js +603 -0
  222. package/dist/cjs/performance/DeterministicPhysics.js.map +1 -0
  223. package/dist/cjs/performance/ECSOptimization.js +726 -0
  224. package/dist/cjs/performance/ECSOptimization.js.map +1 -0
  225. package/dist/cjs/performance/HotReload.js +525 -0
  226. package/dist/cjs/performance/HotReload.js.map +1 -0
  227. package/dist/cjs/performance/InputRecording.js +590 -0
  228. package/dist/cjs/performance/InputRecording.js.map +1 -0
  229. package/dist/cjs/performance/InterestManagement.js +532 -0
  230. package/dist/cjs/performance/InterestManagement.js.map +1 -0
  231. package/dist/cjs/performance/LocalizationRuntime.js +472 -0
  232. package/dist/cjs/performance/LocalizationRuntime.js.map +1 -0
  233. package/dist/cjs/performance/MemoryManagement.js +487 -0
  234. package/dist/cjs/performance/MemoryManagement.js.map +1 -0
  235. package/dist/cjs/performance/ModSupport.js +531 -0
  236. package/dist/cjs/performance/ModSupport.js.map +1 -0
  237. package/dist/cjs/performance/MultiThreadedPhysics.js +500 -0
  238. package/dist/cjs/performance/MultiThreadedPhysics.js.map +1 -0
  239. package/dist/cjs/performance/NetworkPrediction.js +521 -0
  240. package/dist/cjs/performance/NetworkPrediction.js.map +1 -0
  241. package/dist/cjs/performance/ObjectPooling.js +653 -0
  242. package/dist/cjs/performance/ObjectPooling.js.map +1 -0
  243. package/dist/cjs/performance/Performance.js +64 -25
  244. package/dist/cjs/performance/Performance.js.map +1 -1
  245. package/dist/cjs/performance/PerformanceAdvanced.js +83 -49
  246. package/dist/cjs/performance/PerformanceAdvanced.js.map +1 -1
  247. package/dist/cjs/performance/SaveSystem.js +574 -0
  248. package/dist/cjs/performance/SaveSystem.js.map +1 -0
  249. package/dist/cjs/performance/WebGPURenderer.js +702 -0
  250. package/dist/cjs/performance/WebGPURenderer.js.map +1 -0
  251. package/dist/cjs/physics/PhysicsAdvanced.js +32 -20
  252. package/dist/cjs/physics/PhysicsAdvanced.js.map +1 -1
  253. package/dist/cjs/physics/PhysicsEngine2D.js +63 -36
  254. package/dist/cjs/physics/PhysicsEngine2D.js.map +1 -1
  255. package/dist/cjs/plugins/PluginSDK.js +46 -34
  256. package/dist/cjs/plugins/PluginSDK.js.map +1 -1
  257. package/dist/cjs/plugins/PluginTestKit.js +28 -29
  258. package/dist/cjs/plugins/PluginTestKit.js.map +1 -1
  259. package/dist/cjs/procedural/Procedural.js +24 -17
  260. package/dist/cjs/procedural/Procedural.js.map +1 -1
  261. package/dist/cjs/procedural/WorldBuilding.js +187 -55
  262. package/dist/cjs/procedural/WorldBuilding.js.map +1 -1
  263. package/dist/cjs/quest/QuestSystem.js +145 -111
  264. package/dist/cjs/quest/QuestSystem.js.map +1 -1
  265. package/dist/cjs/release/Release.js +142 -31
  266. package/dist/cjs/release/Release.js.map +1 -1
  267. package/dist/cjs/rendering/Camera2D.js +12 -7
  268. package/dist/cjs/rendering/Camera2D.js.map +1 -1
  269. package/dist/cjs/rendering/Renderer2D.js +62 -26
  270. package/dist/cjs/rendering/Renderer2D.js.map +1 -1
  271. package/dist/cjs/rendering/WebGPURenderPipeline.js +60 -31
  272. package/dist/cjs/rendering/WebGPURenderPipeline.js.map +1 -1
  273. package/dist/cjs/runtime3d/Runtime3D.js +80 -55
  274. package/dist/cjs/runtime3d/Runtime3D.js.map +1 -1
  275. package/dist/cjs/runtime3d/SceneEditor3D.js +20 -11
  276. package/dist/cjs/runtime3d/SceneEditor3D.js.map +1 -1
  277. package/dist/cjs/scene/SceneManager.js +26 -12
  278. package/dist/cjs/scene/SceneManager.js.map +1 -1
  279. package/dist/cjs/scripting/GraphToAST.js +36 -24
  280. package/dist/cjs/scripting/GraphToAST.js.map +1 -1
  281. package/dist/cjs/scripting/LanguageExporter.js +2 -3
  282. package/dist/cjs/scripting/LanguageExporter.js.map +1 -1
  283. package/dist/cjs/scripting/NodeGraph.js +49 -32
  284. package/dist/cjs/scripting/NodeGraph.js.map +1 -1
  285. package/dist/cjs/scripting/ScriptAST.js +19 -6
  286. package/dist/cjs/scripting/ScriptAST.js.map +1 -1
  287. package/dist/cjs/scripting/VisualScripting2.js +13 -12
  288. package/dist/cjs/scripting/VisualScripting2.js.map +1 -1
  289. package/dist/cjs/scripting/exporters/CSharpExporter.js +16 -16
  290. package/dist/cjs/scripting/exporters/CSharpExporter.js.map +1 -1
  291. package/dist/cjs/scripting/exporters/GDScriptExporter.js +3 -6
  292. package/dist/cjs/scripting/exporters/GDScriptExporter.js.map +1 -1
  293. package/dist/cjs/scripting/exporters/LuaExporter.js +5 -9
  294. package/dist/cjs/scripting/exporters/LuaExporter.js.map +1 -1
  295. package/dist/cjs/scripting/exporters/PythonExporter.js +7 -13
  296. package/dist/cjs/scripting/exporters/PythonExporter.js.map +1 -1
  297. package/dist/cjs/scripting/exporters/RustExporter.js +7 -14
  298. package/dist/cjs/scripting/exporters/RustExporter.js.map +1 -1
  299. package/dist/cjs/scripting/exporters/TypeScriptExporter.js +28 -29
  300. package/dist/cjs/scripting/exporters/TypeScriptExporter.js.map +1 -1
  301. package/dist/cjs/social/Social.js +27 -20
  302. package/dist/cjs/social/Social.js.map +1 -1
  303. package/dist/cjs/systems/LightingSystem.js +980 -0
  304. package/dist/cjs/systems/LightingSystem.js.map +1 -0
  305. package/dist/cjs/systems/ParticleSystem2.js +34 -17
  306. package/dist/cjs/systems/ParticleSystem2.js.map +1 -1
  307. package/dist/cjs/systems/PhysicsDebugSystem.js +1228 -0
  308. package/dist/cjs/systems/PhysicsDebugSystem.js.map +1 -0
  309. package/dist/cjs/systems/TerrainSystem.js +1137 -0
  310. package/dist/cjs/systems/TerrainSystem.js.map +1 -0
  311. package/dist/cjs/templates/ActionTemplates.js +144 -24
  312. package/dist/cjs/templates/ActionTemplates.js.map +1 -1
  313. package/dist/cjs/templates/FightingTemplate.js +536 -0
  314. package/dist/cjs/templates/FightingTemplate.js.map +1 -0
  315. package/dist/cjs/templates/MetroidvaniaTemplate.js +523 -0
  316. package/dist/cjs/templates/MetroidvaniaTemplate.js.map +1 -0
  317. package/dist/cjs/templates/PartyTemplates.js +60 -28
  318. package/dist/cjs/templates/PartyTemplates.js.map +1 -1
  319. package/dist/cjs/templates/PuzzleTemplates.js +63 -22
  320. package/dist/cjs/templates/PuzzleTemplates.js.map +1 -1
  321. package/dist/cjs/templates/RPGTemplates.js +29 -15
  322. package/dist/cjs/templates/RPGTemplates.js.map +1 -1
  323. package/dist/cjs/templates/SportsTemplates.js +41 -17
  324. package/dist/cjs/templates/SportsTemplates.js.map +1 -1
  325. package/dist/cjs/templates/StrategyTemplates.js +45 -18
  326. package/dist/cjs/templates/StrategyTemplates.js.map +1 -1
  327. package/dist/cjs/templates/SurvivalTemplate.js +479 -0
  328. package/dist/cjs/templates/SurvivalTemplate.js.map +1 -0
  329. package/dist/cjs/templates/WaveDefense.js +139 -52
  330. package/dist/cjs/templates/WaveDefense.js.map +1 -1
  331. package/dist/cjs/tilemap/Tilemap.js +48 -32
  332. package/dist/cjs/tilemap/Tilemap.js.map +1 -1
  333. package/dist/cjs/tutorials/TutorialBranching.js +111 -42
  334. package/dist/cjs/tutorials/TutorialBranching.js.map +1 -1
  335. package/dist/cjs/tutorials/TutorialEngine.js +152 -80
  336. package/dist/cjs/tutorials/TutorialEngine.js.map +1 -1
  337. package/dist/cjs/tutorials/TutorialOverlay.js +117 -40
  338. package/dist/cjs/tutorials/TutorialOverlay.js.map +1 -1
  339. package/dist/cjs/ui/GameUI.js +69 -42
  340. package/dist/cjs/ui/GameUI.js.map +1 -1
  341. package/dist/cjs/unity-integration/UnityAssetStore.js +754 -0
  342. package/dist/cjs/unity-integration/UnityAssetStore.js.map +1 -0
  343. package/dist/cjs/unity-integration/UnityImport.js +1252 -0
  344. package/dist/cjs/unity-integration/UnityImport.js.map +1 -0
  345. package/dist/cjs/unity-integration/UnityLiveLink.js +1022 -0
  346. package/dist/cjs/unity-integration/UnityLiveLink.js.map +1 -0
  347. package/dist/cjs/unity-integration/components/UnityAssetStoreBrowser.js +796 -0
  348. package/dist/cjs/unity-integration/components/UnityAssetStoreBrowser.js.map +1 -0
  349. package/dist/cjs/unity-integration/components/UnityProjectBrowser.js +833 -0
  350. package/dist/cjs/unity-integration/components/UnityProjectBrowser.js.map +1 -0
  351. package/dist/cjs/unreal-integration/UnrealImport.js +442 -0
  352. package/dist/cjs/unreal-integration/UnrealImport.js.map +1 -0
  353. package/dist/cjs/unreal-integration/UnrealLiveLink.js +1186 -0
  354. package/dist/cjs/unreal-integration/UnrealLiveLink.js.map +1 -0
  355. package/dist/cjs/unreal-integration/UnrealMarketplace.js +497 -0
  356. package/dist/cjs/unreal-integration/UnrealMarketplace.js.map +1 -0
  357. package/dist/cjs/unreal-integration/components/UnrealProjectBrowser.js +835 -0
  358. package/dist/cjs/unreal-integration/components/UnrealProjectBrowser.js.map +1 -0
  359. package/dist/cjs/xr/ARVR.js +32 -9
  360. package/dist/cjs/xr/ARVR.js.map +1 -1
  361. package/dist/esm/accessibility/Accessibility.js +55 -20
  362. package/dist/esm/accessibility/Accessibility.js.map +1 -1
  363. package/dist/esm/ai/AI.js +74 -40
  364. package/dist/esm/ai/AI.js.map +1 -1
  365. package/dist/esm/ai/BehaviorTree.js +39 -47
  366. package/dist/esm/ai/BehaviorTree.js.map +1 -1
  367. package/dist/esm/ai/StateMachine.js +65 -99
  368. package/dist/esm/ai/StateMachine.js.map +1 -1
  369. package/dist/esm/animation/Animation.js +58 -34
  370. package/dist/esm/animation/Animation.js.map +1 -1
  371. package/dist/esm/audio/AudioAdvanced.js +71 -37
  372. package/dist/esm/audio/AudioAdvanced.js.map +1 -1
  373. package/dist/esm/audio/AudioBridge.js +61 -49
  374. package/dist/esm/audio/AudioBridge.js.map +1 -1
  375. package/dist/esm/audio/AudioManager.js +45 -29
  376. package/dist/esm/audio/AudioManager.js.map +1 -1
  377. package/dist/esm/build-cloud/BuildOrchestration.js +1129 -0
  378. package/dist/esm/build-cloud/BuildOrchestration.js.map +1 -0
  379. package/dist/esm/build-cloud/GodotBuildCloud.js +715 -0
  380. package/dist/esm/build-cloud/GodotBuildCloud.js.map +1 -0
  381. package/dist/esm/build-cloud/UnityBuildCloud.js +643 -0
  382. package/dist/esm/build-cloud/UnityBuildCloud.js.map +1 -0
  383. package/dist/esm/build-cloud/UnrealBuildCloud.js +668 -0
  384. package/dist/esm/build-cloud/UnrealBuildCloud.js.map +1 -0
  385. package/dist/esm/core/EventBus.js +2 -1
  386. package/dist/esm/core/EventBus.js.map +1 -1
  387. package/dist/esm/core/GameConfig.js +1 -1
  388. package/dist/esm/core/GameConfig.js.map +1 -1
  389. package/dist/esm/core/GameLoop.js +6 -3
  390. package/dist/esm/core/GameLoop.js.map +1 -1
  391. package/dist/esm/core/ServiceLocator.js +1 -2
  392. package/dist/esm/core/ServiceLocator.js.map +1 -1
  393. package/dist/esm/devtools/DevTools.js +73 -43
  394. package/dist/esm/devtools/DevTools.js.map +1 -1
  395. package/dist/esm/devtools/DeveloperExperience.js +84 -42
  396. package/dist/esm/devtools/DeveloperExperience.js.map +1 -1
  397. package/dist/esm/devtools/GameplayAnalytics.js +71 -43
  398. package/dist/esm/devtools/GameplayAnalytics.js.map +1 -1
  399. package/dist/esm/dialogue/DialogueSystem.js +153 -129
  400. package/dist/esm/dialogue/DialogueSystem.js.map +1 -1
  401. package/dist/esm/docs/DocGenerator.js +70 -28
  402. package/dist/esm/docs/DocGenerator.js.map +1 -1
  403. package/dist/esm/ecs/World.js +159 -33
  404. package/dist/esm/ecs/World.js.map +1 -1
  405. package/dist/esm/editor/AchievementEditor.js +645 -0
  406. package/dist/esm/editor/AchievementEditor.js.map +1 -0
  407. package/dist/esm/editor/AdvancedEditor.js +95 -23
  408. package/dist/esm/editor/AdvancedEditor.js.map +1 -1
  409. package/dist/esm/editor/AnimationRetargeting.js +738 -0
  410. package/dist/esm/editor/AnimationRetargeting.js.map +1 -0
  411. package/dist/esm/editor/AssetBrowser.js +1184 -0
  412. package/dist/esm/editor/AssetBrowser.js.map +1 -0
  413. package/dist/esm/editor/AssetManager.js +22 -14
  414. package/dist/esm/editor/AssetManager.js.map +1 -1
  415. package/dist/esm/editor/ConsolePro.js +1085 -0
  416. package/dist/esm/editor/ConsolePro.js.map +1 -0
  417. package/dist/esm/editor/CraftingEditor.js +744 -0
  418. package/dist/esm/editor/CraftingEditor.js.map +1 -0
  419. package/dist/esm/editor/DebugTools.js +46 -23
  420. package/dist/esm/editor/DebugTools.js.map +1 -1
  421. package/dist/esm/editor/DialogueSystem.js +918 -0
  422. package/dist/esm/editor/DialogueSystem.js.map +1 -0
  423. package/dist/esm/editor/LeaderboardSystem.js +491 -0
  424. package/dist/esm/editor/LeaderboardSystem.js.map +1 -0
  425. package/dist/esm/editor/NiceGameEditor.js +532 -142
  426. package/dist/esm/editor/NiceGameEditor.js.map +1 -1
  427. package/dist/esm/editor/PrefabSystem.js +858 -0
  428. package/dist/esm/editor/PrefabSystem.js.map +1 -0
  429. package/dist/esm/editor/ProfilerPanel.js +710 -0
  430. package/dist/esm/editor/ProfilerPanel.js.map +1 -0
  431. package/dist/esm/editor/QuestEditor.js +846 -0
  432. package/dist/esm/editor/QuestEditor.js.map +1 -0
  433. package/dist/esm/editor/ReplaySystem.js +648 -0
  434. package/dist/esm/editor/ReplaySystem.js.map +1 -0
  435. package/dist/esm/editor/SceneEditor.js +33 -13
  436. package/dist/esm/editor/SceneEditor.js.map +1 -1
  437. package/dist/esm/editor/ScreenshotMode.js +702 -0
  438. package/dist/esm/editor/ScreenshotMode.js.map +1 -0
  439. package/dist/esm/editor/ShaderGraph.js +7 -6
  440. package/dist/esm/editor/ShaderGraph.js.map +1 -1
  441. package/dist/esm/editor/TimelineEditor.js +37 -30
  442. package/dist/esm/editor/TimelineEditor.js.map +1 -1
  443. package/dist/esm/editor/UndoRedoPro.js +914 -0
  444. package/dist/esm/editor/UndoRedoPro.js.map +1 -0
  445. package/dist/esm/editor/VRARMode.js +653 -0
  446. package/dist/esm/editor/VRARMode.js.map +1 -0
  447. package/dist/esm/engine/NiceGameEngine.js +12 -10
  448. package/dist/esm/engine/NiceGameEngine.js.map +1 -1
  449. package/dist/esm/engine/SaveSystemV2.js +73 -37
  450. package/dist/esm/engine/SaveSystemV2.js.map +1 -1
  451. package/dist/esm/enterprise/Enterprise.js +92 -44
  452. package/dist/esm/enterprise/Enterprise.js.map +1 -1
  453. package/dist/esm/export/BevyExporter.js +995 -0
  454. package/dist/esm/export/BevyExporter.js.map +1 -0
  455. package/dist/esm/export/CocosExporter.js +703 -0
  456. package/dist/esm/export/CocosExporter.js.map +1 -0
  457. package/dist/esm/export/Construct3Exporter.js +829 -0
  458. package/dist/esm/export/Construct3Exporter.js.map +1 -0
  459. package/dist/esm/export/DefoldExporter.js +1103 -0
  460. package/dist/esm/export/DefoldExporter.js.map +1 -0
  461. package/dist/esm/export/GDevelopExporter.js +745 -0
  462. package/dist/esm/export/GDevelopExporter.js.map +1 -0
  463. package/dist/esm/export/GameMakerExporter.js +843 -0
  464. package/dist/esm/export/GameMakerExporter.js.map +1 -0
  465. package/dist/esm/export/GodotExporter.js +45 -50
  466. package/dist/esm/export/GodotExporter.js.map +1 -1
  467. package/dist/esm/export/MinecraftBedrockExporter.js +603 -0
  468. package/dist/esm/export/MinecraftBedrockExporter.js.map +1 -0
  469. package/dist/esm/export/MonoGameExporter.js +1331 -0
  470. package/dist/esm/export/MonoGameExporter.js.map +1 -0
  471. package/dist/esm/export/Pico8Exporter.js +843 -0
  472. package/dist/esm/export/Pico8Exporter.js.map +1 -0
  473. package/dist/esm/export/PlatformExporter.js +4 -5
  474. package/dist/esm/export/PlatformExporter.js.map +1 -1
  475. package/dist/esm/export/RPGMakerExporter.js +903 -0
  476. package/dist/esm/export/RPGMakerExporter.js.map +1 -0
  477. package/dist/esm/export/RobloxExporter.js +940 -0
  478. package/dist/esm/export/RobloxExporter.js.map +1 -0
  479. package/dist/esm/export/Solar2DExporter.js +1280 -0
  480. package/dist/esm/export/Solar2DExporter.js.map +1 -0
  481. package/dist/esm/export/ThreeJSExporter.js +52 -55
  482. package/dist/esm/export/ThreeJSExporter.js.map +1 -1
  483. package/dist/esm/export/Tic80Exporter.js +1312 -0
  484. package/dist/esm/export/Tic80Exporter.js.map +1 -0
  485. package/dist/esm/export/UnityExporter.js +41 -56
  486. package/dist/esm/export/UnityExporter.js.map +1 -1
  487. package/dist/esm/export/UnrealExporter.js +959 -0
  488. package/dist/esm/export/UnrealExporter.js.map +1 -0
  489. package/dist/esm/export/WebExporter.js +42 -50
  490. package/dist/esm/export/WebExporter.js.map +1 -1
  491. package/dist/esm/export/index.js +38 -2
  492. package/dist/esm/export/index.js.map +1 -1
  493. package/dist/esm/godot-integration/GodotAssetLibrary.js +711 -0
  494. package/dist/esm/godot-integration/GodotAssetLibrary.js.map +1 -0
  495. package/dist/esm/godot-integration/GodotImport.js +1062 -0
  496. package/dist/esm/godot-integration/GodotImport.js.map +1 -0
  497. package/dist/esm/godot-integration/GodotLiveLink.js +958 -0
  498. package/dist/esm/godot-integration/GodotLiveLink.js.map +1 -0
  499. package/dist/esm/godot-integration/components/GodotProjectBrowser.js +666 -0
  500. package/dist/esm/godot-integration/components/GodotProjectBrowser.js.map +1 -0
  501. package/dist/esm/i18n/I18n.js +56 -30
  502. package/dist/esm/i18n/I18n.js.map +1 -1
  503. package/dist/esm/i18n/useTranslation.js +4 -4
  504. package/dist/esm/i18n/useTranslation.js.map +1 -1
  505. package/dist/esm/import/AsepriteImporter.js +15 -19
  506. package/dist/esm/import/AsepriteImporter.js.map +1 -1
  507. package/dist/esm/import/DragonBonesImporter.js +36 -40
  508. package/dist/esm/import/DragonBonesImporter.js.map +1 -1
  509. package/dist/esm/import/GameMakerImporter.js +11 -17
  510. package/dist/esm/import/GameMakerImporter.js.map +1 -1
  511. package/dist/esm/import/GodotSceneImporter.js +43 -29
  512. package/dist/esm/import/GodotSceneImporter.js.map +1 -1
  513. package/dist/esm/import/LDtkImporter.js +16 -17
  514. package/dist/esm/import/LDtkImporter.js.map +1 -1
  515. package/dist/esm/import/Live2DImporter.js +16 -19
  516. package/dist/esm/import/Live2DImporter.js.map +1 -1
  517. package/dist/esm/import/NdgFormat.js +28 -35
  518. package/dist/esm/import/NdgFormat.js.map +1 -1
  519. package/dist/esm/import/OgmoImporter.js +16 -18
  520. package/dist/esm/import/OgmoImporter.js.map +1 -1
  521. package/dist/esm/import/RPGMakerImporter.js +5 -6
  522. package/dist/esm/import/RPGMakerImporter.js.map +1 -1
  523. package/dist/esm/import/SceneImporter.js +23 -13
  524. package/dist/esm/import/SceneImporter.js.map +1 -1
  525. package/dist/esm/import/SpineImporter.js +20 -20
  526. package/dist/esm/import/SpineImporter.js.map +1 -1
  527. package/dist/esm/import/SpriterImporter.js +38 -46
  528. package/dist/esm/import/SpriterImporter.js.map +1 -1
  529. package/dist/esm/import/TiledMapImporter.js +20 -24
  530. package/dist/esm/import/TiledMapImporter.js.map +1 -1
  531. package/dist/esm/import/UnitySceneImporter.js +15 -15
  532. package/dist/esm/import/UnitySceneImporter.js.map +1 -1
  533. package/dist/esm/index.js +76 -3
  534. package/dist/esm/index.js.map +1 -1
  535. package/dist/esm/input/GamepadNavigation.js +82 -47
  536. package/dist/esm/input/GamepadNavigation.js.map +1 -1
  537. package/dist/esm/input/InputManager.js +107 -52
  538. package/dist/esm/input/InputManager.js.map +1 -1
  539. package/dist/esm/input/useGamepads.js +35 -29
  540. package/dist/esm/input/useGamepads.js.map +1 -1
  541. package/dist/esm/integration/IconSprite.js +39 -21
  542. package/dist/esm/integration/IconSprite.js.map +1 -1
  543. package/dist/esm/inventory/InventorySystem.js +218 -127
  544. package/dist/esm/inventory/InventorySystem.js.map +1 -1
  545. package/dist/esm/kids/KidMode.js +491 -78
  546. package/dist/esm/kids/KidMode.js.map +1 -1
  547. package/dist/esm/kids/KidTools.js +154 -48
  548. package/dist/esm/kids/KidTools.js.map +1 -1
  549. package/dist/esm/monetization/Monetization.js +47 -35
  550. package/dist/esm/monetization/Monetization.js.map +1 -1
  551. package/dist/esm/multiplayer/LocalMultiplayer.js +48 -26
  552. package/dist/esm/multiplayer/LocalMultiplayer.js.map +1 -1
  553. package/dist/esm/multiplayer/MiniGameTypes.js +23 -10
  554. package/dist/esm/multiplayer/MiniGameTypes.js.map +1 -1
  555. package/dist/esm/native-engine/AssetPipeline.js +537 -0
  556. package/dist/esm/native-engine/AssetPipeline.js.map +1 -0
  557. package/dist/esm/native-engine/AudioEngine.js +822 -0
  558. package/dist/esm/native-engine/AudioEngine.js.map +1 -0
  559. package/dist/esm/native-engine/InputSystem.js +1170 -0
  560. package/dist/esm/native-engine/InputSystem.js.map +1 -0
  561. package/dist/esm/native-engine/NetworkingSystem.js +817 -0
  562. package/dist/esm/native-engine/NetworkingSystem.js.map +1 -0
  563. package/dist/esm/native-engine/PhysicsEngine.js +619 -0
  564. package/dist/esm/native-engine/PhysicsEngine.js.map +1 -0
  565. package/dist/esm/native-engine/RenderingEngine.js +368 -0
  566. package/dist/esm/native-engine/RenderingEngine.js.map +1 -0
  567. package/dist/esm/native-engine/SceneGraph.js +857 -0
  568. package/dist/esm/native-engine/SceneGraph.js.map +1 -0
  569. package/dist/esm/network/MultiplayerTransport.js +63 -33
  570. package/dist/esm/network/MultiplayerTransport.js.map +1 -1
  571. package/dist/esm/network/Networking.js +87 -62
  572. package/dist/esm/network/Networking.js.map +1 -1
  573. package/dist/esm/pathfinding/Pathfinding.js +71 -26
  574. package/dist/esm/pathfinding/Pathfinding.js.map +1 -1
  575. package/dist/esm/performance/AssetStreaming.js +649 -0
  576. package/dist/esm/performance/AssetStreaming.js.map +1 -0
  577. package/dist/esm/performance/BenchmarkSuite.js +37 -24
  578. package/dist/esm/performance/BenchmarkSuite.js.map +1 -1
  579. package/dist/esm/performance/DeltaCompression.js +554 -0
  580. package/dist/esm/performance/DeltaCompression.js.map +1 -0
  581. package/dist/esm/performance/DeterministicPhysics.js +573 -0
  582. package/dist/esm/performance/DeterministicPhysics.js.map +1 -0
  583. package/dist/esm/performance/ECSOptimization.js +716 -0
  584. package/dist/esm/performance/ECSOptimization.js.map +1 -0
  585. package/dist/esm/performance/HotReload.js +517 -0
  586. package/dist/esm/performance/HotReload.js.map +1 -0
  587. package/dist/esm/performance/InputRecording.js +580 -0
  588. package/dist/esm/performance/InputRecording.js.map +1 -0
  589. package/dist/esm/performance/InterestManagement.js +524 -0
  590. package/dist/esm/performance/InterestManagement.js.map +1 -0
  591. package/dist/esm/performance/LocalizationRuntime.js +465 -0
  592. package/dist/esm/performance/LocalizationRuntime.js.map +1 -0
  593. package/dist/esm/performance/MemoryManagement.js +481 -0
  594. package/dist/esm/performance/MemoryManagement.js.map +1 -0
  595. package/dist/esm/performance/ModSupport.js +520 -0
  596. package/dist/esm/performance/ModSupport.js.map +1 -0
  597. package/dist/esm/performance/MultiThreadedPhysics.js +491 -0
  598. package/dist/esm/performance/MultiThreadedPhysics.js.map +1 -0
  599. package/dist/esm/performance/NetworkPrediction.js +508 -0
  600. package/dist/esm/performance/NetworkPrediction.js.map +1 -0
  601. package/dist/esm/performance/ObjectPooling.js +639 -0
  602. package/dist/esm/performance/ObjectPooling.js.map +1 -0
  603. package/dist/esm/performance/Performance.js +64 -25
  604. package/dist/esm/performance/Performance.js.map +1 -1
  605. package/dist/esm/performance/PerformanceAdvanced.js +83 -49
  606. package/dist/esm/performance/PerformanceAdvanced.js.map +1 -1
  607. package/dist/esm/performance/SaveSystem.js +567 -0
  608. package/dist/esm/performance/SaveSystem.js.map +1 -0
  609. package/dist/esm/performance/WebGPURenderer.js +697 -0
  610. package/dist/esm/performance/WebGPURenderer.js.map +1 -0
  611. package/dist/esm/physics/PhysicsAdvanced.js +32 -20
  612. package/dist/esm/physics/PhysicsAdvanced.js.map +1 -1
  613. package/dist/esm/physics/PhysicsEngine2D.js +63 -36
  614. package/dist/esm/physics/PhysicsEngine2D.js.map +1 -1
  615. package/dist/esm/plugins/PluginSDK.js +46 -34
  616. package/dist/esm/plugins/PluginSDK.js.map +1 -1
  617. package/dist/esm/plugins/PluginTestKit.js +28 -29
  618. package/dist/esm/plugins/PluginTestKit.js.map +1 -1
  619. package/dist/esm/procedural/Procedural.js +24 -17
  620. package/dist/esm/procedural/Procedural.js.map +1 -1
  621. package/dist/esm/procedural/WorldBuilding.js +188 -55
  622. package/dist/esm/procedural/WorldBuilding.js.map +1 -1
  623. package/dist/esm/quest/QuestSystem.js +145 -111
  624. package/dist/esm/quest/QuestSystem.js.map +1 -1
  625. package/dist/esm/release/Release.js +142 -31
  626. package/dist/esm/release/Release.js.map +1 -1
  627. package/dist/esm/rendering/Camera2D.js +12 -7
  628. package/dist/esm/rendering/Camera2D.js.map +1 -1
  629. package/dist/esm/rendering/Renderer2D.js +62 -26
  630. package/dist/esm/rendering/Renderer2D.js.map +1 -1
  631. package/dist/esm/rendering/WebGPURenderPipeline.js +60 -31
  632. package/dist/esm/rendering/WebGPURenderPipeline.js.map +1 -1
  633. package/dist/esm/runtime3d/Runtime3D.js +80 -55
  634. package/dist/esm/runtime3d/Runtime3D.js.map +1 -1
  635. package/dist/esm/runtime3d/SceneEditor3D.js +20 -11
  636. package/dist/esm/runtime3d/SceneEditor3D.js.map +1 -1
  637. package/dist/esm/scene/SceneManager.js +26 -12
  638. package/dist/esm/scene/SceneManager.js.map +1 -1
  639. package/dist/esm/scripting/GraphToAST.js +36 -24
  640. package/dist/esm/scripting/GraphToAST.js.map +1 -1
  641. package/dist/esm/scripting/LanguageExporter.js +2 -3
  642. package/dist/esm/scripting/LanguageExporter.js.map +1 -1
  643. package/dist/esm/scripting/NodeGraph.js +49 -32
  644. package/dist/esm/scripting/NodeGraph.js.map +1 -1
  645. package/dist/esm/scripting/ScriptAST.js +19 -6
  646. package/dist/esm/scripting/ScriptAST.js.map +1 -1
  647. package/dist/esm/scripting/VisualScripting2.js +13 -12
  648. package/dist/esm/scripting/VisualScripting2.js.map +1 -1
  649. package/dist/esm/scripting/exporters/CSharpExporter.js +16 -16
  650. package/dist/esm/scripting/exporters/CSharpExporter.js.map +1 -1
  651. package/dist/esm/scripting/exporters/GDScriptExporter.js +3 -6
  652. package/dist/esm/scripting/exporters/GDScriptExporter.js.map +1 -1
  653. package/dist/esm/scripting/exporters/LuaExporter.js +5 -9
  654. package/dist/esm/scripting/exporters/LuaExporter.js.map +1 -1
  655. package/dist/esm/scripting/exporters/PythonExporter.js +7 -13
  656. package/dist/esm/scripting/exporters/PythonExporter.js.map +1 -1
  657. package/dist/esm/scripting/exporters/RustExporter.js +7 -14
  658. package/dist/esm/scripting/exporters/RustExporter.js.map +1 -1
  659. package/dist/esm/scripting/exporters/TypeScriptExporter.js +28 -29
  660. package/dist/esm/scripting/exporters/TypeScriptExporter.js.map +1 -1
  661. package/dist/esm/social/Social.js +27 -20
  662. package/dist/esm/social/Social.js.map +1 -1
  663. package/dist/esm/systems/LightingSystem.js +968 -0
  664. package/dist/esm/systems/LightingSystem.js.map +1 -0
  665. package/dist/esm/systems/ParticleSystem2.js +34 -17
  666. package/dist/esm/systems/ParticleSystem2.js.map +1 -1
  667. package/dist/esm/systems/PhysicsDebugSystem.js +1219 -0
  668. package/dist/esm/systems/PhysicsDebugSystem.js.map +1 -0
  669. package/dist/esm/systems/TerrainSystem.js +1125 -0
  670. package/dist/esm/systems/TerrainSystem.js.map +1 -0
  671. package/dist/esm/templates/ActionTemplates.js +144 -24
  672. package/dist/esm/templates/ActionTemplates.js.map +1 -1
  673. package/dist/esm/templates/FightingTemplate.js +513 -0
  674. package/dist/esm/templates/FightingTemplate.js.map +1 -0
  675. package/dist/esm/templates/MetroidvaniaTemplate.js +484 -0
  676. package/dist/esm/templates/MetroidvaniaTemplate.js.map +1 -0
  677. package/dist/esm/templates/PartyTemplates.js +60 -28
  678. package/dist/esm/templates/PartyTemplates.js.map +1 -1
  679. package/dist/esm/templates/PuzzleTemplates.js +63 -22
  680. package/dist/esm/templates/PuzzleTemplates.js.map +1 -1
  681. package/dist/esm/templates/RPGTemplates.js +29 -15
  682. package/dist/esm/templates/RPGTemplates.js.map +1 -1
  683. package/dist/esm/templates/SportsTemplates.js +41 -17
  684. package/dist/esm/templates/SportsTemplates.js.map +1 -1
  685. package/dist/esm/templates/StrategyTemplates.js +45 -18
  686. package/dist/esm/templates/StrategyTemplates.js.map +1 -1
  687. package/dist/esm/templates/SurvivalTemplate.js +447 -0
  688. package/dist/esm/templates/SurvivalTemplate.js.map +1 -0
  689. package/dist/esm/templates/WaveDefense.js +139 -52
  690. package/dist/esm/templates/WaveDefense.js.map +1 -1
  691. package/dist/esm/tilemap/Tilemap.js +48 -32
  692. package/dist/esm/tilemap/Tilemap.js.map +1 -1
  693. package/dist/esm/tutorials/TutorialBranching.js +111 -42
  694. package/dist/esm/tutorials/TutorialBranching.js.map +1 -1
  695. package/dist/esm/tutorials/TutorialEngine.js +152 -80
  696. package/dist/esm/tutorials/TutorialEngine.js.map +1 -1
  697. package/dist/esm/tutorials/TutorialOverlay.js +117 -40
  698. package/dist/esm/tutorials/TutorialOverlay.js.map +1 -1
  699. package/dist/esm/ui/GameUI.js +69 -42
  700. package/dist/esm/ui/GameUI.js.map +1 -1
  701. package/dist/esm/unity-integration/UnityAssetStore.js +749 -0
  702. package/dist/esm/unity-integration/UnityAssetStore.js.map +1 -0
  703. package/dist/esm/unity-integration/UnityImport.js +1246 -0
  704. package/dist/esm/unity-integration/UnityImport.js.map +1 -0
  705. package/dist/esm/unity-integration/UnityLiveLink.js +1017 -0
  706. package/dist/esm/unity-integration/UnityLiveLink.js.map +1 -0
  707. package/dist/esm/unity-integration/components/UnityAssetStoreBrowser.js +794 -0
  708. package/dist/esm/unity-integration/components/UnityAssetStoreBrowser.js.map +1 -0
  709. package/dist/esm/unity-integration/components/UnityProjectBrowser.js +831 -0
  710. package/dist/esm/unity-integration/components/UnityProjectBrowser.js.map +1 -0
  711. package/dist/esm/unreal-integration/UnrealImport.js +437 -0
  712. package/dist/esm/unreal-integration/UnrealImport.js.map +1 -0
  713. package/dist/esm/unreal-integration/UnrealLiveLink.js +1182 -0
  714. package/dist/esm/unreal-integration/UnrealLiveLink.js.map +1 -0
  715. package/dist/esm/unreal-integration/UnrealMarketplace.js +490 -0
  716. package/dist/esm/unreal-integration/UnrealMarketplace.js.map +1 -0
  717. package/dist/esm/unreal-integration/components/UnrealProjectBrowser.js +833 -0
  718. package/dist/esm/unreal-integration/components/UnrealProjectBrowser.js.map +1 -0
  719. package/dist/esm/xr/ARVR.js +32 -9
  720. package/dist/esm/xr/ARVR.js.map +1 -1
  721. package/package.json +6 -5
@@ -0,0 +1,1137 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @file TerrainSystem.ts
5
+ * @description Advanced Terrain System with Heightmap, Splatmap, and Foliage
6
+ * PRO-1.4: Professional Editor Features
7
+ *
8
+ * Features:
9
+ * - Heightmap terrain with LOD
10
+ * - Splatmap texture blending (up to 8 layers)
11
+ * - Foliage scattering (grass, trees, rocks)
12
+ * - Terrain brushes (raise, lower, smooth, flatten, noise, erosion)
13
+ * - Procedural generation (Perlin noise, diamond-square, hydraulic erosion)
14
+ * - Holes/caves support
15
+ * - Detail meshes and decals
16
+ * - Terrain chunks with streaming
17
+ * - Physics collision mesh generation
18
+ */
19
+ const DEFAULT_TERRAIN_CONFIG = {
20
+ width: 1000,
21
+ depth: 1000,
22
+ maxHeight: 100,
23
+ heightmapResolution: 513, // Power of 2 + 1 for LOD
24
+ splatmapResolution: 512,
25
+ chunksPerSide: 4,
26
+ detailResolution: 1024,
27
+ detailResolutionPerPatch: 8,
28
+ basemapDistance: 1000,
29
+ castShadows: true,
30
+ drawInstanced: true,
31
+ };
32
+ function createTerrainLayer(id, name, diffuseTexture) {
33
+ return {
34
+ id,
35
+ name,
36
+ diffuseTexture,
37
+ tileSize: { x: 15, y: 15 },
38
+ tileOffset: { x: 0, y: 0 },
39
+ metallic: 0,
40
+ smoothness: 0.5,
41
+ specularColor: { r: 0.2, g: 0.2, b: 0.2, a: 1 },
42
+ normalScale: 1,
43
+ diffuseRemapMin: { r: 0, g: 0, b: 0, a: 0 },
44
+ diffuseRemapMax: { r: 1, g: 1, b: 1, a: 1 },
45
+ maskRemapMin: { r: 0, g: 0, b: 0, a: 0 },
46
+ maskRemapMax: { r: 1, g: 1, b: 1, a: 1 },
47
+ };
48
+ }
49
+ function createGrassDetail(id, name, textureId) {
50
+ return {
51
+ id,
52
+ name,
53
+ textureId,
54
+ renderMode: 'grass',
55
+ useInstancing: true,
56
+ healthyColor: { r: 0.26, g: 0.8, b: 0.28, a: 1 },
57
+ dryColor: { r: 0.8, g: 0.72, b: 0.28, a: 1 },
58
+ minWidth: 0.8,
59
+ maxWidth: 1.2,
60
+ minHeight: 0.4,
61
+ maxHeight: 0.8,
62
+ noiseSpread: 0.1,
63
+ density: 1,
64
+ alignToGround: 0.5,
65
+ positionJitter: 0.5,
66
+ holeEdgePadding: 0,
67
+ };
68
+ }
69
+ function createTreePrototype(id, name, meshId) {
70
+ return {
71
+ id,
72
+ name,
73
+ meshId,
74
+ lodMeshes: [],
75
+ bendFactor: 1,
76
+ minScale: 0.8,
77
+ maxScale: 1.2,
78
+ randomRotation: true,
79
+ alignToGround: 0.5,
80
+ navMeshArea: 0,
81
+ };
82
+ }
83
+ const DEFAULT_BRUSH = {
84
+ type: 'raise',
85
+ size: 10,
86
+ strength: 0.5,
87
+ falloff: 0.5,
88
+ rotation: 0,
89
+ spacingJitter: 0,
90
+ scatter: 0,
91
+ };
92
+ // ============================================================
93
+ // Terrain System Class
94
+ // ============================================================
95
+ class TerrainSystem {
96
+ constructor(config) {
97
+ this.undoStack = [];
98
+ this.redoStack = [];
99
+ this.maxUndoSteps = 50;
100
+ this.data = this.createEmptyTerrain(config);
101
+ }
102
+ createEmptyTerrain(configOverride) {
103
+ const config = { ...DEFAULT_TERRAIN_CONFIG, ...configOverride };
104
+ const hmRes = config.heightmapResolution;
105
+ const smRes = config.splatmapResolution;
106
+ config.detailResolution;
107
+ const chunks = config.chunksPerSide;
108
+ // Initialize heightmap
109
+ const heightmap = new Float32Array(hmRes * hmRes);
110
+ // Initialize splatmaps (2 textures for 8 layers)
111
+ const splatmaps = [
112
+ new Uint8Array(smRes * smRes * 4),
113
+ new Uint8Array(smRes * smRes * 4),
114
+ ];
115
+ // Set first layer to full coverage by default
116
+ for (let i = 0; i < smRes * smRes; i++) {
117
+ splatmaps[0][i * 4] = 255; // Layer 0 = 100%
118
+ }
119
+ // Initialize holemap (all solid)
120
+ const holemap = new Uint8Array(hmRes * hmRes);
121
+ holemap.fill(1);
122
+ // Create chunks
123
+ const chunkList = [];
124
+ const chunkWidth = config.width / chunks;
125
+ const chunkDepth = config.depth / chunks;
126
+ for (let gz = 0; gz < chunks; gz++) {
127
+ for (let gx = 0; gx < chunks; gx++) {
128
+ chunkList.push({
129
+ id: `chunk_${gx}_${gz}`,
130
+ gridX: gx,
131
+ gridZ: gz,
132
+ boundsMin: {
133
+ x: gx * chunkWidth - config.width / 2,
134
+ y: 0,
135
+ z: gz * chunkDepth - config.depth / 2,
136
+ },
137
+ boundsMax: {
138
+ x: (gx + 1) * chunkWidth - config.width / 2,
139
+ y: config.maxHeight,
140
+ z: (gz + 1) * chunkDepth - config.depth / 2,
141
+ },
142
+ isLoaded: gx < 2 && gz < 2, // Load center chunks
143
+ lodLevel: 0,
144
+ });
145
+ }
146
+ }
147
+ return {
148
+ id: `terrain_${Date.now()}`,
149
+ name: 'New Terrain',
150
+ config,
151
+ heightmap,
152
+ splatmaps,
153
+ holemap,
154
+ layers: [],
155
+ detailPrototypes: [],
156
+ detailMaps: [],
157
+ treePrototypes: [],
158
+ trees: [],
159
+ chunks: chunkList,
160
+ metadata: {
161
+ createdAt: Date.now(),
162
+ modifiedAt: Date.now(),
163
+ version: 1,
164
+ },
165
+ };
166
+ }
167
+ // ─── Heightmap Operations ──────────────────────────────
168
+ /** Get height at grid coordinates (0 to resolution-1) */
169
+ getHeightAtGrid(gridX, gridZ) {
170
+ const res = this.data.config.heightmapResolution;
171
+ const x = Math.max(0, Math.min(res - 1, Math.floor(gridX)));
172
+ const z = Math.max(0, Math.min(res - 1, Math.floor(gridZ)));
173
+ return this.data.heightmap[z * res + x] * this.data.config.maxHeight;
174
+ }
175
+ /** Set height at grid coordinates */
176
+ setHeightAtGrid(gridX, gridZ, height, recordUndo = true) {
177
+ const res = this.data.config.heightmapResolution;
178
+ const maxH = this.data.config.maxHeight;
179
+ if (gridX < 0 || gridX >= res || gridZ < 0 || gridZ >= res) {
180
+ return;
181
+ }
182
+ const idx = gridZ * res + gridX;
183
+ const normalizedHeight = Math.max(0, Math.min(1, height / maxH));
184
+ if (recordUndo) {
185
+ this.recordHeightChange(gridX, gridZ, this.data.heightmap[idx], normalizedHeight);
186
+ }
187
+ this.data.heightmap[idx] = normalizedHeight;
188
+ this.data.metadata.modifiedAt = Date.now();
189
+ }
190
+ /** Get interpolated height at world coordinates */
191
+ getHeightAtWorld(worldX, worldZ) {
192
+ const { width, depth, heightmapResolution: res } = this.data.config;
193
+ // Convert world to grid
194
+ const gx = ((worldX + width / 2) / width) * (res - 1);
195
+ const gz = ((worldZ + depth / 2) / depth) * (res - 1);
196
+ // Bilinear interpolation
197
+ const ix = Math.floor(gx);
198
+ const iz = Math.floor(gz);
199
+ const fx = gx - ix;
200
+ const fz = gz - iz;
201
+ const h00 = this.getHeightAtGrid(ix, iz);
202
+ const h10 = this.getHeightAtGrid(ix + 1, iz);
203
+ const h01 = this.getHeightAtGrid(ix, iz + 1);
204
+ const h11 = this.getHeightAtGrid(ix + 1, iz + 1);
205
+ const h0 = h00 + (h10 - h00) * fx;
206
+ const h1 = h01 + (h11 - h01) * fx;
207
+ return h0 + (h1 - h0) * fz;
208
+ }
209
+ /** Convert world position to grid coordinates */
210
+ worldToGrid(worldX, worldZ) {
211
+ const { width, depth, heightmapResolution: res } = this.data.config;
212
+ return {
213
+ x: ((worldX + width / 2) / width) * (res - 1),
214
+ y: ((worldZ + depth / 2) / depth) * (res - 1),
215
+ };
216
+ }
217
+ /** Convert grid coordinates to world position */
218
+ gridToWorld(gridX, gridZ) {
219
+ const { width, depth, heightmapResolution: res } = this.data.config;
220
+ const worldX = (gridX / (res - 1)) * width - width / 2;
221
+ const worldZ = (gridZ / (res - 1)) * depth - depth / 2;
222
+ const worldY = this.getHeightAtGrid(gridX, gridZ);
223
+ return { x: worldX, y: worldY, z: worldZ };
224
+ }
225
+ /// Get terrain normal at world position
226
+ getNormalAtWorld(worldX, worldZ) {
227
+ const { width, depth, heightmapResolution: res } = this.data.config;
228
+ const cellWidth = width / (res - 1);
229
+ const cellDepth = depth / (res - 1);
230
+ const hL = this.getHeightAtWorld(worldX - cellWidth, worldZ);
231
+ const hR = this.getHeightAtWorld(worldX + cellWidth, worldZ);
232
+ const hD = this.getHeightAtWorld(worldX, worldZ - cellDepth);
233
+ const hU = this.getHeightAtWorld(worldX, worldZ + cellDepth);
234
+ // Cross product to get normal
235
+ const dx = hR - hL;
236
+ const dz = hU - hD;
237
+ const nx = -dx / (2 * cellWidth);
238
+ const ny = 1;
239
+ const nz = -dz / (2 * cellDepth);
240
+ // Normalize
241
+ const len = Math.sqrt(nx * nx + ny * ny + nz * nz);
242
+ return { x: nx / len, y: ny / len, z: nz / len };
243
+ }
244
+ // ─── Brush Operations ──────────────────────────────────
245
+ applyBrush(brush, worldX, worldZ) {
246
+ switch (brush.type) {
247
+ case 'raise':
248
+ this.applyHeightBrush(worldX, worldZ, brush, 1);
249
+ break;
250
+ case 'lower':
251
+ this.applyHeightBrush(worldX, worldZ, brush, -1);
252
+ break;
253
+ case 'flatten':
254
+ this.applyFlattenBrush(worldX, worldZ, brush);
255
+ break;
256
+ case 'smooth':
257
+ this.applySmoothBrush(worldX, worldZ, brush);
258
+ break;
259
+ case 'noise':
260
+ this.applyNoiseBrush(worldX, worldZ, brush);
261
+ break;
262
+ case 'erosion':
263
+ this.applyErosionBrush(worldX, worldZ, brush);
264
+ break;
265
+ case 'paint':
266
+ this.applyPaintBrush(worldX, worldZ, brush);
267
+ break;
268
+ case 'paintHoles':
269
+ this.applyHoleBrush(worldX, worldZ, brush);
270
+ break;
271
+ case 'stampHeight':
272
+ this.applyStampBrush(worldX, worldZ, brush);
273
+ break;
274
+ }
275
+ }
276
+ applyHeightBrush(worldX, worldZ, brush, direction) {
277
+ const grid = this.worldToGrid(worldX, worldZ);
278
+ const { heightmapResolution: res, width, maxHeight } = this.data.config;
279
+ const gridRadius = (brush.size / (width / (res - 1))) * 0.5;
280
+ const delta = (brush.strength * direction * maxHeight) / 100;
281
+ const minX = Math.max(0, Math.floor(grid.x - gridRadius));
282
+ const maxX = Math.min(res - 1, Math.ceil(grid.x + gridRadius));
283
+ const minZ = Math.max(0, Math.floor(grid.y - gridRadius));
284
+ const maxZ = Math.min(res - 1, Math.ceil(grid.y + gridRadius));
285
+ for (let gz = minZ; gz <= maxZ; gz++) {
286
+ for (let gx = minX; gx <= maxX; gx++) {
287
+ const dx = gx - grid.x;
288
+ const dz = gz - grid.y;
289
+ const dist = Math.sqrt(dx * dx + dz * dz);
290
+ if (dist <= gridRadius) {
291
+ const falloff = this.calculateFalloff(dist / gridRadius, brush.falloff);
292
+ const currentHeight = this.getHeightAtGrid(gx, gz);
293
+ const newHeight = currentHeight + delta * falloff;
294
+ this.setHeightAtGrid(gx, gz, newHeight);
295
+ }
296
+ }
297
+ }
298
+ }
299
+ applyFlattenBrush(worldX, worldZ, brush) {
300
+ const grid = this.worldToGrid(worldX, worldZ);
301
+ const { heightmapResolution: res, width } = this.data.config;
302
+ const gridRadius = (brush.size / (width / (res - 1))) * 0.5;
303
+ const targetHeight = brush.targetHeight ?? this.getHeightAtWorld(worldX, worldZ);
304
+ const minX = Math.max(0, Math.floor(grid.x - gridRadius));
305
+ const maxX = Math.min(res - 1, Math.ceil(grid.x + gridRadius));
306
+ const minZ = Math.max(0, Math.floor(grid.y - gridRadius));
307
+ const maxZ = Math.min(res - 1, Math.ceil(grid.y + gridRadius));
308
+ for (let gz = minZ; gz <= maxZ; gz++) {
309
+ for (let gx = minX; gx <= maxX; gx++) {
310
+ const dx = gx - grid.x;
311
+ const dz = gz - grid.y;
312
+ const dist = Math.sqrt(dx * dx + dz * dz);
313
+ if (dist <= gridRadius) {
314
+ const falloff = this.calculateFalloff(dist / gridRadius, brush.falloff);
315
+ const currentHeight = this.getHeightAtGrid(gx, gz);
316
+ const newHeight = currentHeight + (targetHeight - currentHeight) * falloff * brush.strength;
317
+ this.setHeightAtGrid(gx, gz, newHeight);
318
+ }
319
+ }
320
+ }
321
+ }
322
+ applySmoothBrush(worldX, worldZ, brush) {
323
+ const grid = this.worldToGrid(worldX, worldZ);
324
+ const { heightmapResolution: res, width } = this.data.config;
325
+ const gridRadius = (brush.size / (width / (res - 1))) * 0.5;
326
+ const minX = Math.max(0, Math.floor(grid.x - gridRadius));
327
+ const maxX = Math.min(res - 1, Math.ceil(grid.x + gridRadius));
328
+ const minZ = Math.max(0, Math.floor(grid.y - gridRadius));
329
+ const maxZ = Math.min(res - 1, Math.ceil(grid.y + gridRadius));
330
+ // Collect heights first
331
+ const newHeights = [];
332
+ for (let gz = minZ; gz <= maxZ; gz++) {
333
+ for (let gx = minX; gx <= maxX; gx++) {
334
+ const dx = gx - grid.x;
335
+ const dz = gz - grid.y;
336
+ const dist = Math.sqrt(dx * dx + dz * dz);
337
+ if (dist <= gridRadius) {
338
+ // Average of neighbors
339
+ let sum = 0;
340
+ let count = 0;
341
+ for (let nz = -1; nz <= 1; nz++) {
342
+ for (let nx = -1; nx <= 1; nx++) {
343
+ const ngx = gx + nx;
344
+ const ngz = gz + nz;
345
+ if (ngx >= 0 && ngx < res && ngz >= 0 && ngz < res) {
346
+ sum += this.getHeightAtGrid(ngx, ngz);
347
+ count++;
348
+ }
349
+ }
350
+ }
351
+ const avgHeight = sum / count;
352
+ const falloff = this.calculateFalloff(dist / gridRadius, brush.falloff);
353
+ const currentHeight = this.getHeightAtGrid(gx, gz);
354
+ const newHeight = currentHeight + (avgHeight - currentHeight) * falloff * brush.strength;
355
+ newHeights.push({ gx, gz, height: newHeight });
356
+ }
357
+ }
358
+ }
359
+ // Apply new heights
360
+ for (const { gx, gz, height } of newHeights) {
361
+ this.setHeightAtGrid(gx, gz, height);
362
+ }
363
+ }
364
+ applyNoiseBrush(worldX, worldZ, brush) {
365
+ const grid = this.worldToGrid(worldX, worldZ);
366
+ const { heightmapResolution: res, width, maxHeight } = this.data.config;
367
+ const gridRadius = (brush.size / (width / (res - 1))) * 0.5;
368
+ const noiseScale = brush.noiseScale ?? 0.1;
369
+ const octaves = brush.noiseOctaves ?? 4;
370
+ const minX = Math.max(0, Math.floor(grid.x - gridRadius));
371
+ const maxX = Math.min(res - 1, Math.ceil(grid.x + gridRadius));
372
+ const minZ = Math.max(0, Math.floor(grid.y - gridRadius));
373
+ const maxZ = Math.min(res - 1, Math.ceil(grid.y + gridRadius));
374
+ for (let gz = minZ; gz <= maxZ; gz++) {
375
+ for (let gx = minX; gx <= maxX; gx++) {
376
+ const dx = gx - grid.x;
377
+ const dz = gz - grid.y;
378
+ const dist = Math.sqrt(dx * dx + dz * dz);
379
+ if (dist <= gridRadius) {
380
+ const falloff = this.calculateFalloff(dist / gridRadius, brush.falloff);
381
+ const noise = this.perlinNoise2D(gx * noiseScale, gz * noiseScale, octaves);
382
+ const delta = noise * brush.strength * maxHeight * 0.1 * falloff;
383
+ const currentHeight = this.getHeightAtGrid(gx, gz);
384
+ this.setHeightAtGrid(gx, gz, currentHeight + delta);
385
+ }
386
+ }
387
+ }
388
+ }
389
+ applyErosionBrush(worldX, worldZ, brush) {
390
+ const grid = this.worldToGrid(worldX, worldZ);
391
+ const { heightmapResolution: res, width } = this.data.config;
392
+ const gridRadius = (brush.size / (width / (res - 1))) * 0.5;
393
+ const minX = Math.max(1, Math.floor(grid.x - gridRadius));
394
+ const maxX = Math.min(res - 2, Math.ceil(grid.x + gridRadius));
395
+ const minZ = Math.max(1, Math.floor(grid.y - gridRadius));
396
+ const maxZ = Math.min(res - 2, Math.ceil(grid.y + gridRadius));
397
+ // Simple thermal erosion
398
+ const newHeights = [];
399
+ const talusAngle = 0.5; // Adjustment factor
400
+ for (let gz = minZ; gz <= maxZ; gz++) {
401
+ for (let gx = minX; gx <= maxX; gx++) {
402
+ const dx = gx - grid.x;
403
+ const dz = gz - grid.y;
404
+ const dist = Math.sqrt(dx * dx + dz * dz);
405
+ if (dist <= gridRadius) {
406
+ const falloff = this.calculateFalloff(dist / gridRadius, brush.falloff);
407
+ const h = this.getHeightAtGrid(gx, gz);
408
+ let totalDiff = 0;
409
+ const neighbors = [
410
+ this.getHeightAtGrid(gx - 1, gz),
411
+ this.getHeightAtGrid(gx + 1, gz),
412
+ this.getHeightAtGrid(gx, gz - 1),
413
+ this.getHeightAtGrid(gx, gz + 1),
414
+ ];
415
+ for (const nh of neighbors) {
416
+ const diff = h - nh;
417
+ if (diff > talusAngle) {
418
+ totalDiff += diff - talusAngle;
419
+ }
420
+ }
421
+ // Erode if slope too steep
422
+ if (totalDiff > 0) {
423
+ const erosion = totalDiff * brush.strength * falloff * 0.25;
424
+ newHeights.push({ gx, gz, height: h - erosion });
425
+ }
426
+ }
427
+ }
428
+ }
429
+ // Apply erosion
430
+ for (const { gx, gz, height } of newHeights) {
431
+ this.setHeightAtGrid(gx, gz, height);
432
+ }
433
+ }
434
+ applyPaintBrush(worldX, worldZ, brush) {
435
+ const { splatmapResolution: res, width } = this.data.config;
436
+ const layerIndex = brush.layerIndex ?? 0;
437
+ if (layerIndex >= 8) {
438
+ return;
439
+ }
440
+ const splatmapIndex = Math.floor(layerIndex / 4);
441
+ const channelIndex = layerIndex % 4;
442
+ // Convert world to splatmap coords
443
+ const smX = ((worldX + width / 2) / width) * (res - 1);
444
+ const smZ = ((worldZ + width / 2) / width) * (res - 1);
445
+ const gridRadius = (brush.size / (width / (res - 1))) * 0.5;
446
+ const minX = Math.max(0, Math.floor(smX - gridRadius));
447
+ const maxX = Math.min(res - 1, Math.ceil(smX + gridRadius));
448
+ const minZ = Math.max(0, Math.floor(smZ - gridRadius));
449
+ const maxZ = Math.min(res - 1, Math.ceil(smZ + gridRadius));
450
+ const splatmap = this.data.splatmaps[splatmapIndex];
451
+ for (let z = minZ; z <= maxZ; z++) {
452
+ for (let x = minX; x <= maxX; x++) {
453
+ const dx = x - smX;
454
+ const dz = z - smZ;
455
+ const dist = Math.sqrt(dx * dx + dz * dz);
456
+ if (dist <= gridRadius) {
457
+ const falloff = this.calculateFalloff(dist / gridRadius, brush.falloff);
458
+ const idx = (z * res + x) * 4;
459
+ const strength = brush.strength * falloff * 255;
460
+ // Add to target channel
461
+ const current = splatmap[idx + channelIndex];
462
+ const newValue = Math.min(255, current + strength);
463
+ splatmap[idx + channelIndex] = newValue;
464
+ // Normalize all channels so they sum to 255
465
+ this.normalizeSplatmapPixel(x, z);
466
+ }
467
+ }
468
+ }
469
+ this.data.metadata.modifiedAt = Date.now();
470
+ }
471
+ normalizeSplatmapPixel(x, z) {
472
+ const res = this.data.config.splatmapResolution;
473
+ let total = 0;
474
+ // Sum all 8 channels
475
+ for (let s = 0; s < 2; s++) {
476
+ const idx = (z * res + x) * 4;
477
+ for (let c = 0; c < 4; c++) {
478
+ total += this.data.splatmaps[s][idx + c];
479
+ }
480
+ }
481
+ // Normalize
482
+ if (total > 0) {
483
+ const scale = 255 / total;
484
+ for (let s = 0; s < 2; s++) {
485
+ const idx = (z * res + x) * 4;
486
+ for (let c = 0; c < 4; c++) {
487
+ this.data.splatmaps[s][idx + c] = Math.round(this.data.splatmaps[s][idx + c] * scale);
488
+ }
489
+ }
490
+ }
491
+ }
492
+ applyHoleBrush(worldX, worldZ, brush) {
493
+ const { heightmapResolution: res, width } = this.data.config;
494
+ const gridCoords = this.worldToGrid(worldX, worldZ);
495
+ const gridRadius = (brush.size / (width / (res - 1))) * 0.5;
496
+ const isAddHole = brush.strength > 0;
497
+ const minX = Math.max(0, Math.floor(gridCoords.x - gridRadius));
498
+ const maxX = Math.min(res - 1, Math.ceil(gridCoords.x + gridRadius));
499
+ const minZ = Math.max(0, Math.floor(gridCoords.y - gridRadius));
500
+ const maxZ = Math.min(res - 1, Math.ceil(gridCoords.y + gridRadius));
501
+ for (let gz = minZ; gz <= maxZ; gz++) {
502
+ for (let gx = minX; gx <= maxX; gx++) {
503
+ const dx = gx - gridCoords.x;
504
+ const dz = gz - gridCoords.y;
505
+ const dist = Math.sqrt(dx * dx + dz * dz);
506
+ if (dist <= gridRadius) {
507
+ this.data.holemap[gz * res + gx] = isAddHole ? 0 : 1;
508
+ }
509
+ }
510
+ }
511
+ this.data.metadata.modifiedAt = Date.now();
512
+ }
513
+ applyStampBrush(worldX, worldZ, brush) {
514
+ // TODO: Apply stamp texture as height
515
+ // For now, just raise
516
+ this.applyHeightBrush(worldX, worldZ, brush, 1);
517
+ }
518
+ calculateFalloff(t, falloffStrength) {
519
+ // t is 0 at center, 1 at edge
520
+ // falloffStrength: 0 = hard edge, 1 = very smooth
521
+ if (t >= 1) {
522
+ return 0;
523
+ }
524
+ if (falloffStrength <= 0) {
525
+ return 1;
526
+ }
527
+ const smoothT = t * t * (3 - 2 * t); // Smoothstep
528
+ const power = 1 + falloffStrength * 3;
529
+ return Math.pow(1 - smoothT, power);
530
+ }
531
+ // ─── Procedural Generation ─────────────────────────────
532
+ generatePerlinTerrain(scale = 0.01, octaves = 6, persistence = 0.5) {
533
+ const res = this.data.config.heightmapResolution;
534
+ for (let z = 0; z < res; z++) {
535
+ for (let x = 0; x < res; x++) {
536
+ const height = this.perlinNoise2D(x * scale, z * scale, octaves, persistence);
537
+ this.data.heightmap[z * res + x] = (height + 1) * 0.5; // Normalize to 0-1
538
+ }
539
+ }
540
+ this.data.metadata.modifiedAt = Date.now();
541
+ }
542
+ generateDiamondSquare(roughness = 0.5) {
543
+ const size = this.data.config.heightmapResolution;
544
+ // Initialize corners
545
+ this.data.heightmap[0] = Math.random();
546
+ this.data.heightmap[size - 1] = Math.random();
547
+ this.data.heightmap[(size - 1) * size] = Math.random();
548
+ this.data.heightmap[(size - 1) * size + size - 1] = Math.random();
549
+ let stepSize = size - 1;
550
+ let scale = roughness;
551
+ while (stepSize > 1) {
552
+ const halfStep = stepSize / 2;
553
+ // Diamond step
554
+ for (let z = halfStep; z < size - 1; z += stepSize) {
555
+ for (let x = halfStep; x < size - 1; x += stepSize) {
556
+ const avg = (this.data.heightmap[(z - halfStep) * size + (x - halfStep)] +
557
+ this.data.heightmap[(z - halfStep) * size + (x + halfStep)] +
558
+ this.data.heightmap[(z + halfStep) * size + (x - halfStep)] +
559
+ this.data.heightmap[(z + halfStep) * size + (x + halfStep)]) /
560
+ 4;
561
+ this.data.heightmap[z * size + x] = avg + (Math.random() - 0.5) * scale;
562
+ }
563
+ }
564
+ // Square step
565
+ for (let z = 0; z < size; z += halfStep) {
566
+ for (let x = (z + halfStep) % stepSize; x < size; x += stepSize) {
567
+ let sum = 0;
568
+ let count = 0;
569
+ if (z - halfStep >= 0) {
570
+ sum += this.data.heightmap[(z - halfStep) * size + x];
571
+ count++;
572
+ }
573
+ if (z + halfStep < size) {
574
+ sum += this.data.heightmap[(z + halfStep) * size + x];
575
+ count++;
576
+ }
577
+ if (x - halfStep >= 0) {
578
+ sum += this.data.heightmap[z * size + (x - halfStep)];
579
+ count++;
580
+ }
581
+ if (x + halfStep < size) {
582
+ sum += this.data.heightmap[z * size + (x + halfStep)];
583
+ count++;
584
+ }
585
+ this.data.heightmap[z * size + x] = sum / count + (Math.random() - 0.5) * scale;
586
+ }
587
+ }
588
+ stepSize = halfStep;
589
+ scale *= 0.5;
590
+ }
591
+ // Normalize
592
+ let min = Infinity;
593
+ let max = -Infinity;
594
+ for (let i = 0; i < this.data.heightmap.length; i++) {
595
+ min = Math.min(min, this.data.heightmap[i]);
596
+ max = Math.max(max, this.data.heightmap[i]);
597
+ }
598
+ const range = max - min;
599
+ if (range > 0) {
600
+ for (let i = 0; i < this.data.heightmap.length; i++) {
601
+ this.data.heightmap[i] = (this.data.heightmap[i] - min) / range;
602
+ }
603
+ }
604
+ this.data.metadata.modifiedAt = Date.now();
605
+ }
606
+ applyHydraulicErosion(iterations = 50000) {
607
+ const res = this.data.config.heightmapResolution;
608
+ const { maxHeight } = this.data.config;
609
+ // Erosion parameters
610
+ const inertia = 0.05;
611
+ const sedimentCapacityFactor = 4;
612
+ const minSedimentCapacity = 0.01;
613
+ const erodeSpeed = 0.3;
614
+ const depositSpeed = 0.3;
615
+ const evaporateSpeed = 0.01;
616
+ const gravity = 4;
617
+ const maxDropletLifetime = 30;
618
+ const initialWaterVolume = 1;
619
+ const initialSpeed = 1;
620
+ for (let i = 0; i < iterations; i++) {
621
+ // Start at random position
622
+ let posX = Math.random() * (res - 1);
623
+ let posZ = Math.random() * (res - 1);
624
+ let dirX = 0;
625
+ let dirZ = 0;
626
+ let speed = initialSpeed;
627
+ let water = initialWaterVolume;
628
+ let sediment = 0;
629
+ for (let lifetime = 0; lifetime < maxDropletLifetime; lifetime++) {
630
+ const cellX = Math.floor(posX);
631
+ const cellZ = Math.floor(posZ);
632
+ const cellOffsetX = posX - cellX;
633
+ const cellOffsetZ = posZ - cellZ;
634
+ // Calculate gradient
635
+ const heightNW = this.data.heightmap[cellZ * res + cellX];
636
+ const heightNE = cellX < res - 1 ? this.data.heightmap[cellZ * res + cellX + 1] : heightNW;
637
+ const heightSW = cellZ < res - 1 ? this.data.heightmap[(cellZ + 1) * res + cellX] : heightNW;
638
+ const heightSE = cellX < res - 1 && cellZ < res - 1
639
+ ? this.data.heightmap[(cellZ + 1) * res + cellX + 1]
640
+ : heightNW;
641
+ const gradientX = (heightNE - heightNW) * (1 - cellOffsetZ) + (heightSE - heightSW) * cellOffsetZ;
642
+ const gradientZ = (heightSW - heightNW) * (1 - cellOffsetX) + (heightSE - heightNE) * cellOffsetX;
643
+ // Update direction with inertia
644
+ dirX = dirX * inertia - gradientX * (1 - inertia);
645
+ dirZ = dirZ * inertia - gradientZ * (1 - inertia);
646
+ // Normalize direction
647
+ const len = Math.sqrt(dirX * dirX + dirZ * dirZ);
648
+ if (len > 0) {
649
+ dirX /= len;
650
+ dirZ /= len;
651
+ }
652
+ // Move
653
+ posX += dirX;
654
+ posZ += dirZ;
655
+ // Check bounds
656
+ if (posX < 0 || posX >= res - 1 || posZ < 0 || posZ >= res - 1 || len === 0) {
657
+ break;
658
+ }
659
+ // Calculate height difference
660
+ const newHeight = heightNW * (1 - cellOffsetX) * (1 - cellOffsetZ) +
661
+ heightNE * cellOffsetX * (1 - cellOffsetZ) +
662
+ heightSW * (1 - cellOffsetX) * cellOffsetZ +
663
+ heightSE * cellOffsetX * cellOffsetZ;
664
+ const oldHeight = this.data.heightmap[cellZ * res + cellX] * (1 - cellOffsetX) * (1 - cellOffsetZ) +
665
+ (cellX < res - 1
666
+ ? this.data.heightmap[cellZ * res + cellX + 1]
667
+ : this.data.heightmap[cellZ * res + cellX]) *
668
+ cellOffsetX *
669
+ (1 - cellOffsetZ) +
670
+ (cellZ < res - 1
671
+ ? this.data.heightmap[(cellZ + 1) * res + cellX]
672
+ : this.data.heightmap[cellZ * res + cellX]) *
673
+ (1 - cellOffsetX) *
674
+ cellOffsetZ +
675
+ (cellX < res - 1 && cellZ < res - 1
676
+ ? this.data.heightmap[(cellZ + 1) * res + cellX + 1]
677
+ : this.data.heightmap[cellZ * res + cellX]) *
678
+ cellOffsetX *
679
+ cellOffsetZ;
680
+ const heightDiff = newHeight - oldHeight;
681
+ // Calculate sediment capacity
682
+ const sedimentCapacity = Math.max(-heightDiff * speed * water * sedimentCapacityFactor, minSedimentCapacity);
683
+ // Deposit or erode
684
+ if (sediment > sedimentCapacity || heightDiff > 0) {
685
+ // Deposit
686
+ const depositAmount = heightDiff > 0
687
+ ? Math.min(heightDiff, sediment)
688
+ : (sediment - sedimentCapacity) * depositSpeed;
689
+ sediment -= depositAmount;
690
+ this.data.heightmap[cellZ * res + cellX] +=
691
+ depositAmount * (1 - cellOffsetX) * (1 - cellOffsetZ);
692
+ if (cellX < res - 1) {
693
+ this.data.heightmap[cellZ * res + cellX + 1] +=
694
+ depositAmount * cellOffsetX * (1 - cellOffsetZ);
695
+ }
696
+ if (cellZ < res - 1) {
697
+ this.data.heightmap[(cellZ + 1) * res + cellX] +=
698
+ depositAmount * (1 - cellOffsetX) * cellOffsetZ;
699
+ }
700
+ if (cellX < res - 1 && cellZ < res - 1) {
701
+ this.data.heightmap[(cellZ + 1) * res + cellX + 1] +=
702
+ depositAmount * cellOffsetX * cellOffsetZ;
703
+ }
704
+ }
705
+ else {
706
+ // Erode
707
+ const erodeAmount = Math.min((sedimentCapacity - sediment) * erodeSpeed, -heightDiff);
708
+ this.data.heightmap[cellZ * res + cellX] -=
709
+ erodeAmount * (1 - cellOffsetX) * (1 - cellOffsetZ);
710
+ if (cellX < res - 1) {
711
+ this.data.heightmap[cellZ * res + cellX + 1] -=
712
+ erodeAmount * cellOffsetX * (1 - cellOffsetZ);
713
+ }
714
+ if (cellZ < res - 1) {
715
+ this.data.heightmap[(cellZ + 1) * res + cellX] -=
716
+ erodeAmount * (1 - cellOffsetX) * cellOffsetZ;
717
+ }
718
+ if (cellX < res - 1 && cellZ < res - 1) {
719
+ this.data.heightmap[(cellZ + 1) * res + cellX + 1] -=
720
+ erodeAmount * cellOffsetX * cellOffsetZ;
721
+ }
722
+ sediment += erodeAmount;
723
+ }
724
+ // Update speed and water
725
+ speed = Math.sqrt(Math.max(0, speed * speed + heightDiff * gravity));
726
+ water *= 1 - evaporateSpeed;
727
+ }
728
+ }
729
+ // Clamp heights
730
+ for (let i = 0; i < this.data.heightmap.length; i++) {
731
+ this.data.heightmap[i] = Math.max(0, Math.min(1, this.data.heightmap[i]));
732
+ }
733
+ this.data.metadata.modifiedAt = Date.now();
734
+ }
735
+ // ─── Perlin Noise ──────────────────────────────────────
736
+ perlinNoise2D(x, y, octaves = 6, persistence = 0.5) {
737
+ let total = 0;
738
+ let frequency = 1;
739
+ let amplitude = 1;
740
+ let maxValue = 0;
741
+ for (let i = 0; i < octaves; i++) {
742
+ total += this.noise2D(x * frequency, y * frequency) * amplitude;
743
+ maxValue += amplitude;
744
+ amplitude *= persistence;
745
+ frequency *= 2;
746
+ }
747
+ return total / maxValue;
748
+ }
749
+ noise2D(x, y) {
750
+ // Simple hash-based noise
751
+ const X = Math.floor(x) & 255;
752
+ const Y = Math.floor(y) & 255;
753
+ const xf = x - Math.floor(x);
754
+ const yf = y - Math.floor(y);
755
+ const topRight = this.dot2D(X + 1, Y, xf - 1, yf);
756
+ const topLeft = this.dot2D(X, Y, xf, yf);
757
+ const bottomRight = this.dot2D(X + 1, Y + 1, xf - 1, yf - 1);
758
+ const bottomLeft = this.dot2D(X, Y + 1, xf, yf - 1);
759
+ const u = this.fade(xf);
760
+ const v = this.fade(yf);
761
+ return this.lerp(this.lerp(topLeft, topRight, u), this.lerp(bottomLeft, bottomRight, u), v);
762
+ }
763
+ dot2D(ix, iy, x, y) {
764
+ // Pseudo-random gradient
765
+ const random = this.hash(ix, iy);
766
+ const angle = random * Math.PI * 2;
767
+ return x * Math.cos(angle) + y * Math.sin(angle);
768
+ }
769
+ hash(x, y) {
770
+ const n = x + y * 57;
771
+ const nn = (n << 13) ^ n;
772
+ return ((nn * (nn * nn * 15731 + 789221) + 1376312589) & 0x7fffffff) / 2147483648.0;
773
+ }
774
+ fade(t) {
775
+ return t * t * t * (t * (t * 6 - 15) + 10);
776
+ }
777
+ lerp(a, b, t) {
778
+ return a + t * (b - a);
779
+ }
780
+ // ─── Foliage ───────────────────────────────────────────
781
+ addDetailPrototype(prototype) {
782
+ this.data.detailPrototypes.push(prototype);
783
+ // Create corresponding density map
784
+ const res = this.data.config.detailResolution;
785
+ this.data.detailMaps.push(new Uint8Array(res * res));
786
+ this.data.metadata.modifiedAt = Date.now();
787
+ }
788
+ paintDetail(worldX, worldZ, prototypeIndex, radius, density) {
789
+ if (prototypeIndex >= this.data.detailMaps.length) {
790
+ return;
791
+ }
792
+ const { width, detailResolution: res } = this.data.config;
793
+ const densityMap = this.data.detailMaps[prototypeIndex];
794
+ const gridX = ((worldX + width / 2) / width) * (res - 1);
795
+ const gridZ = ((worldZ + width / 2) / width) * (res - 1);
796
+ const gridRadius = (radius / width) * res;
797
+ const minX = Math.max(0, Math.floor(gridX - gridRadius));
798
+ const maxX = Math.min(res - 1, Math.ceil(gridX + gridRadius));
799
+ const minZ = Math.max(0, Math.floor(gridZ - gridRadius));
800
+ const maxZ = Math.min(res - 1, Math.ceil(gridZ + gridRadius));
801
+ for (let z = minZ; z <= maxZ; z++) {
802
+ for (let x = minX; x <= maxX; x++) {
803
+ const dx = x - gridX;
804
+ const dz = z - gridZ;
805
+ const dist = Math.sqrt(dx * dx + dz * dz);
806
+ if (dist <= gridRadius) {
807
+ const falloff = 1 - dist / gridRadius;
808
+ const idx = z * res + x;
809
+ const current = densityMap[idx];
810
+ densityMap[idx] = Math.min(255, current + density * falloff * 255);
811
+ }
812
+ }
813
+ }
814
+ this.data.metadata.modifiedAt = Date.now();
815
+ }
816
+ scatterFoliage(prototypeIndex, minSlope = 0, maxSlope = 45, minHeight = 0, maxHeight = 1) {
817
+ if (prototypeIndex >= this.data.detailPrototypes.length) {
818
+ return;
819
+ }
820
+ const { width, depth, heightmapResolution: hmRes, detailResolution: res } = this.data.config;
821
+ const densityMap = this.data.detailMaps[prototypeIndex];
822
+ const prototype = this.data.detailPrototypes[prototypeIndex];
823
+ for (let z = 0; z < res; z++) {
824
+ for (let x = 0; x < res; x++) {
825
+ const worldX = (x / (res - 1)) * width - width / 2;
826
+ const worldZ = (z / (res - 1)) * depth - depth / 2;
827
+ // Get terrain properties at this point
828
+ const height = this.getHeightAtWorld(worldX, worldZ) / this.data.config.maxHeight;
829
+ const normal = this.getNormalAtWorld(worldX, worldZ);
830
+ const slope = Math.acos(normal.y) * (180 / Math.PI);
831
+ // Check constraints
832
+ const isValidHeight = height >= minHeight && height <= maxHeight;
833
+ const isValidSlope = slope >= minSlope && slope <= maxSlope;
834
+ if (isValidHeight && isValidSlope) {
835
+ // Apply noise-based density
836
+ const noise = (this.perlinNoise2D(x * 0.1, z * 0.1, 2) + 1) * 0.5;
837
+ const baseDensity = prototype.density * noise;
838
+ densityMap[z * res + x] = Math.min(255, densityMap[z * res + x] + baseDensity * 255);
839
+ }
840
+ }
841
+ }
842
+ this.data.metadata.modifiedAt = Date.now();
843
+ }
844
+ // ─── Trees ─────────────────────────────────────────────
845
+ addTreePrototype(prototype) {
846
+ this.data.treePrototypes.push(prototype);
847
+ this.data.metadata.modifiedAt = Date.now();
848
+ }
849
+ addTree(worldX, worldZ, prototypeId, scale, rotation) {
850
+ const prototype = this.data.treePrototypes.find((p) => p.id === prototypeId);
851
+ if (!prototype) {
852
+ return null;
853
+ }
854
+ const height = this.getHeightAtWorld(worldX, worldZ);
855
+ const actualScale = scale ?? prototype.minScale + Math.random() * (prototype.maxScale - prototype.minScale);
856
+ const actualRotation = rotation ?? (prototype.randomRotation ? Math.random() * Math.PI * 2 : 0);
857
+ const instance = {
858
+ position: { x: worldX, y: height, z: worldZ },
859
+ rotation: actualRotation,
860
+ scale: { x: actualScale, y: actualScale, z: actualScale },
861
+ prototypeId,
862
+ color: { r: 1, g: 1, b: 1, a: 1 },
863
+ lightmapColor: { r: 1, g: 1, b: 1, a: 1 },
864
+ };
865
+ this.data.trees.push(instance);
866
+ this.data.metadata.modifiedAt = Date.now();
867
+ return instance;
868
+ }
869
+ scatterTrees(prototypeId, density, minSlope = 0, maxSlope = 30, minHeight = 0, maxHeight = 1, minSpacing = 5) {
870
+ const prototype = this.data.treePrototypes.find((p) => p.id === prototypeId);
871
+ if (!prototype) {
872
+ return 0;
873
+ }
874
+ const { width, depth } = this.data.config;
875
+ let treesAdded = 0;
876
+ // Use Poisson disk sampling for natural distribution
877
+ const cellSize = minSpacing / Math.SQRT2;
878
+ const gridWidth = Math.ceil(width / cellSize);
879
+ const gridDepth = Math.ceil(depth / cellSize);
880
+ const grid = [];
881
+ for (let i = 0; i < gridWidth; i++) {
882
+ grid[i] = [];
883
+ for (let j = 0; j < gridDepth; j++) {
884
+ grid[i][j] = null;
885
+ }
886
+ }
887
+ const numAttempts = Math.floor(width * depth * density);
888
+ const activeList = [];
889
+ // Start with a random point
890
+ const startX = Math.random() * width - width / 2;
891
+ const startZ = Math.random() * depth - depth / 2;
892
+ const startHeight = this.getHeightAtWorld(startX, startZ);
893
+ activeList.push({ x: startX, y: startHeight, z: startZ });
894
+ for (let attempt = 0; attempt < numAttempts && activeList.length > 0; attempt++) {
895
+ const idx = Math.floor(Math.random() * activeList.length);
896
+ const point = activeList[idx];
897
+ let found = false;
898
+ for (let k = 0; k < 30; k++) {
899
+ const angle = Math.random() * Math.PI * 2;
900
+ const r = minSpacing + Math.random() * minSpacing;
901
+ const newX = point.x + Math.cos(angle) * r;
902
+ const newZ = point.z + Math.sin(angle) * r;
903
+ // Check bounds
904
+ if (newX < -width / 2 || newX > width / 2 || newZ < -depth / 2 || newZ > depth / 2) {
905
+ continue;
906
+ }
907
+ // Check terrain constraints
908
+ const newHeight = this.getHeightAtWorld(newX, newZ) / this.data.config.maxHeight;
909
+ const normal = this.getNormalAtWorld(newX, newZ);
910
+ const slope = Math.acos(normal.y) * (180 / Math.PI);
911
+ if (newHeight < minHeight ||
912
+ newHeight > maxHeight ||
913
+ slope < minSlope ||
914
+ slope > maxSlope) {
915
+ continue;
916
+ }
917
+ // Check grid for nearby points
918
+ const gridX = Math.floor((newX + width / 2) / cellSize);
919
+ const gridZ = Math.floor((newZ + depth / 2) / cellSize);
920
+ let tooClose = false;
921
+ for (let di = -2; di <= 2 && !tooClose; di++) {
922
+ for (let dj = -2; dj <= 2 && !tooClose; dj++) {
923
+ const ni = gridX + di;
924
+ const nj = gridZ + dj;
925
+ if (ni >= 0 && ni < gridWidth && nj >= 0 && nj < gridDepth && grid[ni][nj]) {
926
+ const neighbor = grid[ni][nj];
927
+ const dx = neighbor.x - newX;
928
+ const dz = neighbor.z - newZ;
929
+ if (dx * dx + dz * dz < minSpacing * minSpacing) {
930
+ tooClose = true;
931
+ }
932
+ }
933
+ }
934
+ }
935
+ if (!tooClose) {
936
+ const newPoint = { x: newX, y: this.getHeightAtWorld(newX, newZ), z: newZ };
937
+ grid[gridX][gridZ] = newPoint;
938
+ activeList.push(newPoint);
939
+ this.addTree(newX, newZ, prototypeId);
940
+ treesAdded++;
941
+ found = true;
942
+ break;
943
+ }
944
+ }
945
+ if (!found) {
946
+ activeList.splice(idx, 1);
947
+ }
948
+ }
949
+ return treesAdded;
950
+ }
951
+ removeTreesInRadius(worldX, worldZ, radius) {
952
+ const initialCount = this.data.trees.length;
953
+ this.data.trees = this.data.trees.filter((tree) => {
954
+ const dx = tree.position.x - worldX;
955
+ const dz = tree.position.z - worldZ;
956
+ return dx * dx + dz * dz > radius * radius;
957
+ });
958
+ this.data.metadata.modifiedAt = Date.now();
959
+ return initialCount - this.data.trees.length;
960
+ }
961
+ // ─── Undo/Redo ─────────────────────────────────────────
962
+ recordHeightChange(gridX, gridZ, oldValue, newValue) {
963
+ const operation = {
964
+ type: 'height',
965
+ gridX,
966
+ gridZ,
967
+ oldValue,
968
+ newValue,
969
+ timestamp: Date.now(),
970
+ };
971
+ this.undoStack.push(operation);
972
+ if (this.undoStack.length > this.maxUndoSteps) {
973
+ this.undoStack.shift();
974
+ }
975
+ this.redoStack = [];
976
+ }
977
+ undo() {
978
+ const operation = this.undoStack.pop();
979
+ if (!operation) {
980
+ return false;
981
+ }
982
+ if (operation.type === 'height') {
983
+ const res = this.data.config.heightmapResolution;
984
+ this.data.heightmap[operation.gridZ * res + operation.gridX] = operation.oldValue;
985
+ }
986
+ this.redoStack.push(operation);
987
+ this.data.metadata.modifiedAt = Date.now();
988
+ return true;
989
+ }
990
+ redo() {
991
+ const operation = this.redoStack.pop();
992
+ if (!operation) {
993
+ return false;
994
+ }
995
+ if (operation.type === 'height') {
996
+ const res = this.data.config.heightmapResolution;
997
+ this.data.heightmap[operation.gridZ * res + operation.gridX] = operation.newValue;
998
+ }
999
+ this.undoStack.push(operation);
1000
+ this.data.metadata.modifiedAt = Date.now();
1001
+ return true;
1002
+ }
1003
+ // ─── Serialization ─────────────────────────────────────
1004
+ getData() {
1005
+ return this.data;
1006
+ }
1007
+ setData(data) {
1008
+ this.data = data;
1009
+ this.undoStack = [];
1010
+ this.redoStack = [];
1011
+ }
1012
+ serialize() {
1013
+ return JSON.stringify({
1014
+ ...this.data,
1015
+ heightmap: Array.from(this.data.heightmap),
1016
+ splatmaps: this.data.splatmaps.map((s) => Array.from(s)),
1017
+ holemap: Array.from(this.data.holemap),
1018
+ detailMaps: this.data.detailMaps.map((d) => Array.from(d)),
1019
+ });
1020
+ }
1021
+ static deserialize(json) {
1022
+ const data = JSON.parse(json);
1023
+ const terrain = new TerrainSystem(data.config);
1024
+ terrain.data = {
1025
+ ...data,
1026
+ heightmap: new Float32Array(data.heightmap),
1027
+ splatmaps: data.splatmaps.map((s) => new Uint8Array(s)),
1028
+ holemap: new Uint8Array(data.holemap),
1029
+ detailMaps: data.detailMaps.map((d) => new Uint8Array(d)),
1030
+ };
1031
+ return terrain;
1032
+ }
1033
+ // ─── Export Heightmap ──────────────────────────────────
1034
+ exportHeightmapAsRAW() {
1035
+ const res = this.data.config.heightmapResolution;
1036
+ const buffer = new ArrayBuffer(res * res * 2); // 16-bit
1037
+ const view = new Uint16Array(buffer);
1038
+ for (let i = 0; i < this.data.heightmap.length; i++) {
1039
+ view[i] = Math.round(this.data.heightmap[i] * 65535);
1040
+ }
1041
+ return buffer;
1042
+ }
1043
+ importHeightmapFromRAW(buffer, is16bit = true) {
1044
+ const res = this.data.config.heightmapResolution;
1045
+ if (is16bit) {
1046
+ const view = new Uint16Array(buffer);
1047
+ const expectedSize = res * res;
1048
+ if (view.length !== expectedSize) {
1049
+ throw new Error(`RAW size mismatch: expected ${expectedSize}, got ${view.length}`);
1050
+ }
1051
+ for (let i = 0; i < view.length; i++) {
1052
+ this.data.heightmap[i] = view[i] / 65535;
1053
+ }
1054
+ }
1055
+ else {
1056
+ const view = new Uint8Array(buffer);
1057
+ const expectedSize = res * res;
1058
+ if (view.length !== expectedSize) {
1059
+ throw new Error(`RAW size mismatch: expected ${expectedSize}, got ${view.length}`);
1060
+ }
1061
+ for (let i = 0; i < view.length; i++) {
1062
+ this.data.heightmap[i] = view[i] / 255;
1063
+ }
1064
+ }
1065
+ this.data.metadata.modifiedAt = Date.now();
1066
+ }
1067
+ exportSplatmapAsPNG(splatmapIndex) {
1068
+ if (splatmapIndex >= this.data.splatmaps.length) {
1069
+ return null;
1070
+ }
1071
+ const res = this.data.config.splatmapResolution;
1072
+ const splatmap = this.data.splatmaps[splatmapIndex];
1073
+ const imageData = new ImageData(res, res);
1074
+ for (let i = 0; i < splatmap.length; i++) {
1075
+ imageData.data[i] = splatmap[i];
1076
+ }
1077
+ return imageData;
1078
+ }
1079
+ }
1080
+ // ============================================================
1081
+ // Factory Functions
1082
+ // ============================================================
1083
+ function createTerrain(config) {
1084
+ return new TerrainSystem(config);
1085
+ }
1086
+ function createFlatTerrain(config) {
1087
+ const terrain = new TerrainSystem(config);
1088
+ // Already flat (heights = 0)
1089
+ return terrain;
1090
+ }
1091
+ function createHillyTerrain(config) {
1092
+ const terrain = new TerrainSystem(config);
1093
+ terrain.generatePerlinTerrain(0.005, 6, 0.5);
1094
+ return terrain;
1095
+ }
1096
+ function createMountainousTerrain(config) {
1097
+ const terrain = new TerrainSystem(config);
1098
+ terrain.generateDiamondSquare(0.6);
1099
+ terrain.applyHydraulicErosion(30000);
1100
+ return terrain;
1101
+ }
1102
+ function createIslandTerrain(config) {
1103
+ const terrain = new TerrainSystem(config);
1104
+ const res = terrain.getData().config.heightmapResolution;
1105
+ const data = terrain.getData();
1106
+ // Generate hills
1107
+ terrain.generatePerlinTerrain(0.008, 5, 0.5);
1108
+ // Apply radial falloff for island shape
1109
+ const centerX = res / 2;
1110
+ const centerZ = res / 2;
1111
+ const maxDist = Math.min(centerX, centerZ) * 0.9;
1112
+ for (let z = 0; z < res; z++) {
1113
+ for (let x = 0; x < res; x++) {
1114
+ const dx = x - centerX;
1115
+ const dz = z - centerZ;
1116
+ const dist = Math.sqrt(dx * dx + dz * dz);
1117
+ const falloff = Math.max(0, 1 - dist / maxDist);
1118
+ const smoothFalloff = falloff * falloff * (3 - 2 * falloff); // Smoothstep
1119
+ data.heightmap[z * res + x] *= smoothFalloff;
1120
+ }
1121
+ }
1122
+ terrain.setData(data);
1123
+ return terrain;
1124
+ }
1125
+
1126
+ exports.DEFAULT_BRUSH = DEFAULT_BRUSH;
1127
+ exports.DEFAULT_TERRAIN_CONFIG = DEFAULT_TERRAIN_CONFIG;
1128
+ exports.TerrainSystem = TerrainSystem;
1129
+ exports.createFlatTerrain = createFlatTerrain;
1130
+ exports.createGrassDetail = createGrassDetail;
1131
+ exports.createHillyTerrain = createHillyTerrain;
1132
+ exports.createIslandTerrain = createIslandTerrain;
1133
+ exports.createMountainousTerrain = createMountainousTerrain;
1134
+ exports.createTerrain = createTerrain;
1135
+ exports.createTerrainLayer = createTerrainLayer;
1136
+ exports.createTreePrototype = createTreePrototype;
1137
+ //# sourceMappingURL=TerrainSystem.js.map