cyberia 3.1.3 → 3.2.9

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 (377) hide show
  1. package/.env.example +0 -2
  2. package/.github/workflows/engine-cyberia.cd.yml +10 -8
  3. package/.github/workflows/engine-cyberia.ci.yml +12 -29
  4. package/.github/workflows/ghpkg.ci.yml +4 -4
  5. package/.github/workflows/npmpkg.ci.yml +28 -11
  6. package/.github/workflows/publish.ci.yml +21 -2
  7. package/.github/workflows/pwa-microservices-template-page.cd.yml +4 -5
  8. package/.github/workflows/pwa-microservices-template-test.ci.yml +3 -3
  9. package/.github/workflows/release.cd.yml +14 -10
  10. package/CHANGELOG.md +783 -1
  11. package/CLI-HELP.md +95 -18
  12. package/Dockerfile +0 -2
  13. package/README.md +290 -220
  14. package/bin/build.js +24 -7
  15. package/bin/cyberia.js +2838 -252
  16. package/bin/deploy.js +747 -125
  17. package/bin/file.js +9 -0
  18. package/bin/index.js +2838 -252
  19. package/bin/vs.js +1 -1
  20. package/conf.js +99 -65
  21. package/deployment.yaml +18 -164
  22. package/hardhat/hardhat.config.js +13 -13
  23. package/hardhat/ignition/modules/ObjectLayerToken.js +1 -1
  24. package/hardhat/package-lock.json +2559 -5864
  25. package/hardhat/package.json +14 -23
  26. package/hardhat/scripts/deployObjectLayerToken.js +1 -1
  27. package/hardhat/test/ObjectLayerToken.js +4 -2
  28. package/hardhat/types/ethers-contracts/ObjectLayerToken.ts +690 -0
  29. package/hardhat/types/ethers-contracts/common.ts +92 -0
  30. package/hardhat/types/ethers-contracts/factories/ObjectLayerToken__factory.ts +1055 -0
  31. package/hardhat/types/ethers-contracts/factories/index.ts +4 -0
  32. package/hardhat/types/ethers-contracts/hardhat.d.ts +47 -0
  33. package/hardhat/types/ethers-contracts/index.ts +6 -0
  34. package/jsconfig.json +1 -1
  35. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +6 -5
  36. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +6 -5
  37. package/manifests/deployment/dd-cyberia-development/deployment.yaml +18 -164
  38. package/manifests/deployment/dd-cyberia-development/proxy.yaml +7 -79
  39. package/manifests/deployment/dd-default-development/deployment.yaml +2 -6
  40. package/manifests/deployment/dd-test-development/deployment.yaml +112 -28
  41. package/manifests/deployment/dd-test-development/proxy.yaml +46 -1
  42. package/manifests/deployment/playwright/deployment.yaml +1 -1
  43. package/nodemon.json +1 -1
  44. package/package.json +39 -24
  45. package/proxy.yaml +7 -79
  46. package/scripts/k3s-node-setup.sh +2 -2
  47. package/scripts/nat-iptables.sh +103 -18
  48. package/scripts/rhel-grpc-setup.sh +56 -0
  49. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +58 -14
  50. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +23 -14
  51. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +5 -0
  52. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +148 -20
  53. package/src/api/core/core.controller.js +10 -10
  54. package/src/api/core/core.service.js +10 -10
  55. package/src/api/crypto/crypto.controller.js +8 -8
  56. package/src/api/crypto/crypto.service.js +8 -8
  57. package/src/api/cyberia-action/cyberia-action.controller.js +74 -0
  58. package/src/api/cyberia-action/cyberia-action.model.js +87 -0
  59. package/src/api/cyberia-action/cyberia-action.router.js +27 -0
  60. package/src/api/cyberia-action/cyberia-action.service.js +42 -0
  61. package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +93 -0
  62. package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +36 -0
  63. package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +29 -0
  64. package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +51 -0
  65. package/src/api/cyberia-entity/cyberia-entity.controller.js +74 -0
  66. package/src/api/cyberia-entity/cyberia-entity.model.js +24 -0
  67. package/src/api/cyberia-entity/cyberia-entity.router.js +27 -0
  68. package/src/api/cyberia-entity/cyberia-entity.service.js +42 -0
  69. package/src/api/cyberia-instance/cyberia-fallback-world.js +178 -0
  70. package/src/api/cyberia-instance/cyberia-instance.controller.js +92 -0
  71. package/src/api/cyberia-instance/cyberia-instance.model.js +87 -0
  72. package/src/api/cyberia-instance/cyberia-instance.router.js +63 -0
  73. package/src/api/cyberia-instance/cyberia-instance.service.js +156 -0
  74. package/src/api/cyberia-instance/cyberia-portal-connector.js +260 -0
  75. package/src/api/cyberia-instance/cyberia-world-generator.js +505 -0
  76. package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +74 -0
  77. package/src/api/cyberia-instance-conf/cyberia-instance-conf.defaults.js +574 -0
  78. package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +231 -0
  79. package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +27 -0
  80. package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +46 -0
  81. package/src/api/cyberia-map/cyberia-map.controller.js +79 -0
  82. package/src/api/cyberia-map/cyberia-map.model.js +30 -0
  83. package/src/api/cyberia-map/cyberia-map.router.js +40 -0
  84. package/src/api/cyberia-map/cyberia-map.service.js +74 -0
  85. package/src/api/cyberia-quest/cyberia-quest.controller.js +74 -0
  86. package/src/api/cyberia-quest/cyberia-quest.model.js +67 -0
  87. package/src/api/cyberia-quest/cyberia-quest.router.js +27 -0
  88. package/src/api/cyberia-quest/cyberia-quest.service.js +42 -0
  89. package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.js +74 -0
  90. package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +49 -0
  91. package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +27 -0
  92. package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +42 -0
  93. package/src/api/default/default.controller.js +10 -10
  94. package/src/api/default/default.service.js +10 -10
  95. package/src/api/document/document.controller.js +12 -12
  96. package/src/api/document/document.model.js +10 -16
  97. package/src/api/file/file.controller.js +8 -8
  98. package/src/api/file/file.model.js +10 -10
  99. package/src/api/file/file.ref.json +18 -0
  100. package/src/api/file/file.service.js +36 -36
  101. package/src/api/instance/instance.controller.js +10 -10
  102. package/src/api/instance/instance.model.js +4 -10
  103. package/src/api/instance/instance.service.js +10 -10
  104. package/src/api/ipfs/ipfs.controller.js +15 -36
  105. package/src/api/ipfs/ipfs.model.js +47 -47
  106. package/src/api/ipfs/ipfs.router.js +8 -13
  107. package/src/api/ipfs/ipfs.service.js +67 -129
  108. package/src/api/object-layer/object-layer.controller.js +12 -12
  109. package/src/api/object-layer/object-layer.model.js +4 -17
  110. package/src/api/object-layer/object-layer.router.js +30 -0
  111. package/src/api/object-layer/object-layer.service.js +126 -43
  112. package/src/api/object-layer-render-frames/object-layer-render-frames.controller.js +10 -10
  113. package/src/api/object-layer-render-frames/object-layer-render-frames.model.js +6 -16
  114. package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +18 -14
  115. package/src/api/test/test.controller.js +8 -8
  116. package/src/api/test/test.service.js +8 -8
  117. package/src/api/user/guest.service.js +99 -0
  118. package/src/api/user/user.controller.js +6 -6
  119. package/src/api/user/user.model.js +8 -13
  120. package/src/api/user/user.service.js +11 -27
  121. package/src/cli/cluster.js +68 -21
  122. package/src/cli/db.js +753 -825
  123. package/src/cli/deploy.js +215 -125
  124. package/src/cli/env.js +29 -0
  125. package/src/cli/fs.js +82 -8
  126. package/src/cli/image.js +43 -1
  127. package/src/cli/index.js +74 -3
  128. package/src/cli/kubectl.js +211 -0
  129. package/src/cli/release.js +340 -0
  130. package/src/cli/repository.js +475 -74
  131. package/src/cli/run.js +582 -43
  132. package/src/cli/secrets.js +73 -0
  133. package/src/cli/ssh.js +1 -1
  134. package/src/cli/static.js +43 -115
  135. package/src/cli/test.js +3 -3
  136. package/src/client/Cryptokoyn.index.js +18 -22
  137. package/src/client/CyberiaPortal.index.js +19 -24
  138. package/src/client/Default.index.js +21 -34
  139. package/src/client/Itemledger.index.js +20 -27
  140. package/src/client/Underpost.index.js +19 -24
  141. package/src/client/components/core/404.js +4 -4
  142. package/src/client/components/core/500.js +4 -4
  143. package/src/client/components/core/Account.js +73 -60
  144. package/src/client/components/core/AgGrid.js +23 -33
  145. package/src/client/components/core/Alert.js +12 -13
  146. package/src/client/components/core/AppStore.js +69 -0
  147. package/src/client/components/core/Auth.js +35 -37
  148. package/src/client/components/core/Badge.js +7 -13
  149. package/src/client/components/core/BtnIcon.js +15 -17
  150. package/src/client/components/core/CalendarCore.js +43 -64
  151. package/src/client/components/core/Chat.js +13 -15
  152. package/src/client/components/core/ClientEvents.js +87 -0
  153. package/src/client/components/core/ColorPaletteElement.js +309 -0
  154. package/src/client/components/core/Content.js +17 -14
  155. package/src/client/components/core/Css.js +15 -71
  156. package/src/client/components/core/CssCore.js +12 -16
  157. package/src/client/components/core/D3Chart.js +4 -4
  158. package/src/client/components/core/Docs.js +64 -91
  159. package/src/client/components/core/DropDown.js +194 -96
  160. package/src/client/components/core/EventBus.js +92 -0
  161. package/src/client/components/core/EventsUI.js +14 -17
  162. package/src/client/components/core/FileExplorer.js +96 -228
  163. package/src/client/components/core/FullScreen.js +47 -75
  164. package/src/client/components/core/Input.js +24 -69
  165. package/src/client/components/core/Keyboard.js +26 -19
  166. package/src/client/components/core/KeyboardAvoidance.js +145 -0
  167. package/src/client/components/core/LoadingAnimation.js +25 -31
  168. package/src/client/components/core/LogIn.js +43 -43
  169. package/src/client/components/core/LogOut.js +25 -16
  170. package/src/client/components/core/Modal.js +462 -179
  171. package/src/client/components/core/NotificationManager.js +14 -18
  172. package/src/client/components/core/Panel.js +54 -51
  173. package/src/client/components/core/PanelForm.js +44 -144
  174. package/src/client/components/core/Polyhedron.js +110 -214
  175. package/src/client/components/core/PublicProfile.js +39 -32
  176. package/src/client/components/core/Recover.js +48 -44
  177. package/src/client/components/core/Responsive.js +88 -32
  178. package/src/client/components/core/RichText.js +9 -18
  179. package/src/client/components/core/Router.js +24 -3
  180. package/src/client/components/core/SearchBox.js +37 -37
  181. package/src/client/components/core/SignUp.js +39 -30
  182. package/src/client/components/core/SocketIo.js +112 -30
  183. package/src/client/components/core/SocketIoHandler.js +75 -0
  184. package/src/client/components/core/Stream.js +143 -95
  185. package/src/client/components/core/ToggleSwitch.js +8 -20
  186. package/src/client/components/core/ToolTip.js +5 -17
  187. package/src/client/components/core/Translate.js +56 -59
  188. package/src/client/components/core/Validator.js +26 -16
  189. package/src/client/components/core/Wallet.js +15 -26
  190. package/src/client/components/core/Webhook.js +40 -7
  191. package/src/client/components/core/Worker.js +163 -27
  192. package/src/client/components/core/windowGetDimensions.js +7 -7
  193. package/src/client/components/cryptokoyn/{MenuCryptokoyn.js → AppShellCryptokoyn.js} +59 -59
  194. package/src/client/components/cryptokoyn/AppStoreCryptokoyn.js +5 -0
  195. package/src/client/components/cryptokoyn/CssCryptokoyn.js +15 -15
  196. package/src/client/components/cryptokoyn/LogInCryptokoyn.js +9 -7
  197. package/src/client/components/cryptokoyn/LogOutCryptokoyn.js +8 -6
  198. package/src/client/components/cryptokoyn/RouterCryptokoyn.js +37 -0
  199. package/src/client/components/cryptokoyn/SettingsCryptokoyn.js +4 -4
  200. package/src/client/components/cryptokoyn/SignUpCryptokoyn.js +6 -4
  201. package/src/client/components/cryptokoyn/SocketIoCryptokoyn.js +3 -51
  202. package/src/client/components/cyberia/InstanceEngineCyberia.js +781 -0
  203. package/src/client/components/cyberia/MapEngineCyberia.js +1836 -2
  204. package/src/client/components/cyberia/ObjectLayerEngine.js +19 -0
  205. package/src/client/components/cyberia/ObjectLayerEngineModal.js +1220 -99
  206. package/src/client/components/cyberia/ObjectLayerEngineViewer.js +252 -316
  207. package/src/client/components/cyberia-portal/{MenuCyberiaPortal.js → AppShellCyberiaPortal.js} +136 -103
  208. package/src/client/components/cyberia-portal/AppStoreCyberiaPortal.js +5 -0
  209. package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +462 -32
  210. package/src/client/components/cyberia-portal/CssCyberiaPortal.js +15 -15
  211. package/src/client/components/cyberia-portal/LogInCyberiaPortal.js +9 -7
  212. package/src/client/components/cyberia-portal/LogOutCyberiaPortal.js +8 -6
  213. package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +4 -4
  214. package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +60 -0
  215. package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +4 -4
  216. package/src/client/components/cyberia-portal/SignUpCyberiaPortal.js +6 -4
  217. package/src/client/components/cyberia-portal/SocketIoCyberiaPortal.js +3 -49
  218. package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +8 -4
  219. package/src/client/components/default/{MenuDefault.js → AppShellDefault.js} +91 -91
  220. package/src/client/components/default/AppStoreDefault.js +5 -0
  221. package/src/client/components/default/CssDefault.js +12 -12
  222. package/src/client/components/default/LogInDefault.js +9 -7
  223. package/src/client/components/default/LogOutDefault.js +8 -6
  224. package/src/client/components/default/RouterDefault.js +47 -0
  225. package/src/client/components/default/SettingsDefault.js +4 -4
  226. package/src/client/components/default/SignUpDefault.js +6 -4
  227. package/src/client/components/default/SocketIoDefault.js +3 -51
  228. package/src/client/components/default/TranslateDefault.js +3 -3
  229. package/src/client/components/itemledger/{MenuItemledger.js → AppShellItemledger.js} +59 -59
  230. package/src/client/components/itemledger/AppStoreItemledger.js +5 -0
  231. package/src/client/components/itemledger/CssItemledger.js +15 -15
  232. package/src/client/components/itemledger/LogInItemledger.js +9 -7
  233. package/src/client/components/itemledger/LogOutItemledger.js +8 -6
  234. package/src/client/components/itemledger/RouterItemledger.js +38 -0
  235. package/src/client/components/itemledger/SettingsItemledger.js +4 -4
  236. package/src/client/components/itemledger/SignUpItemledger.js +6 -4
  237. package/src/client/components/itemledger/SocketIoItemledger.js +3 -51
  238. package/src/client/components/itemledger/TranslateItemledger.js +3 -3
  239. package/src/client/components/underpost/{MenuUnderpost.js → AppShellUnderpost.js} +92 -92
  240. package/src/client/components/underpost/AppStoreUnderpost.js +5 -0
  241. package/src/client/components/underpost/CssUnderpost.js +14 -14
  242. package/src/client/components/underpost/CyberpunkBloggerUnderpost.js +4 -4
  243. package/src/client/components/underpost/DocumentSearchProvider.js +1 -1
  244. package/src/client/components/underpost/LabGalleryUnderpost.js +12 -15
  245. package/src/client/components/underpost/LogInUnderpost.js +9 -7
  246. package/src/client/components/underpost/LogOutUnderpost.js +8 -6
  247. package/src/client/components/underpost/RouterUnderpost.js +45 -0
  248. package/src/client/components/underpost/SettingsUnderpost.js +4 -4
  249. package/src/client/components/underpost/SignUpUnderpost.js +6 -4
  250. package/src/client/components/underpost/SocketIoUnderpost.js +3 -51
  251. package/src/client/components/underpost/TranslateUnderpost.js +4 -4
  252. package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +235 -0
  253. package/src/client/public/cyberia-docs/ARCHITECTURE.md +443 -0
  254. package/src/client/public/cyberia-docs/CYBERIA-CLI.md +417 -0
  255. package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +313 -0
  256. package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +260 -0
  257. package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +241 -0
  258. package/src/client/public/cyberia-docs/HARDHAT-MODULE.md +300 -0
  259. package/src/client/public/cyberia-docs/OFF-CHAIN-ECONOMY.md +279 -0
  260. package/src/client/public/cyberia-docs/QUEST-SYSTEM.md +206 -0
  261. package/src/client/public/cyberia-docs/ROADMAP.md +240 -0
  262. package/src/client/public/cyberia-docs/WHITE-PAPER.md +732 -0
  263. package/src/client/services/atlas-sprite-sheet/atlas-sprite-sheet.service.js +14 -20
  264. package/src/client/services/core/core.service.js +35 -55
  265. package/src/client/services/crypto/crypto.service.js +8 -13
  266. package/src/client/services/cyberia-action/cyberia-action.service.js +99 -0
  267. package/src/client/services/cyberia-dialogue/cyberia-dialogue.service.js +99 -0
  268. package/src/client/services/cyberia-entity/cyberia-entity.management.js +57 -0
  269. package/src/client/services/cyberia-entity/cyberia-entity.service.js +99 -0
  270. package/src/client/services/cyberia-instance/cyberia-instance.management.js +194 -0
  271. package/src/client/services/cyberia-instance/cyberia-instance.service.js +116 -0
  272. package/src/client/services/cyberia-instance-conf/cyberia-instance-conf.service.js +99 -0
  273. package/src/client/services/cyberia-map/cyberia-map.management.js +193 -0
  274. package/src/client/services/cyberia-map/cyberia-map.service.js +120 -0
  275. package/src/client/services/cyberia-quest/cyberia-quest.service.js +99 -0
  276. package/src/client/services/cyberia-quest-progress/cyberia-quest-progress.service.js +99 -0
  277. package/src/client/services/default/default.management.js +159 -267
  278. package/src/client/services/default/default.service.js +10 -16
  279. package/src/client/services/document/document.service.js +14 -19
  280. package/src/client/services/file/file.service.js +8 -13
  281. package/src/client/services/instance/instance.management.js +6 -6
  282. package/src/client/services/instance/instance.service.js +10 -15
  283. package/src/client/services/ipfs/ipfs.service.js +14 -40
  284. package/src/client/services/object-layer/object-layer.management.js +14 -14
  285. package/src/client/services/object-layer/object-layer.service.js +39 -24
  286. package/src/client/services/object-layer-render-frames/object-layer-render-frames.service.js +10 -16
  287. package/src/client/services/test/test.service.js +8 -13
  288. package/src/client/services/user/guest.service.js +86 -0
  289. package/src/client/services/user/user.management.js +6 -6
  290. package/src/client/services/user/user.service.js +14 -20
  291. package/src/client/ssr/body/404.js +3 -3
  292. package/src/client/ssr/body/500.js +3 -3
  293. package/src/client/ssr/body/CacheControl.js +5 -2
  294. package/src/client/ssr/body/DefaultSplashScreen.js +19 -12
  295. package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +13 -6
  296. package/src/client/ssr/head/PwaItemledger.js +197 -60
  297. package/src/client/ssr/mailer/DefaultRecoverEmail.js +19 -20
  298. package/src/client/ssr/mailer/DefaultVerifyEmail.js +15 -16
  299. package/src/client/ssr/offline/Maintenance.js +12 -11
  300. package/src/client/ssr/offline/NoNetworkConnection.js +3 -3
  301. package/src/client/ssr/pages/CyberiaServerMetrics.js +1 -1
  302. package/src/client/ssr/pages/Test.js +2 -2
  303. package/src/client/sw/core.sw.js +212 -0
  304. package/src/grpc/cyberia/grpc-server.js +642 -0
  305. package/src/index.js +24 -1
  306. package/src/runtime/cyberia-client/Dockerfile +80 -0
  307. package/src/runtime/cyberia-server/Dockerfile +37 -0
  308. package/src/runtime/express/Dockerfile +5 -1
  309. package/src/runtime/express/Express.js +18 -1
  310. package/src/runtime/lampp/Dockerfile +17 -5
  311. package/src/runtime/lampp/Lampp.js +27 -4
  312. package/src/runtime/wp/Dockerfile +62 -0
  313. package/src/runtime/wp/Wp.js +639 -0
  314. package/src/server/atlas-sprite-sheet-generator.js +4 -2
  315. package/src/server/auth.js +24 -1
  316. package/src/server/backup.js +37 -9
  317. package/src/server/client-build-docs.js +52 -46
  318. package/src/server/client-build.js +356 -82
  319. package/src/server/client-formatted.js +140 -57
  320. package/src/server/conf.js +29 -13
  321. package/src/server/cron.js +25 -23
  322. package/src/server/data-query.js +32 -20
  323. package/src/server/dns.js +24 -1
  324. package/src/server/ipfs-client.js +253 -89
  325. package/src/server/object-layer.js +150 -114
  326. package/src/server/peer.js +8 -0
  327. package/src/server/process.js +13 -27
  328. package/src/server/runtime.js +25 -1
  329. package/src/server/semantic-layer-generator-floor.js +319 -0
  330. package/src/server/semantic-layer-generator-resource.js +259 -0
  331. package/src/server/semantic-layer-generator-skin.js +1164 -0
  332. package/src/server/semantic-layer-generator.js +211 -542
  333. package/src/server/shape-generator.js +108 -0
  334. package/src/server/start.js +19 -5
  335. package/src/server/valkey.js +141 -235
  336. package/src/ws/IoInterface.js +1 -10
  337. package/src/ws/IoServer.js +14 -33
  338. package/src/ws/core/channels/core.ws.chat.js +65 -20
  339. package/src/ws/core/channels/core.ws.mailer.js +113 -32
  340. package/src/ws/core/channels/core.ws.stream.js +90 -31
  341. package/src/ws/core/core.ws.connection.js +12 -33
  342. package/src/ws/core/core.ws.emit.js +10 -26
  343. package/src/ws/core/core.ws.server.js +25 -58
  344. package/src/ws/default/channels/default.ws.main.js +53 -12
  345. package/src/ws/default/default.ws.connection.js +26 -13
  346. package/src/ws/default/default.ws.server.js +30 -12
  347. package/tsconfig.docs.json +15 -0
  348. package/typedoc.dd-cyberia.json +29 -0
  349. package/typedoc.json +29 -0
  350. package/WHITE-PAPER.md +0 -1540
  351. package/hardhat/README.md +0 -531
  352. package/hardhat/WHITE-PAPER.md +0 -1540
  353. package/jsdoc.dd-cyberia.json +0 -59
  354. package/jsdoc.json +0 -59
  355. package/src/api/object-layer/README.md +0 -347
  356. package/src/client/components/core/ColorPalette.js +0 -5267
  357. package/src/client/components/core/JoyStick.js +0 -80
  358. package/src/client/components/cryptokoyn/CommonCryptokoyn.js +0 -29
  359. package/src/client/components/cryptokoyn/ElementsCryptokoyn.js +0 -38
  360. package/src/client/components/cryptokoyn/RoutesCryptokoyn.js +0 -39
  361. package/src/client/components/cyberia-portal/ElementsCyberiaPortal.js +0 -38
  362. package/src/client/components/cyberia-portal/RoutesCyberiaPortal.js +0 -58
  363. package/src/client/components/cyberia-portal/ServerCyberiaPortal.js +0 -136
  364. package/src/client/components/default/ElementsDefault.js +0 -38
  365. package/src/client/components/default/RoutesDefault.js +0 -49
  366. package/src/client/components/itemledger/CommonItemledger.js +0 -29
  367. package/src/client/components/itemledger/ElementsItemledger.js +0 -38
  368. package/src/client/components/itemledger/RoutesItemledger.js +0 -40
  369. package/src/client/components/underpost/CommonUnderpost.js +0 -29
  370. package/src/client/components/underpost/ElementsUnderpost.js +0 -38
  371. package/src/client/components/underpost/RoutesUnderpost.js +0 -47
  372. package/src/client/sw/default.sw.js +0 -127
  373. package/src/client/sw/template.sw.js +0 -84
  374. package/src/ws/core/management/core.ws.chat.js +0 -8
  375. package/src/ws/core/management/core.ws.mailer.js +0 -16
  376. package/src/ws/core/management/core.ws.stream.js +0 -8
  377. package/src/ws/default/management/default.ws.main.js +0 -8
@@ -1,12 +1,16 @@
1
1
  /**
2
- * Semantic Layer Generator for Cyberia Online.
2
+ * Semantic Layer Generator for Cyberia Online — Router / Dispatcher.
3
3
  *
4
- * Produces semantically consistent object layers with controlled, reproducible
5
- * variation and short-term temporal coherence (consecutive frames stay consistent).
6
- *
7
- * Uses the shape-generator primitives (createRng, seedToInt, createNoise2D, generateShape)
8
- * and object-layer engine (createObjectLayerDocuments, buildImgFromTile) to produce
9
- * frame matrices that can be persisted to MongoDB / IPFS / static assets.
4
+ * This module is the public API surface. It:
5
+ * 1. Owns the semantic registry (registerSemantic / lookupSemantic).
6
+ * 2. Provides the shared utility functions used by category submodules.
7
+ * 3. Implements the default shape/noise-field generation pipeline
8
+ * (generateFrame / generateMultiFrame).
9
+ * 4. Delegates to descriptor-attached custom generators when present
10
+ * (e.g. skin uses template-based pixel painting via customMultiFrameGenerator).
11
+ * 5. Loads category submodules at initialisation:
12
+ * • semantic-layer-generator-floor.js — all floor-* descriptors
13
+ * • semantic-layer-generator-skin.js — skin-* descriptors
10
14
  *
11
15
  * @module src/server/semantic-layer-generator.js
12
16
  * @namespace SemanticLayerGenerator
@@ -17,6 +21,10 @@ import crypto from 'crypto';
17
21
  import { createRng, seedToInt, createNoise2D, generateShape, listShapes } from './shape-generator.js';
18
22
  import { loggerFactory } from './logger.js';
19
23
 
24
+ import { registerFloorSemantics } from './semantic-layer-generator-floor.js';
25
+ import { registerSkinSemantics } from './semantic-layer-generator-skin.js';
26
+ import { registerResourceSemantics } from './semantic-layer-generator-resource.js';
27
+
20
28
  const logger = loggerFactory(import.meta);
21
29
 
22
30
  /* ═══════════════════════════════════════════════════════════════════════════
@@ -25,39 +33,34 @@ const logger = loggerFactory(import.meta);
25
33
 
26
34
  /**
27
35
  * Produces a deterministic 32-bit integer hash from an arbitrary string.
28
- * Used to derive per-layer and per-frame seeds.
29
36
  * @param {string} str
30
37
  * @returns {number}
31
38
  * @memberof SemanticLayerGenerator
32
39
  */
40
+ function hashString(str) {
41
+ let h = 0;
42
+ for (let i = 0; i < str.length; i++) {
43
+ h = (Math.imul(31, h) + str.charCodeAt(i)) | 0;
44
+ }
45
+ return h;
46
+ }
47
+
33
48
  /**
34
49
  * Derives a deterministic UUID v4 from an arbitrary seed string.
35
- * Uses SHA-256 to hash the seed, then formats 16 bytes as a valid UUID v4
36
- * (version nibble = 4, variant bits = 10xx).
37
50
  * @param {string} seed
38
- * @returns {string} A valid UUID v4 string.
51
+ * @returns {string}
39
52
  * @memberof SemanticLayerGenerator
40
53
  */
41
54
  function seedToUUIDv4(seed) {
42
55
  const hash = crypto.createHash('sha256').update(seed).digest();
43
- // Set version nibble (byte 6, high nibble) to 0100 (version 4)
44
56
  hash[6] = (hash[6] & 0x0f) | 0x40;
45
- // Set variant bits (byte 8, high 2 bits) to 10xx
46
57
  hash[8] = (hash[8] & 0x3f) | 0x80;
47
58
  const hex = hash.toString('hex');
48
59
  return [hex.slice(0, 8), hex.slice(8, 12), hex.slice(12, 16), hex.slice(16, 20), hex.slice(20, 32)].join('-');
49
60
  }
50
61
 
51
- function hashString(str) {
52
- let h = 0;
53
- for (let i = 0; i < str.length; i++) {
54
- h = (Math.imul(31, h) + str.charCodeAt(i)) | 0;
55
- }
56
- return h;
57
- }
58
-
59
62
  /**
60
- * Derives a per-layer seed: layerSeed = hash(seed + ':' + itemId + ':' + layerKey)
63
+ * Derives a per-layer seed.
61
64
  * @param {string} seed
62
65
  * @param {string} itemId
63
66
  * @param {string} layerKey
@@ -69,7 +72,7 @@ function deriveLayerSeed(seed, itemId, layerKey) {
69
72
  }
70
73
 
71
74
  /**
72
- * Derives a per-frame seed: frameSeed = hash(layerSeed + ':' + frameIndex)
75
+ * Derives a per-frame seed.
73
76
  * @param {number} layerSeed
74
77
  * @param {number} frameIndex
75
78
  * @returns {number}
@@ -79,36 +82,100 @@ function deriveFrameSeed(layerSeed, frameIndex) {
79
82
  return hashString(`${layerSeed}:${frameIndex}`);
80
83
  }
81
84
 
85
+ /* ═══════════════════════════════════════════════════════════════════════════
86
+ * BIOME COLOUR PALETTES (canonical source — shared by floor + resource)
87
+ * ═══════════════════════════════════════════════════════════════════════════ */
88
+
89
+ /** @type {Object<string, number[][]>} */
90
+ const BIOME_PALETTES = {
91
+ desert: [
92
+ [210, 180, 120, 255],
93
+ [194, 160, 100, 255],
94
+ [230, 205, 150, 255],
95
+ [180, 140, 80, 255],
96
+ [160, 120, 70, 255],
97
+ [120, 90, 55, 255],
98
+ [100, 80, 50, 255],
99
+ [240, 220, 175, 255],
100
+ ],
101
+ grass: [
102
+ [80, 140, 60, 255],
103
+ [60, 120, 45, 255],
104
+ [110, 170, 80, 255],
105
+ [90, 130, 55, 255],
106
+ [130, 100, 65, 255],
107
+ [70, 110, 40, 255],
108
+ [150, 190, 100, 255],
109
+ [100, 85, 50, 255],
110
+ ],
111
+ water: [
112
+ [40, 100, 180, 255],
113
+ [60, 130, 200, 255],
114
+ [90, 160, 220, 255],
115
+ [120, 190, 230, 255],
116
+ [30, 80, 150, 255],
117
+ [70, 140, 210, 255],
118
+ [150, 210, 240, 255],
119
+ [20, 60, 120, 255],
120
+ ],
121
+ stone: [
122
+ [140, 140, 145, 255],
123
+ [120, 118, 125, 255],
124
+ [165, 165, 170, 255],
125
+ [100, 98, 105, 255],
126
+ [180, 180, 185, 255],
127
+ [90, 85, 80, 255],
128
+ [155, 150, 148, 255],
129
+ [110, 108, 115, 255],
130
+ ],
131
+ lava: [
132
+ [200, 50, 20, 255],
133
+ [230, 100, 30, 255],
134
+ [255, 180, 50, 255],
135
+ [160, 30, 10, 255],
136
+ [80, 20, 10, 255],
137
+ [50, 15, 8, 255],
138
+ [240, 140, 40, 255],
139
+ [120, 25, 12, 255],
140
+ ],
141
+ };
142
+
82
143
  /* ═══════════════════════════════════════════════════════════════════════════
83
144
  * SEMANTIC REGISTRY
84
- * Maps item-id prefixes to semantic descriptors that drive generation.
85
145
  * ═══════════════════════════════════════════════════════════════════════════ */
86
146
 
87
147
  /**
88
148
  * @typedef {Object} SemanticDescriptor
89
- * @property {string[]} semanticTags - Conceptual tags (e.g. ['sand','dune']).
90
- * @property {number[][]} paletteHints - Array of RGBA palette colors.
91
- * @property {Object<string,number>} preferredShapes - Shape key → relative weight.
92
- * @property {Object<string,LayerSpec>} layers - Named layer specifications.
93
- * @property {string} itemType - Object layer type (floor, skin, weapon…).
149
+ * @property {string[]} semanticTags Conceptual tags.
150
+ * @property {number[][]} paletteHints RGBA palette colours.
151
+ * @property {Object<string,number>} preferredShapes Shape key → weight.
152
+ * @property {Object<string,LayerSpec>} layers Named layer specs.
153
+ * @property {string} itemType floor | skin | weapon | skill | coin
154
+ * @property {Function} [customMultiFrameGenerator] Overrides the default multi-frame pipeline.
94
155
  * @memberof SemanticLayerGenerator
95
156
  */
96
157
 
97
158
  /**
98
159
  * @typedef {Object} LayerSpec
99
- * @property {string} generator - 'shape' | 'noise-field' | 'sprite'
100
- * @property {string[]} shapes - Candidate shape keys for this layer.
101
- * @property {number} count - Number of elements to place.
102
- * @property {number} scaleVariance - Max ± scale deviation (0..1).
103
- * @property {number} rotationVariance- Max ± rotation deviation in degrees.
104
- * @property {number} colorShift - Max RGBA channel shift per element.
105
- * @property {number} jitter - Positional jitter amount (0..1).
106
- * @property {number} noiseLevel - Noise displacement applied to shapes.
107
- * @property {number} detailLevel - Point count multiplier for shapes.
108
- * @property {number} sparsity - Fraction of grid cells left empty (0..1).
109
- * @property {number} [frameJitter] - Per-frame positional wobble for temporal coherence.
110
- * @property {number} [frameRotation] - Per-frame rotation wobble in degrees.
111
- * @property {number} [frameScale] - Per-frame scale wobble.
160
+ * @property {string} generator 'shape' | 'noise-field' | 'template-zone'
161
+ * @property {string[]} [shapes]
162
+ * @property {number} [count]
163
+ * @property {number} [scaleVariance]
164
+ * @property {number} [rotationVariance]
165
+ * @property {number} [colorShift]
166
+ * @property {number} [jitter]
167
+ * @property {number} [noiseLevel]
168
+ * @property {number} [detailLevel]
169
+ * @property {number} [sparsity]
170
+ * @property {number} [frameJitter]
171
+ * @property {number} [frameRotation]
172
+ * @property {number} [frameScale]
173
+ * @property {boolean} [fill] When true, shapes are scanline-filled (solid silhouettes).
174
+ * @property {Object} [shapeParams] Extra parameters forwarded to generateShape (e.g. {sides, closed, a, rangeX}).
175
+ * @property {number} [scaleBase=0.15] Base scale for stamped shapes (0..1 fraction of GRID_DIM).
176
+ * @property {number} [scaleRange=0.25] Random range added on top of scaleBase.
177
+ * @property {number} [rotationBase=0] Fixed rotation offset in degrees applied before random variance.
178
+ * @property {number} [centerBias=0] 0..1 factor pulling element positions toward the tile centre.
112
179
  * @memberof SemanticLayerGenerator
113
180
  */
114
181
 
@@ -137,7 +204,6 @@ export function registerSemantic(prefix, descriptor) {
137
204
  */
138
205
  export function lookupSemantic(itemId) {
139
206
  if (semanticRegistry[itemId]) return semanticRegistry[itemId];
140
- // Longest prefix match
141
207
  let best = null;
142
208
  let bestLen = 0;
143
209
  for (const prefix of Object.keys(semanticRegistry)) {
@@ -149,385 +215,10 @@ export function lookupSemantic(itemId) {
149
215
  return best;
150
216
  }
151
217
 
152
- /* ── Built-in semantic descriptors ─────────────────────────────────────── */
153
-
154
- registerSemantic('floor-desert', {
155
- semanticTags: ['sand', 'dune', 'arid', 'dry'],
156
- paletteHints: [
157
- [210, 180, 120, 255], // warm sand
158
- [194, 160, 100, 255], // darker sand
159
- [230, 205, 150, 255], // light sand
160
- [180, 140, 80, 255], // ochre
161
- [160, 120, 70, 255], // deep ochre
162
- [120, 90, 55, 255], // rock brown
163
- [100, 80, 50, 255], // shadow
164
- [240, 220, 175, 255], // highlight
165
- ],
166
- preferredShapes: { ellipse: 3, circle: 2, cactus: 1, star: 0.5 },
167
- itemType: 'floor',
168
- layers: {
169
- base: {
170
- generator: 'noise-field',
171
- shapes: ['ellipse'],
172
- count: 0,
173
- scaleVariance: 0,
174
- rotationVariance: 0,
175
- colorShift: 8,
176
- jitter: 0,
177
- noiseLevel: 0.3,
178
- detailLevel: 1,
179
- sparsity: 0,
180
- frameJitter: 0,
181
- frameRotation: 0,
182
- frameScale: 0,
183
- },
184
- dunes: {
185
- generator: 'shape',
186
- shapes: ['ellipse', 'circle'],
187
- count: 5,
188
- scaleVariance: 0.3,
189
- rotationVariance: 15,
190
- colorShift: 12,
191
- jitter: 0.08,
192
- noiseLevel: 0.15,
193
- detailLevel: 1.2,
194
- sparsity: 0.3,
195
- frameJitter: 0.005,
196
- frameRotation: 0.5,
197
- frameScale: 0.005,
198
- },
199
- rocks: {
200
- generator: 'shape',
201
- shapes: ['star', 'circle'],
202
- count: 3,
203
- scaleVariance: 0.4,
204
- rotationVariance: 45,
205
- colorShift: 15,
206
- jitter: 0.12,
207
- noiseLevel: 0.2,
208
- detailLevel: 1,
209
- sparsity: 0.5,
210
- frameJitter: 0.002,
211
- frameRotation: 0.3,
212
- frameScale: 0.003,
213
- },
214
- tufts: {
215
- generator: 'shape',
216
- shapes: ['cactus', 'star'],
217
- count: 2,
218
- scaleVariance: 0.25,
219
- rotationVariance: 20,
220
- colorShift: 10,
221
- jitter: 0.1,
222
- noiseLevel: 0.1,
223
- detailLevel: 0.8,
224
- sparsity: 0.6,
225
- frameJitter: 0.008,
226
- frameRotation: 1.0,
227
- frameScale: 0.006,
228
- },
229
- },
230
- });
231
-
232
- registerSemantic('floor-grass', {
233
- semanticTags: ['grass', 'meadow', 'green', 'earth'],
234
- paletteHints: [
235
- [80, 140, 60, 255], // base green
236
- [60, 120, 45, 255], // dark green
237
- [110, 170, 80, 255], // light green
238
- [90, 130, 55, 255], // mid green
239
- [130, 100, 65, 255], // earth
240
- [70, 110, 40, 255], // shadow green
241
- [150, 190, 100, 255], // highlight
242
- [100, 85, 50, 255], // dark earth
243
- ],
244
- preferredShapes: { ellipse: 3, circle: 2, heart: 0.5 },
245
- itemType: 'floor',
246
- layers: {
247
- base: {
248
- generator: 'noise-field',
249
- shapes: ['circle'],
250
- count: 0,
251
- scaleVariance: 0,
252
- rotationVariance: 0,
253
- colorShift: 10,
254
- jitter: 0,
255
- noiseLevel: 0.25,
256
- detailLevel: 1,
257
- sparsity: 0,
258
- frameJitter: 0,
259
- frameRotation: 0,
260
- frameScale: 0,
261
- },
262
- blades: {
263
- generator: 'shape',
264
- shapes: ['ellipse', 'heart'],
265
- count: 6,
266
- scaleVariance: 0.35,
267
- rotationVariance: 40,
268
- colorShift: 15,
269
- jitter: 0.1,
270
- noiseLevel: 0.12,
271
- detailLevel: 1.0,
272
- sparsity: 0.25,
273
- frameJitter: 0.01,
274
- frameRotation: 2.0,
275
- frameScale: 0.005,
276
- },
277
- patches: {
278
- generator: 'shape',
279
- shapes: ['circle', 'ellipse'],
280
- count: 3,
281
- scaleVariance: 0.3,
282
- rotationVariance: 30,
283
- colorShift: 12,
284
- jitter: 0.08,
285
- noiseLevel: 0.15,
286
- detailLevel: 0.9,
287
- sparsity: 0.4,
288
- frameJitter: 0.003,
289
- frameRotation: 0.5,
290
- frameScale: 0.003,
291
- },
292
- },
293
- });
294
-
295
- registerSemantic('floor-water', {
296
- semanticTags: ['water', 'ocean', 'wave', 'liquid'],
297
- paletteHints: [
298
- [40, 100, 180, 255], // deep blue
299
- [60, 130, 200, 255], // mid blue
300
- [90, 160, 220, 255], // light blue
301
- [120, 190, 230, 255], // highlight
302
- [30, 80, 150, 255], // dark blue
303
- [70, 140, 210, 255], // wave crest
304
- [150, 210, 240, 255], // foam
305
- [20, 60, 120, 255], // abyss
306
- ],
307
- preferredShapes: { ellipse: 3, circle: 2 },
308
- itemType: 'floor',
309
- layers: {
310
- base: {
311
- generator: 'noise-field',
312
- shapes: ['ellipse'],
313
- count: 0,
314
- scaleVariance: 0,
315
- rotationVariance: 0,
316
- colorShift: 12,
317
- jitter: 0,
318
- noiseLevel: 0.35,
319
- detailLevel: 1,
320
- sparsity: 0,
321
- frameJitter: 0,
322
- frameRotation: 0,
323
- frameScale: 0,
324
- },
325
- waves: {
326
- generator: 'shape',
327
- shapes: ['ellipse'],
328
- count: 4,
329
- scaleVariance: 0.3,
330
- rotationVariance: 10,
331
- colorShift: 18,
332
- jitter: 0.06,
333
- noiseLevel: 0.2,
334
- detailLevel: 1.2,
335
- sparsity: 0.2,
336
- frameJitter: 0.015,
337
- frameRotation: 1.5,
338
- frameScale: 0.008,
339
- },
340
- foam: {
341
- generator: 'shape',
342
- shapes: ['circle'],
343
- count: 3,
344
- scaleVariance: 0.5,
345
- rotationVariance: 0,
346
- colorShift: 10,
347
- jitter: 0.15,
348
- noiseLevel: 0.1,
349
- detailLevel: 0.7,
350
- sparsity: 0.5,
351
- frameJitter: 0.012,
352
- frameRotation: 0.5,
353
- frameScale: 0.01,
354
- },
355
- },
356
- });
357
-
358
- registerSemantic('floor-stone', {
359
- semanticTags: ['stone', 'rock', 'cobble', 'grey'],
360
- paletteHints: [
361
- [140, 140, 145, 255], // base grey
362
- [120, 118, 125, 255], // dark grey
363
- [165, 165, 170, 255], // light grey
364
- [100, 98, 105, 255], // shadow
365
- [180, 180, 185, 255], // highlight
366
- [90, 85, 80, 255], // dark rock
367
- [155, 150, 148, 255], // warm grey
368
- [110, 108, 115, 255], // cool grey
369
- ],
370
- preferredShapes: { circle: 3, ellipse: 2, star: 1, 'pixel-art': 0.5 },
371
- itemType: 'floor',
372
- layers: {
373
- base: {
374
- generator: 'noise-field',
375
- shapes: ['circle'],
376
- count: 0,
377
- scaleVariance: 0,
378
- rotationVariance: 0,
379
- colorShift: 6,
380
- jitter: 0,
381
- noiseLevel: 0.2,
382
- detailLevel: 1,
383
- sparsity: 0,
384
- frameJitter: 0,
385
- frameRotation: 0,
386
- frameScale: 0,
387
- },
388
- cobbles: {
389
- generator: 'shape',
390
- shapes: ['circle', 'ellipse', 'pixel-art'],
391
- count: 6,
392
- scaleVariance: 0.35,
393
- rotationVariance: 90,
394
- colorShift: 10,
395
- jitter: 0.06,
396
- noiseLevel: 0.15,
397
- detailLevel: 1.0,
398
- sparsity: 0.2,
399
- frameJitter: 0.001,
400
- frameRotation: 0.2,
401
- frameScale: 0.001,
402
- },
403
- cracks: {
404
- generator: 'shape',
405
- shapes: ['star'],
406
- count: 2,
407
- scaleVariance: 0.5,
408
- rotationVariance: 180,
409
- colorShift: 20,
410
- jitter: 0.1,
411
- noiseLevel: 0.25,
412
- detailLevel: 0.8,
413
- sparsity: 0.6,
414
- frameJitter: 0.0,
415
- frameRotation: 0.0,
416
- frameScale: 0.0,
417
- },
418
- },
419
- });
420
-
421
- registerSemantic('floor-lava', {
422
- semanticTags: ['lava', 'magma', 'fire', 'hot'],
423
- paletteHints: [
424
- [200, 50, 20, 255], // hot red
425
- [230, 100, 30, 255], // orange
426
- [255, 180, 50, 255], // bright yellow
427
- [160, 30, 10, 255], // dark red
428
- [80, 20, 10, 255], // cooled rock
429
- [50, 15, 8, 255], // dark crust
430
- [240, 140, 40, 255], // glow
431
- [120, 25, 12, 255], // mid lava
432
- ],
433
- preferredShapes: { circle: 3, ellipse: 2, cactus: 1 },
434
- itemType: 'floor',
435
- layers: {
436
- base: {
437
- generator: 'noise-field',
438
- shapes: ['circle'],
439
- count: 0,
440
- scaleVariance: 0,
441
- rotationVariance: 0,
442
- colorShift: 15,
443
- jitter: 0,
444
- noiseLevel: 0.4,
445
- detailLevel: 1,
446
- sparsity: 0,
447
- frameJitter: 0,
448
- frameRotation: 0,
449
- frameScale: 0,
450
- },
451
- flow: {
452
- generator: 'shape',
453
- shapes: ['ellipse', 'circle'],
454
- count: 5,
455
- scaleVariance: 0.35,
456
- rotationVariance: 25,
457
- colorShift: 20,
458
- jitter: 0.1,
459
- noiseLevel: 0.2,
460
- detailLevel: 1.1,
461
- sparsity: 0.2,
462
- frameJitter: 0.02,
463
- frameRotation: 2.0,
464
- frameScale: 0.01,
465
- },
466
- crust: {
467
- generator: 'shape',
468
- shapes: ['star', 'cactus'],
469
- count: 3,
470
- scaleVariance: 0.4,
471
- rotationVariance: 60,
472
- colorShift: 10,
473
- jitter: 0.08,
474
- noiseLevel: 0.15,
475
- detailLevel: 0.9,
476
- sparsity: 0.4,
477
- frameJitter: 0.005,
478
- frameRotation: 0.5,
479
- frameScale: 0.004,
480
- },
481
- },
482
- });
483
-
484
- registerSemantic('skin-', {
485
- semanticTags: ['character', 'body', 'humanoid'],
486
- paletteHints: [
487
- [180, 140, 110, 255],
488
- [160, 120, 90, 255],
489
- [200, 160, 130, 255],
490
- [140, 100, 70, 255],
491
- [100, 70, 50, 255],
492
- [60, 60, 80, 255],
493
- [80, 80, 100, 255],
494
- [220, 180, 150, 255],
495
- ],
496
- preferredShapes: { 'skull-bone': 2, circle: 2, ellipse: 1 },
497
- itemType: 'skin',
498
- layers: {
499
- body: {
500
- generator: 'shape',
501
- shapes: ['ellipse', 'circle'],
502
- count: 4,
503
- scaleVariance: 0.3,
504
- rotationVariance: 10,
505
- colorShift: 12,
506
- jitter: 0.05,
507
- noiseLevel: 0.1,
508
- detailLevel: 1.2,
509
- sparsity: 0.2,
510
- frameJitter: 0.003,
511
- frameRotation: 0.5,
512
- frameScale: 0.003,
513
- },
514
- detail: {
515
- generator: 'shape',
516
- shapes: ['skull-bone', 'star'],
517
- count: 2,
518
- scaleVariance: 0.2,
519
- rotationVariance: 5,
520
- colorShift: 8,
521
- jitter: 0.03,
522
- noiseLevel: 0.08,
523
- detailLevel: 1.5,
524
- sparsity: 0.5,
525
- frameJitter: 0.002,
526
- frameRotation: 0.3,
527
- frameScale: 0.002,
528
- },
529
- },
530
- });
218
+ /* ── Load category submodules at startup ────────────────────────────────── */
219
+ registerFloorSemantics(registerSemantic);
220
+ registerSkinSemantics(registerSemantic);
221
+ registerResourceSemantics(registerSemantic);
531
222
 
532
223
  /* ═══════════════════════════════════════════════════════════════════════════
533
224
  * COLOR UTILITIES
@@ -537,7 +228,7 @@ registerSemantic('skin-', {
537
228
  * Picks a palette color deterministically from the hint palette.
538
229
  * @param {number[][]} palette
539
230
  * @param {function():number} rng
540
- * @param {number} colorShift - Max channel deviation.
231
+ * @param {number} colorShift
541
232
  * @returns {number[]} RGBA array.
542
233
  * @memberof SemanticLayerGenerator
543
234
  */
@@ -569,7 +260,6 @@ function clamp(v, min, max) {
569
260
 
570
261
  /**
571
262
  * Picks a shape key from candidate list, weighted by the descriptor's preferredShapes.
572
- * Falls back to uniform if no weights match.
573
263
  * @param {string[]} candidates
574
264
  * @param {Object<string,number>} weights
575
265
  * @param {function():number} rng
@@ -577,13 +267,9 @@ function clamp(v, min, max) {
577
267
  * @memberof SemanticLayerGenerator
578
268
  */
579
269
  function pickShape(candidates, weights, rng) {
580
- // Filter to only shapes that actually exist in the shape registry
581
270
  const available = listShapes();
582
271
  const valid = candidates.filter((c) => available.includes(c));
583
- if (valid.length === 0) {
584
- // fallback to any available shape
585
- return available[Math.floor(rng() * available.length)];
586
- }
272
+ if (valid.length === 0) return available[Math.floor(rng() * available.length)];
587
273
  const w = valid.map((k) => weights[k] ?? 1);
588
274
  const total = w.reduce((s, v) => s + v, 0);
589
275
  let r = rng() * total;
@@ -596,46 +282,33 @@ function pickShape(candidates, weights, rng) {
596
282
 
597
283
  /* ═══════════════════════════════════════════════════════════════════════════
598
284
  * FRAME MATRIX GENERATION
599
- * Converts generated shape layers into a 24×24 frame_matrix compatible
600
- * with the ObjectLayerEngine frame format.
601
285
  * ═══════════════════════════════════════════════════════════════════════════ */
602
286
 
603
- const GRID_DIM = 24; // standard object layer grid (24 rows × 24 cols)
287
+ const GRID_DIM = 24;
604
288
 
605
289
  /**
606
290
  * Generates a noise-field base layer as a 24×24 frame matrix.
607
- * Uses low-frequency 2D noise seeded per-frame for temporal coherence.
608
- * @param {number[][]} palette
609
- * @param {number} layerSeedInt
610
- * @param {number} frameIndex
611
- * @param {LayerSpec} spec
612
- * @param {number} density
613
- * @returns {{frameMatrix: number[][], colors: number[][]}}
614
291
  * @memberof SemanticLayerGenerator
615
292
  */
616
293
  function generateNoiseFieldLayer(palette, layerSeedInt, frameIndex, spec, density) {
617
294
  const frameSeedInt = deriveFrameSeed(layerSeedInt, frameIndex);
618
295
  const rng = createRng(frameSeedInt);
619
- const noise = createNoise2D(createRng(layerSeedInt)); // topology from layerSeed, not frameSeed
296
+ const noise = createNoise2D(createRng(layerSeedInt));
620
297
 
621
298
  const colors = [];
622
299
  const frameMatrix = [];
623
300
 
624
- // Pre-pick a small set of colors for the base
625
301
  const baseColors = [];
626
- const colorRng = createRng(layerSeedInt + 7); // stable color selection
302
+ const colorRng = createRng(layerSeedInt + 7);
627
303
  for (let i = 0; i < Math.min(palette.length, 4); i++) {
628
304
  baseColors.push(pickColor(palette, colorRng, spec.colorShift));
629
305
  }
630
-
631
- // Register base colors
632
306
  const colorIndices = baseColors.map((c) => {
633
307
  colors.push(c);
634
308
  return colors.length - 1;
635
309
  });
636
310
 
637
311
  const noiseFreq = 0.15 + spec.noiseLevel * 0.3;
638
- // Frame-level noise offset for smooth temporal variation
639
312
  const frameOffsetX = frameIndex * 0.05;
640
313
  const frameOffsetY = frameIndex * 0.03;
641
314
 
@@ -643,8 +316,7 @@ function generateNoiseFieldLayer(palette, layerSeedInt, frameIndex, spec, densit
643
316
  const row = [];
644
317
  for (let x = 0; x < GRID_DIM; x++) {
645
318
  const n = noise((x + frameOffsetX) * noiseFreq, (y + frameOffsetY) * noiseFreq);
646
- // Map noise [-1,1] color index
647
- const normalized = (n + 1) / 2; // 0..1
319
+ const normalized = (n + 1) / 2;
648
320
  const idx = Math.min(colorIndices.length - 1, Math.floor(normalized * colorIndices.length));
649
321
  row.push(colorIndices[idx]);
650
322
  }
@@ -656,18 +328,19 @@ function generateNoiseFieldLayer(palette, layerSeedInt, frameIndex, spec, densit
656
328
 
657
329
  /**
658
330
  * Stamps a parametric shape onto a frame matrix at a given position/scale.
659
- * @param {number[][]} frameMatrix - Mutable 24×24 matrix.
660
- * @param {number[][]} colors - Mutable color palette.
331
+ * @param {number[][]} frameMatrix
332
+ * @param {number[][]} colors
661
333
  * @param {string} shapeKey
662
- * @param {Object} transform - { x, y, scale, rotation }
663
- * @param {number[]} color - RGBA color for this stamp.
334
+ * @param {Object} transform
335
+ * @param {number[]} color
664
336
  * @param {number} noiseLevel
665
337
  * @param {number} detailLevel
666
- * @param {string} seed - String seed for shape generation.
338
+ * @param {string|number} seed
339
+ * @param {boolean} [fill]
340
+ * @param {Object} [shapeParams] Extra parameters forwarded to generateShape (e.g. sides, closed, a, rangeX).
667
341
  * @memberof SemanticLayerGenerator
668
342
  */
669
- function stampShape(frameMatrix, colors, shapeKey, transform, color, noiseLevel, detailLevel, seed) {
670
- // Generate shape using intCoords for pixel-level placement
343
+ function stampShape(frameMatrix, colors, shapeKey, transform, color, noiseLevel, detailLevel, seed, fill, shapeParams) {
671
344
  const gridSize = Math.max(4, Math.round(GRID_DIM * transform.scale));
672
345
  const result = generateShape(shapeKey, {
673
346
  intCoords: [gridSize, gridSize],
@@ -675,9 +348,10 @@ function stampShape(frameMatrix, colors, shapeKey, transform, color, noiseLevel,
675
348
  rotation: transform.rotation,
676
349
  seed,
677
350
  count: Math.round(80 * detailLevel),
351
+ fill: !!fill,
352
+ ...shapeParams,
678
353
  });
679
354
 
680
- // Register color
681
355
  const existingIdx = colors.findIndex(
682
356
  (c) => c[0] === color[0] && c[1] === color[1] && c[2] === color[2] && c[3] === color[3],
683
357
  );
@@ -689,7 +363,6 @@ function stampShape(frameMatrix, colors, shapeKey, transform, color, noiseLevel,
689
363
  colorIdx = colors.length - 1;
690
364
  }
691
365
 
692
- // Compute offset to center the shape at (transform.x, transform.y)
693
366
  const offsetX = Math.round(transform.x * GRID_DIM - gridSize / 2);
694
367
  const offsetY = Math.round(transform.y * GRID_DIM - gridSize / 2);
695
368
 
@@ -708,40 +381,40 @@ function stampShape(frameMatrix, colors, shapeKey, transform, color, noiseLevel,
708
381
 
709
382
  /**
710
383
  * @typedef {Object} GenerateLayerOptions
711
- * @property {string} itemId - The item identifier (e.g. 'floor-desert').
712
- * @property {string} seed - Master seed string (e.g. 'fx-42').
713
- * @property {number} frameIndex - Current frame index (0-based).
714
- * @property {number} [count=3] - Number of shape elements per layer (multiplier).
715
- * @property {number} [density=0.5]- Overall density factor (0..1).
384
+ * @property {string} itemId
385
+ * @property {string} seed
386
+ * @property {number} [frameIndex=0]
387
+ * @property {number} [count=3]
388
+ * @property {number} [density=0.5]
716
389
  * @memberof SemanticLayerGenerator
717
390
  */
718
391
 
719
392
  /**
720
393
  * @typedef {Object} GeneratedLayer
721
- * @property {string} layerId - Composite id: <itemId>-<layerKey>.
722
- * @property {string} layerKey - The layer name (e.g. 'dunes', 'rocks').
723
- * @property {Object[]} keys - Content entries placed in this layer.
724
- * @property {number[][]} frameMatrix - 24×24 color-index matrix.
725
- * @property {number[][]} colors - Shared color palette.
394
+ * @property {string} layerId
395
+ * @property {string} layerKey
396
+ * @property {Object[]} keys
397
+ * @property {number[][]} frameMatrix
398
+ * @property {number[][]} colors
726
399
  * @memberof SemanticLayerGenerator
727
400
  */
728
401
 
729
402
  /**
730
403
  * @typedef {Object} GenerationResult
731
- * @property {string} itemId
732
- * @property {string} seed
733
- * @property {number} frameIndex
404
+ * @property {string} itemId
405
+ * @property {string} seed
406
+ * @property {number} frameIndex
734
407
  * @property {GeneratedLayer[]} layers
735
- * @property {number[][]} compositeFrameMatrix - Final composited 24×24 matrix.
736
- * @property {number[][]} compositeColors - Final color palette.
408
+ * @property {number[][]} compositeFrameMatrix
409
+ * @property {number[][]} compositeColors
737
410
  * @memberof SemanticLayerGenerator
738
411
  */
739
412
 
740
413
  /**
741
414
  * Generates all semantic layers for a single frame of an item.
742
415
  *
743
- * Shape topology stays fixed across adjacent frames (determined by layerSeed);
744
- * only smooth per-frame transforms vary (derived from frameSeed + low-frequency noise).
416
+ * If the descriptor provides `customMultiFrameGenerator`, a stub result is
417
+ * returned use `generateMultiFrame` for those descriptors.
745
418
  *
746
419
  * @param {GenerateLayerOptions} options
747
420
  * @returns {GenerationResult}
@@ -758,13 +431,23 @@ export function generateFrame(options) {
758
431
  );
759
432
  }
760
433
 
434
+ // Descriptors with a custom multi-frame generator: return a transparent stub.
435
+ if (typeof descriptor.customMultiFrameGenerator === 'function') {
436
+ return {
437
+ itemId,
438
+ seed,
439
+ frameIndex,
440
+ layers: [],
441
+ compositeFrameMatrix: Array.from({ length: GRID_DIM }, () => Array(GRID_DIM).fill(0)),
442
+ compositeColors: [[0, 0, 0, 0]],
443
+ };
444
+ }
445
+
761
446
  const { paletteHints, preferredShapes, layers: layerSpecs } = descriptor;
762
447
  const layerKeys = Object.keys(layerSpecs);
763
448
 
764
- // Composite frame matrix (start transparent — color index 0 will be transparent)
765
- const compositeColors = [[0, 0, 0, 0]]; // index 0 = transparent
449
+ const compositeColors = [[0, 0, 0, 0]];
766
450
  const compositeMatrix = Array.from({ length: GRID_DIM }, () => Array(GRID_DIM).fill(0));
767
-
768
451
  const generatedLayers = [];
769
452
 
770
453
  for (const layerKey of layerKeys) {
@@ -773,7 +456,6 @@ export function generateFrame(options) {
773
456
  const layerId = `${itemId}-${layerKey}`;
774
457
 
775
458
  if (spec.generator === 'noise-field') {
776
- // ── Noise-field base layer ──
777
459
  const { frameMatrix, colors: layerColors } = generateNoiseFieldLayer(
778
460
  paletteHints,
779
461
  layerSeedInt,
@@ -782,7 +464,6 @@ export function generateFrame(options) {
782
464
  density,
783
465
  );
784
466
 
785
- // Merge colors into composite palette
786
467
  const colorMap = {};
787
468
  for (let ci = 0; ci < layerColors.length; ci++) {
788
469
  const c = layerColors[ci];
@@ -796,13 +477,10 @@ export function generateFrame(options) {
796
477
  colorMap[ci] = found;
797
478
  }
798
479
 
799
- // Stamp onto composite
800
480
  for (let y = 0; y < GRID_DIM; y++) {
801
481
  for (let x = 0; x < GRID_DIM; x++) {
802
482
  const mapped = colorMap[frameMatrix[y][x]];
803
- if (mapped !== undefined && mapped !== 0) {
804
- compositeMatrix[y][x] = mapped;
805
- }
483
+ if (mapped !== undefined && mapped !== 0) compositeMatrix[y][x] = mapped;
806
484
  }
807
485
  }
808
486
 
@@ -814,7 +492,6 @@ export function generateFrame(options) {
814
492
  colors: layerColors,
815
493
  });
816
494
  } else if (spec.generator === 'shape') {
817
- // ── Shape element layer ──
818
495
  const layerRng = createRng(layerSeedInt);
819
496
  const frameSeedInt = deriveFrameSeed(layerSeedInt, frameIndex);
820
497
  const frameRng = createRng(frameSeedInt);
@@ -822,31 +499,31 @@ export function generateFrame(options) {
822
499
 
823
500
  const effectiveCount = Math.max(1, Math.round(spec.count * count * density));
824
501
  const layerEntries = [];
825
-
826
- // Frame matrix for this layer alone (for metadata)
827
502
  const layerMatrix = Array.from({ length: GRID_DIM }, () => Array(GRID_DIM).fill(-1));
828
503
  const layerColors = [];
829
504
 
830
505
  for (let ei = 0; ei < effectiveCount; ei++) {
831
- // Sparsity check — deterministic per element
832
506
  if (layerRng() < spec.sparsity) continue;
833
507
 
834
- // ── Shape selection (stable across frames) ──
835
508
  const shapeKey = pickShape(spec.shapes, preferredShapes, createRng(layerSeedInt + ei * 97));
836
509
 
837
- // ── Base transform (stable across frames — from layerSeed) ──
838
510
  const baseRng = createRng(layerSeedInt + ei * 31 + 17);
839
- const baseX = baseRng();
840
- const baseY = baseRng();
841
- const baseScale = 0.15 + baseRng() * 0.25 + (baseRng() * 2 - 1) * spec.scaleVariance * 0.15;
842
- const baseRotation = (baseRng() * 2 - 1) * spec.rotationVariance;
511
+ let baseX = baseRng();
512
+ let baseY = baseRng();
513
+ const cb = spec.centerBias ?? 0;
514
+ if (cb > 0) {
515
+ baseX = baseX + (0.5 - baseX) * cb;
516
+ baseY = baseY + (0.5 - baseY) * cb;
517
+ }
518
+ const sBase = spec.scaleBase ?? 0.15;
519
+ const sRange = spec.scaleRange ?? 0.25;
520
+ const baseScale = sBase + baseRng() * sRange + (baseRng() * 2 - 1) * spec.scaleVariance * 0.15;
521
+ const baseRotation = (spec.rotationBase ?? 0) + (baseRng() * 2 - 1) * spec.rotationVariance;
843
522
 
844
- // ── Per-frame smooth perturbation (temporal coherence) ──
845
523
  const fj = spec.frameJitter || 0;
846
524
  const fr = spec.frameRotation || 0;
847
525
  const fs = spec.frameScale || 0;
848
526
 
849
- // Low-frequency noise indexed by element position for smooth frame-to-frame change
850
527
  const noiseX = frameNoise(ei * 2.5, frameIndex * 0.1) * fj;
851
528
  const noiseY = frameNoise(ei * 2.5 + 100, frameIndex * 0.1) * fj;
852
529
  const noiseRot = frameNoise(ei * 2.5 + 200, frameIndex * 0.1) * fr;
@@ -859,18 +536,13 @@ export function generateFrame(options) {
859
536
  rotation: baseRotation + noiseRot,
860
537
  };
861
538
 
862
- // ── Color (stable per element, small per-frame shift) ──
863
539
  const colorRng = createRng(layerSeedInt + ei * 53 + 7);
864
540
  const baseColor = pickColor(paletteHints, colorRng, spec.colorShift);
865
-
866
- // Small per-frame color shift for shimmer
867
541
  const frameColorShift = Math.round(frameNoise(ei * 3.7 + 400, frameIndex * 0.08) * 3);
868
542
  const color = baseColor.map((ch, ci) => (ci < 3 ? clamp(ch + frameColorShift, 0, 255) : ch));
869
543
 
870
- // ── Shape seed (stable topology) ──
871
544
  const shapeSeed = `${seed}:${itemId}:${layerKey}:${ei}`;
872
545
 
873
- // Stamp onto composite matrix
874
546
  stampShape(
875
547
  compositeMatrix,
876
548
  compositeColors,
@@ -880,9 +552,9 @@ export function generateFrame(options) {
880
552
  spec.noiseLevel * (spec.jitter + 0.5),
881
553
  spec.detailLevel,
882
554
  shapeSeed,
555
+ spec.fill,
556
+ spec.shapeParams,
883
557
  );
884
-
885
- // Also stamp onto layer-local matrix for metadata
886
558
  stampShape(
887
559
  layerMatrix,
888
560
  layerColors,
@@ -892,15 +564,11 @@ export function generateFrame(options) {
892
564
  spec.noiseLevel * 0.5,
893
565
  spec.detailLevel,
894
566
  shapeSeed,
567
+ spec.fill,
568
+ spec.shapeParams,
895
569
  );
896
570
 
897
- layerEntries.push({
898
- type: 'shape',
899
- shapeKey,
900
- transform,
901
- color,
902
- shapeSeed,
903
- });
571
+ layerEntries.push({ type: 'shape', shapeKey, transform, color, shapeSeed });
904
572
  }
905
573
 
906
574
  generatedLayers.push({
@@ -911,6 +579,7 @@ export function generateFrame(options) {
911
579
  colors: layerColors,
912
580
  });
913
581
  }
582
+ // 'template-zone' handled by customMultiFrameGenerator — skip here
914
583
  }
915
584
 
916
585
  return {
@@ -925,32 +594,34 @@ export function generateFrame(options) {
925
594
 
926
595
  /* ═══════════════════════════════════════════════════════════════════════════
927
596
  * MULTI-FRAME GENERATION
928
- * Generates multiple consecutive frames with temporal coherence.
929
597
  * ═══════════════════════════════════════════════════════════════════════════ */
930
598
 
931
599
  /**
932
600
  * @typedef {Object} MultiFrameResult
933
- * @property {string} itemId
934
- * @property {string} seed
935
- * @property {number} frameCount
601
+ * @property {string} itemId
602
+ * @property {string} seed
603
+ * @property {number} frameCount
936
604
  * @property {GenerationResult[]} frames
937
- * @property {Object} objectLayerRenderFramesData - Ready for ObjectLayerEngine.createObjectLayerDocuments.
938
- * @property {Object} objectLayerData - Ready for ObjectLayerEngine.createObjectLayerDocuments.
605
+ * @property {Object} objectLayerRenderFramesData
606
+ * @property {Object} objectLayerData
939
607
  * @memberof SemanticLayerGenerator
940
608
  */
941
609
 
942
610
  /**
943
- * Generates N consecutive frames for an item-id, producing data structures
944
- * compatible with ObjectLayerEngine document creation.
611
+ * Generates N consecutive frames for an item-id.
945
612
  *
946
- * @param {Object} options
613
+ * If the matched descriptor provides `customMultiFrameGenerator`, it is invoked
614
+ * directly and its result is returned unchanged — allowing category submodules
615
+ * (e.g. skin) to fully control frame layout and direction assignment.
616
+ *
617
+ * @param {Object} options
947
618
  * @param {string} options.itemId
948
619
  * @param {string} options.seed
949
- * @param {number} [options.frameCount=1] - Number of frames to generate.
950
- * @param {number} [options.startFrame=0] - Starting frame index.
951
- * @param {number} [options.count=3] - Shape element count multiplier.
952
- * @param {number} [options.density=0.5] - Density factor.
953
- * @param {number} [options.frameDuration=250] - ms per frame.
620
+ * @param {number} [options.frameCount=1]
621
+ * @param {number} [options.startFrame=0]
622
+ * @param {number} [options.count=3]
623
+ * @param {number} [options.density=0.5]
624
+ * @param {number} [options.frameDuration=250]
954
625
  * @returns {MultiFrameResult}
955
626
  * @memberof SemanticLayerGenerator
956
627
  */
@@ -965,22 +636,17 @@ export function generateMultiFrame(options) {
965
636
  );
966
637
  }
967
638
 
968
- const frames = [];
969
- let mergedColors = [[0, 0, 0, 0]]; // index 0 = transparent
639
+ // ── Dispatch to custom generator ─────────────────────────────────────────
640
+ if (typeof descriptor.customMultiFrameGenerator === 'function') {
641
+ return descriptor.customMultiFrameGenerator(options, descriptor);
642
+ }
970
643
 
971
- // First pass: generate all frames
644
+ // ── Default shape / noise-field pipeline ─────────────────────────────────
645
+ const frames = [];
972
646
  for (let fi = 0; fi < frameCount; fi++) {
973
- const result = generateFrame({
974
- itemId,
975
- seed,
976
- frameIndex: startFrame + fi,
977
- count,
978
- density,
979
- });
980
- frames.push(result);
647
+ frames.push(generateFrame({ itemId, seed, frameIndex: startFrame + fi, count, density }));
981
648
  }
982
649
 
983
- // Second pass: unify color palettes across all frames
984
650
  const globalColors = [[0, 0, 0, 0]];
985
651
  const frameMappings = [];
986
652
 
@@ -998,22 +664,17 @@ export function generateMultiFrame(options) {
998
664
  frameMappings.push(mapping);
999
665
  }
1000
666
 
1001
- // Third pass: remap frame matrices to global palette
1002
667
  const remappedFrames = frames.map((frame, fi) => {
1003
668
  const mapping = frameMappings[fi];
1004
669
  return frame.compositeFrameMatrix.map((row) => row.map((ci) => (mapping[ci] !== undefined ? mapping[ci] : 0)));
1005
670
  });
1006
671
 
1007
- // Build objectLayerRenderFramesData structure
1008
- // For floor types: use direction '08' (down_idle / default_idle / none_idle)
1009
672
  const objectLayerRenderFramesData = {
1010
673
  frame_duration: frameDuration,
1011
- is_stateless: descriptor.itemType === 'floor',
1012
674
  frames: {},
1013
675
  colors: globalColors,
1014
676
  };
1015
677
 
1016
- // Assign frames to directions
1017
678
  const directionMappings = {
1018
679
  floor: [['down_idle', 'none_idle', 'default_idle']],
1019
680
  skin: [
@@ -1028,14 +689,12 @@ export function generateMultiFrame(options) {
1028
689
  };
1029
690
 
1030
691
  const dirGroups = directionMappings[descriptor.itemType] || directionMappings.floor;
1031
-
1032
692
  for (const dirGroup of dirGroups) {
1033
693
  for (const dirName of dirGroup) {
1034
694
  objectLayerRenderFramesData.frames[dirName] = [...remappedFrames];
1035
695
  }
1036
696
  }
1037
697
 
1038
- // Build objectLayerData
1039
698
  const objectLayerData = {
1040
699
  data: {
1041
700
  item: {
@@ -1081,4 +740,14 @@ function hashMod(str, mod) {
1081
740
  * EXPORTS
1082
741
  * ═══════════════════════════════════════════════════════════════════════════ */
1083
742
 
1084
- export { hashString, deriveLayerSeed, deriveFrameSeed, pickColor, pickShape, seedToUUIDv4, GRID_DIM, semanticRegistry };
743
+ export {
744
+ hashString,
745
+ deriveLayerSeed,
746
+ deriveFrameSeed,
747
+ pickColor,
748
+ pickShape,
749
+ seedToUUIDv4,
750
+ GRID_DIM,
751
+ semanticRegistry,
752
+ BIOME_PALETTES,
753
+ };