@nice2dev/game-engine 1.0.5 → 1.0.11

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