cyberia 3.2.5 → 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 (301) hide show
  1. package/.github/workflows/engine-cyberia.cd.yml +2 -2
  2. package/.github/workflows/release.cd.yml +1 -2
  3. package/CHANGELOG.md +351 -1
  4. package/CLI-HELP.md +40 -13
  5. package/Dockerfile +0 -4
  6. package/README.md +242 -497
  7. package/bin/build.js +19 -5
  8. package/bin/cyberia.js +1149 -240
  9. package/bin/deploy.js +570 -1
  10. package/bin/file.js +6 -0
  11. package/bin/index.js +1149 -240
  12. package/bin/vs.js +1 -1
  13. package/conf.js +67 -89
  14. package/deployment.yaml +4 -222
  15. package/hardhat/package-lock.json +32 -32
  16. package/hardhat/package.json +3 -3
  17. package/jsconfig.json +1 -1
  18. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +2 -2
  19. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +2 -2
  20. package/manifests/deployment/dd-cyberia-development/deployment.yaml +4 -222
  21. package/manifests/deployment/dd-cyberia-development/proxy.yaml +10 -118
  22. package/manifests/deployment/dd-default-development/deployment.yaml +2 -6
  23. package/manifests/deployment/dd-test-development/deployment.yaml +136 -66
  24. package/manifests/deployment/dd-test-development/proxy.yaml +41 -5
  25. package/package.json +23 -14
  26. package/proxy.yaml +10 -118
  27. package/scripts/k3s-node-setup.sh +2 -2
  28. package/scripts/nat-iptables.sh +103 -18
  29. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +18 -18
  30. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +7 -14
  31. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +76 -21
  32. package/src/api/core/core.controller.js +10 -10
  33. package/src/api/core/core.service.js +10 -10
  34. package/src/api/crypto/crypto.controller.js +8 -8
  35. package/src/api/crypto/crypto.service.js +8 -8
  36. package/src/api/cyberia-action/cyberia-action.controller.js +74 -0
  37. package/src/api/cyberia-action/cyberia-action.model.js +87 -0
  38. package/src/api/cyberia-action/cyberia-action.router.js +27 -0
  39. package/src/api/cyberia-action/cyberia-action.service.js +42 -0
  40. package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +13 -13
  41. package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +11 -11
  42. package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +2 -2
  43. package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +16 -16
  44. package/src/api/cyberia-entity/cyberia-entity.controller.js +10 -10
  45. package/src/api/cyberia-entity/cyberia-entity.service.js +10 -10
  46. package/src/api/cyberia-instance/cyberia-fallback-world.js +19 -209
  47. package/src/api/cyberia-instance/cyberia-instance.controller.js +14 -14
  48. package/src/api/cyberia-instance/cyberia-instance.model.js +3 -0
  49. package/src/api/cyberia-instance/cyberia-instance.service.js +22 -57
  50. package/src/api/cyberia-instance/cyberia-portal-connector.js +20 -246
  51. package/src/api/cyberia-instance/cyberia-world-generator.js +505 -0
  52. package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +10 -10
  53. package/src/api/cyberia-instance-conf/cyberia-instance-conf.defaults.js +216 -55
  54. package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +4 -1
  55. package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +18 -14
  56. package/src/api/cyberia-map/cyberia-map.controller.js +10 -10
  57. package/src/api/cyberia-map/cyberia-map.service.js +10 -10
  58. package/src/api/cyberia-quest/cyberia-quest.controller.js +74 -0
  59. package/src/api/cyberia-quest/cyberia-quest.model.js +67 -0
  60. package/src/api/cyberia-quest/cyberia-quest.router.js +27 -0
  61. package/src/api/cyberia-quest/cyberia-quest.service.js +42 -0
  62. package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.js +74 -0
  63. package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +49 -0
  64. package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +27 -0
  65. package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +42 -0
  66. package/src/api/default/default.controller.js +10 -10
  67. package/src/api/default/default.service.js +10 -10
  68. package/src/api/document/document.controller.js +12 -12
  69. package/src/api/document/document.model.js +10 -16
  70. package/src/api/file/file.controller.js +8 -8
  71. package/src/api/file/file.model.js +10 -10
  72. package/src/api/file/file.service.js +36 -36
  73. package/src/api/instance/instance.controller.js +10 -10
  74. package/src/api/instance/instance.model.js +4 -10
  75. package/src/api/instance/instance.service.js +10 -10
  76. package/src/api/ipfs/ipfs.controller.js +12 -12
  77. package/src/api/ipfs/ipfs.model.js +4 -13
  78. package/src/api/ipfs/ipfs.service.js +14 -28
  79. package/src/api/object-layer/object-layer.controller.js +12 -12
  80. package/src/api/object-layer/object-layer.model.js +4 -17
  81. package/src/api/object-layer/object-layer.service.js +12 -12
  82. package/src/api/object-layer-render-frames/object-layer-render-frames.controller.js +10 -10
  83. package/src/api/object-layer-render-frames/object-layer-render-frames.model.js +6 -16
  84. package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +18 -14
  85. package/src/api/test/test.controller.js +8 -8
  86. package/src/api/test/test.service.js +8 -8
  87. package/src/api/user/guest.service.js +99 -0
  88. package/src/api/user/user.controller.js +6 -6
  89. package/src/api/user/user.model.js +8 -13
  90. package/src/api/user/user.service.js +3 -20
  91. package/src/cli/cluster.js +61 -14
  92. package/src/cli/db.js +47 -2
  93. package/src/cli/deploy.js +67 -35
  94. package/src/cli/fs.js +79 -8
  95. package/src/cli/image.js +43 -1
  96. package/src/cli/index.js +26 -1
  97. package/src/cli/release.js +57 -1
  98. package/src/cli/repository.js +69 -31
  99. package/src/cli/run.js +415 -36
  100. package/src/cli/ssh.js +1 -1
  101. package/src/cli/static.js +43 -115
  102. package/src/client/Cryptokoyn.index.js +18 -21
  103. package/src/client/CyberiaPortal.index.js +19 -23
  104. package/src/client/Default.index.js +21 -33
  105. package/src/client/Itemledger.index.js +20 -26
  106. package/src/client/Underpost.index.js +19 -23
  107. package/src/client/components/core/404.js +4 -4
  108. package/src/client/components/core/500.js +4 -4
  109. package/src/client/components/core/Account.js +73 -60
  110. package/src/client/components/core/AgGrid.js +23 -33
  111. package/src/client/components/core/Alert.js +12 -13
  112. package/src/client/components/core/AppStore.js +1 -1
  113. package/src/client/components/core/Auth.js +35 -37
  114. package/src/client/components/core/Badge.js +7 -13
  115. package/src/client/components/core/BtnIcon.js +15 -17
  116. package/src/client/components/core/CalendarCore.js +42 -63
  117. package/src/client/components/core/Chat.js +13 -15
  118. package/src/client/components/core/ClientEvents.js +87 -0
  119. package/src/client/components/core/ColorPaletteElement.js +309 -0
  120. package/src/client/components/core/Content.js +17 -14
  121. package/src/client/components/core/Css.js +15 -71
  122. package/src/client/components/core/CssCore.js +12 -16
  123. package/src/client/components/core/D3Chart.js +4 -4
  124. package/src/client/components/core/Docs.js +64 -91
  125. package/src/client/components/core/DropDown.js +69 -91
  126. package/src/client/components/core/EventBus.js +92 -0
  127. package/src/client/components/core/EventsUI.js +14 -17
  128. package/src/client/components/core/FileExplorer.js +96 -228
  129. package/src/client/components/core/FullScreen.js +47 -75
  130. package/src/client/components/core/Input.js +24 -69
  131. package/src/client/components/core/Keyboard.js +25 -18
  132. package/src/client/components/core/KeyboardAvoidance.js +145 -0
  133. package/src/client/components/core/LoadingAnimation.js +25 -31
  134. package/src/client/components/core/LogIn.js +41 -41
  135. package/src/client/components/core/LogOut.js +23 -14
  136. package/src/client/components/core/Modal.js +462 -178
  137. package/src/client/components/core/NotificationManager.js +14 -18
  138. package/src/client/components/core/Panel.js +54 -50
  139. package/src/client/components/core/PanelForm.js +25 -125
  140. package/src/client/components/core/Polyhedron.js +110 -214
  141. package/src/client/components/core/PublicProfile.js +39 -32
  142. package/src/client/components/core/Recover.js +48 -44
  143. package/src/client/components/core/Responsive.js +88 -32
  144. package/src/client/components/core/RichText.js +9 -18
  145. package/src/client/components/core/Router.js +24 -3
  146. package/src/client/components/core/SearchBox.js +37 -37
  147. package/src/client/components/core/SignUp.js +39 -30
  148. package/src/client/components/core/SocketIo.js +31 -2
  149. package/src/client/components/core/SocketIoHandler.js +6 -6
  150. package/src/client/components/core/ToggleSwitch.js +8 -20
  151. package/src/client/components/core/ToolTip.js +5 -17
  152. package/src/client/components/core/Translate.js +56 -59
  153. package/src/client/components/core/Validator.js +26 -16
  154. package/src/client/components/core/Wallet.js +15 -26
  155. package/src/client/components/core/Worker.js +163 -27
  156. package/src/client/components/core/windowGetDimensions.js +7 -7
  157. package/src/client/components/cryptokoyn/{MenuCryptokoyn.js → AppShellCryptokoyn.js} +57 -57
  158. package/src/client/components/cryptokoyn/CssCryptokoyn.js +15 -15
  159. package/src/client/components/cryptokoyn/LogInCryptokoyn.js +6 -4
  160. package/src/client/components/cryptokoyn/LogOutCryptokoyn.js +6 -4
  161. package/src/client/components/cryptokoyn/RouterCryptokoyn.js +37 -0
  162. package/src/client/components/cryptokoyn/SettingsCryptokoyn.js +4 -4
  163. package/src/client/components/cryptokoyn/SignUpCryptokoyn.js +6 -4
  164. package/src/client/components/cyberia/InstanceEngineCyberia.js +141 -60
  165. package/src/client/components/cyberia/MapEngineCyberia.js +691 -214
  166. package/src/client/components/cyberia/ObjectLayerEngine.js +19 -0
  167. package/src/client/components/cyberia/ObjectLayerEngineModal.js +1204 -94
  168. package/src/client/components/cyberia/ObjectLayerEngineViewer.js +196 -298
  169. package/src/client/components/cyberia-portal/{MenuCyberiaPortal.js → AppShellCyberiaPortal.js} +102 -102
  170. package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +305 -61
  171. package/src/client/components/cyberia-portal/CssCyberiaPortal.js +15 -15
  172. package/src/client/components/cyberia-portal/LogInCyberiaPortal.js +6 -4
  173. package/src/client/components/cyberia-portal/LogOutCyberiaPortal.js +6 -4
  174. package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +4 -4
  175. package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +60 -0
  176. package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +4 -4
  177. package/src/client/components/cyberia-portal/SignUpCyberiaPortal.js +6 -4
  178. package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +4 -4
  179. package/src/client/components/default/{MenuDefault.js → AppShellDefault.js} +87 -87
  180. package/src/client/components/default/CssDefault.js +12 -12
  181. package/src/client/components/default/LogInDefault.js +6 -4
  182. package/src/client/components/default/LogOutDefault.js +6 -4
  183. package/src/client/components/default/RouterDefault.js +47 -0
  184. package/src/client/components/default/SettingsDefault.js +4 -4
  185. package/src/client/components/default/SignUpDefault.js +6 -4
  186. package/src/client/components/default/TranslateDefault.js +3 -3
  187. package/src/client/components/itemledger/{MenuItemledger.js → AppShellItemledger.js} +57 -57
  188. package/src/client/components/itemledger/CssItemledger.js +15 -15
  189. package/src/client/components/itemledger/LogInItemledger.js +6 -4
  190. package/src/client/components/itemledger/LogOutItemledger.js +6 -4
  191. package/src/client/components/itemledger/RouterItemledger.js +38 -0
  192. package/src/client/components/itemledger/SettingsItemledger.js +4 -4
  193. package/src/client/components/itemledger/SignUpItemledger.js +6 -4
  194. package/src/client/components/itemledger/TranslateItemledger.js +3 -3
  195. package/src/client/components/underpost/{MenuUnderpost.js → AppShellUnderpost.js} +88 -88
  196. package/src/client/components/underpost/CssUnderpost.js +14 -14
  197. package/src/client/components/underpost/CyberpunkBloggerUnderpost.js +4 -4
  198. package/src/client/components/underpost/DocumentSearchProvider.js +1 -1
  199. package/src/client/components/underpost/LabGalleryUnderpost.js +12 -15
  200. package/src/client/components/underpost/LogInUnderpost.js +6 -4
  201. package/src/client/components/underpost/LogOutUnderpost.js +6 -4
  202. package/src/client/components/underpost/RouterUnderpost.js +45 -0
  203. package/src/client/components/underpost/SettingsUnderpost.js +4 -4
  204. package/src/client/components/underpost/SignUpUnderpost.js +6 -4
  205. package/src/client/components/underpost/TranslateUnderpost.js +4 -4
  206. package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +235 -0
  207. package/src/client/public/cyberia-docs/ARCHITECTURE.md +443 -0
  208. package/src/client/public/cyberia-docs/CYBERIA-CLI.md +417 -0
  209. package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +313 -0
  210. package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +260 -0
  211. package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +241 -0
  212. package/src/client/public/cyberia-docs/HARDHAT-MODULE.md +300 -0
  213. package/src/client/public/cyberia-docs/OFF-CHAIN-ECONOMY.md +279 -0
  214. package/src/client/public/cyberia-docs/QUEST-SYSTEM.md +206 -0
  215. package/src/client/public/cyberia-docs/ROADMAP.md +240 -0
  216. package/src/client/public/cyberia-docs/WHITE-PAPER.md +732 -0
  217. package/src/client/services/atlas-sprite-sheet/atlas-sprite-sheet.service.js +14 -20
  218. package/src/client/services/core/core.service.js +17 -49
  219. package/src/client/services/crypto/crypto.service.js +8 -13
  220. package/src/client/services/cyberia-action/cyberia-action.service.js +99 -0
  221. package/src/client/services/cyberia-dialogue/cyberia-dialogue.service.js +10 -16
  222. package/src/client/services/cyberia-entity/cyberia-entity.management.js +5 -5
  223. package/src/client/services/cyberia-entity/cyberia-entity.service.js +10 -16
  224. package/src/client/services/cyberia-instance/cyberia-instance.management.js +6 -6
  225. package/src/client/services/cyberia-instance/cyberia-instance.service.js +12 -18
  226. package/src/client/services/cyberia-instance-conf/cyberia-instance-conf.service.js +10 -16
  227. package/src/client/services/cyberia-map/cyberia-map.management.js +6 -6
  228. package/src/client/services/cyberia-map/cyberia-map.service.js +12 -18
  229. package/src/client/services/cyberia-quest/cyberia-quest.service.js +99 -0
  230. package/src/client/services/cyberia-quest-progress/cyberia-quest-progress.service.js +99 -0
  231. package/src/client/services/default/default.management.js +159 -267
  232. package/src/client/services/default/default.service.js +10 -16
  233. package/src/client/services/document/document.service.js +14 -19
  234. package/src/client/services/file/file.service.js +8 -13
  235. package/src/client/services/instance/instance.management.js +5 -5
  236. package/src/client/services/instance/instance.service.js +10 -15
  237. package/src/client/services/ipfs/ipfs.service.js +12 -18
  238. package/src/client/services/object-layer/object-layer.management.js +12 -12
  239. package/src/client/services/object-layer/object-layer.service.js +20 -26
  240. package/src/client/services/object-layer-render-frames/object-layer-render-frames.service.js +10 -16
  241. package/src/client/services/test/test.service.js +8 -13
  242. package/src/client/services/user/guest.service.js +86 -0
  243. package/src/client/services/user/user.management.js +5 -5
  244. package/src/client/services/user/user.service.js +14 -20
  245. package/src/client/ssr/body/404.js +3 -3
  246. package/src/client/ssr/body/500.js +3 -3
  247. package/src/client/ssr/body/CacheControl.js +5 -2
  248. package/src/client/ssr/body/DefaultSplashScreen.js +19 -12
  249. package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +13 -6
  250. package/src/client/ssr/head/PwaItemledger.js +197 -60
  251. package/src/client/ssr/mailer/DefaultRecoverEmail.js +19 -20
  252. package/src/client/ssr/mailer/DefaultVerifyEmail.js +15 -16
  253. package/src/client/ssr/offline/Maintenance.js +12 -11
  254. package/src/client/ssr/offline/NoNetworkConnection.js +3 -3
  255. package/src/client/ssr/pages/Test.js +2 -2
  256. package/src/client/sw/core.sw.js +212 -0
  257. package/src/grpc/cyberia/grpc-server.js +179 -67
  258. package/src/index.js +1 -1
  259. package/src/runtime/cyberia-client/Dockerfile +80 -0
  260. package/src/runtime/cyberia-server/Dockerfile +37 -0
  261. package/src/runtime/express/Dockerfile +4 -4
  262. package/src/runtime/lampp/Dockerfile +8 -7
  263. package/src/runtime/wp/Dockerfile +11 -17
  264. package/src/server/atlas-sprite-sheet-generator.js +4 -2
  265. package/src/server/client-build-docs.js +45 -46
  266. package/src/server/client-build.js +334 -60
  267. package/src/server/client-formatted.js +47 -16
  268. package/src/server/conf.js +5 -4
  269. package/src/server/data-query.js +32 -20
  270. package/src/server/dns.js +22 -0
  271. package/src/server/ipfs-client.js +232 -91
  272. package/src/server/object-layer.js +1 -6
  273. package/src/server/process.js +13 -27
  274. package/src/server/semantic-layer-generator-floor.js +11 -51
  275. package/src/server/semantic-layer-generator-resource.js +259 -0
  276. package/src/server/semantic-layer-generator-skin.js +41 -171
  277. package/src/server/semantic-layer-generator.js +122 -14
  278. package/src/server/shape-generator.js +108 -0
  279. package/src/server/start.js +17 -3
  280. package/src/server/valkey.js +141 -235
  281. package/tsconfig.docs.json +15 -0
  282. package/typedoc.dd-cyberia.json +29 -0
  283. package/typedoc.json +29 -0
  284. package/WHITE-PAPER.md +0 -1540
  285. package/hardhat/README.md +0 -531
  286. package/hardhat/WHITE-PAPER.md +0 -1540
  287. package/jsdoc.dd-cyberia.json +0 -68
  288. package/jsdoc.json +0 -68
  289. package/src/api/object-layer/README.md +0 -672
  290. package/src/client/components/core/ColorPalette.js +0 -5267
  291. package/src/client/components/core/JoyStick.js +0 -80
  292. package/src/client/components/cryptokoyn/RoutesCryptokoyn.js +0 -39
  293. package/src/client/components/cyberia-portal/RoutesCyberiaPortal.js +0 -62
  294. package/src/client/components/cyberia-portal/ServerCyberiaPortal.js +0 -136
  295. package/src/client/components/default/RoutesDefault.js +0 -49
  296. package/src/client/components/itemledger/RoutesItemledger.js +0 -40
  297. package/src/client/components/underpost/RoutesUnderpost.js +0 -47
  298. package/src/client/sw/default.sw.js +0 -127
  299. package/src/client/sw/template.sw.js +0 -84
  300. package/src/grpc/cyberia/OFF_CHAIN_ECONOMY.md +0 -305
  301. package/src/grpc/cyberia/README.md +0 -326
@@ -18,215 +18,25 @@
18
18
  * @module src/api/cyberia-instance/cyberia-fallback-world
19
19
  */
20
20
 
21
+ import { connectPortals } from './cyberia-portal-connector.js';
22
+
21
23
  import {
22
- connectPortals,
23
24
  generateObstacles,
24
25
  generateForeground,
25
- colorToRgba,
26
- findColor,
27
- randInt,
26
+ generateResources,
27
+ generateFloorEntities,
28
+ generatePortalEntity,
29
+ generatePortalEntities,
30
+ generateBots,
28
31
  OccupancyGrid,
29
- BOT_RANGE,
30
- BOT_WEAPON_CHANCE,
31
- PORTAL_DIM_RANGE,
32
- PORTAL_COUNT_RANGE,
33
- PORTAL_MODE_LIST,
34
- PORTAL_MODE_COLOR_KEY,
35
- EXTRA_PORTAL_MODES,
36
- PORTAL_MODES,
37
- } from './cyberia-portal-connector.js';
38
-
39
- import {
40
- CYBERIA_INSTANCE_CONF_DEFAULTS,
41
- ENTITY_TYPE_DEFAULTS,
42
- } from '../cyberia-instance-conf/cyberia-instance-conf.defaults.js';
32
+ } from './cyberia-world-generator.js';
43
33
 
44
- import { DefaultCyberiaItems } from '../../client/components/cyberia-portal/CommonCyberiaPortal.js';
34
+ import { CYBERIA_INSTANCE_CONF_DEFAULTS } from '../cyberia-instance-conf/cyberia-instance-conf.defaults.js';
45
35
 
46
36
  // ── Defaults ─────────────────────────────────────────────────────────────────
47
37
 
48
38
  const DEFAULT_MAP_COUNT = 4;
49
39
  const DEFAULT_GRID_SIZE = 64;
50
- const DEFAULT_FLOOR_TILE_DIM = 4;
51
- const DEFAULT_BOT_DIM_RANGE = [2, 3];
52
-
53
- /** NPC skin pool — all items with type 'skin' from DefaultCyberiaItems. */
54
- const BOT_SKIN_POOL = DefaultCyberiaItems.filter((e) => e.item.type === 'skin').map((e) => e.item.id);
55
-
56
- // ── Floor generator ──────────────────────────────────────────────────────────
57
-
58
- /**
59
- * Generate floor tiles that cover the entire map grid.
60
- * Floor is NOT random — it tiles deterministically so every cell is covered.
61
- *
62
- * @param {{ gridX: number, gridY: number }} mapDims
63
- * @param {Array<{ key: string, r: number, g: number, b: number, a: number }>} colors
64
- * @param {object} [opts]
65
- * @param {number} [opts.tileDim=4] Floor tile size in cells.
66
- * @returns {object[]}
67
- */
68
- function generateFloorEntities(mapDims, colors, opts = {}) {
69
- const { tileDim = DEFAULT_FLOOR_TILE_DIM } = opts;
70
- const floorDefault = ENTITY_TYPE_DEFAULTS.find((d) => d.entityType === 'floor');
71
- const floorItemIds = floorDefault?.liveItemIds?.length ? [...floorDefault.liveItemIds] : [];
72
- const floorColor = findColor(colors, 'FLOOR');
73
- const rgba = floorColor ? colorToRgba(floorColor) : '';
74
-
75
- const entities = [];
76
- for (let y = 0; y < mapDims.gridY; y += tileDim) {
77
- for (let x = 0; x < mapDims.gridX; x += tileDim) {
78
- entities.push({
79
- entityType: 'floor',
80
- initCellX: x,
81
- initCellY: y,
82
- dimX: Math.min(tileDim, mapDims.gridX - x),
83
- dimY: Math.min(tileDim, mapDims.gridY - y),
84
- color: rgba,
85
- objectLayerItemIds: floorItemIds,
86
- });
87
- }
88
- }
89
- return entities;
90
- }
91
-
92
- // ── Portal entity generator ──────────────────────────────────────────────────
93
-
94
- /**
95
- * Generate a portal entity at a random walkable position with random dimensions.
96
- *
97
- * @param {{ gridX: number, gridY: number }} mapDims
98
- * @param {Array<{ key: string, r: number, g: number, b: number, a: number }>} colors
99
- * @param {OccupancyGrid} [grid] If provided, places portal only on walkable cells and marks them blocked.
100
- * @param {string} [portalSubtype] One of PORTAL_MODE_LIST values. Determines the portal colour.
101
- * @returns {object|null} Portal entity or null if no valid position found.
102
- */
103
- function generatePortalEntity(mapDims, colors, grid, portalSubtype) {
104
- // Resolve colour from subtype-specific palette key, falling back to generic PORTAL
105
- const colorKey = portalSubtype ? PORTAL_MODE_COLOR_KEY[portalSubtype] : 'PORTAL';
106
- const portalColor = findColor(colors, colorKey) || findColor(colors, 'PORTAL');
107
- const rgba = portalColor ? colorToRgba(portalColor) : 'rgba(0, 200, 200, 1)';
108
- const dimX = randInt(PORTAL_DIM_RANGE[0], PORTAL_DIM_RANGE[1]);
109
- const dimY = randInt(PORTAL_DIM_RANGE[0], PORTAL_DIM_RANGE[1]);
110
-
111
- if (grid) {
112
- const pos = grid.findPosition(dimX, dimY);
113
- if (!pos) return null;
114
- grid.block(pos.x, pos.y, dimX, dimY);
115
- return {
116
- entityType: 'portal',
117
- portalSubtype: portalSubtype || 'inter-portal',
118
- initCellX: pos.x,
119
- initCellY: pos.y,
120
- dimX,
121
- dimY,
122
- color: rgba,
123
- objectLayerItemIds: [],
124
- };
125
- }
126
-
127
- const maxX = Math.max(0, mapDims.gridX - dimX);
128
- const maxY = Math.max(0, mapDims.gridY - dimY);
129
- return {
130
- entityType: 'portal',
131
- portalSubtype: portalSubtype || 'inter-portal',
132
- initCellX: randInt(0, maxX),
133
- initCellY: randInt(0, maxY),
134
- dimX,
135
- dimY,
136
- color: rgba,
137
- objectLayerItemIds: [],
138
- };
139
- }
140
-
141
- /**
142
- * Generate a random number of portal entities for a map, each with a
143
- * randomly assigned portal subtype (and corresponding colour).
144
- *
145
- * @param {{ gridX: number, gridY: number }} mapDims
146
- * @param {Array<{ key: string, r: number, g: number, b: number, a: number }>} colors
147
- * @param {object} [opts]
148
- * @param {number} [opts.count] Override count (ignores range).
149
- * @param {OccupancyGrid} [opts.grid] If provided, places portals only on walkable cells.
150
- * @returns {object[]}
151
- */
152
- function generatePortalEntities(mapDims, colors, opts = {}) {
153
- const count = opts.count ?? randInt(PORTAL_COUNT_RANGE[0], PORTAL_COUNT_RANGE[1]);
154
- const entities = [];
155
- for (let i = 0; i < count; i++) {
156
- // First portal is always inter-portal (reserved for the ring topology);
157
- // extra portals get a random non-ring subtype.
158
- const subtype =
159
- i === 0 ? PORTAL_MODES.INTER_PORTAL : EXTRA_PORTAL_MODES[Math.floor(Math.random() * EXTRA_PORTAL_MODES.length)];
160
- const portal = generatePortalEntity(mapDims, colors, opts.grid, subtype);
161
- if (portal) entities.push(portal);
162
- }
163
- return entities;
164
- }
165
-
166
- // ── Bot generator ────────────────────────────────────────────────────────────
167
-
168
- /**
169
- * Generate bot entities for a map.
170
- *
171
- * - Each bot picks a random skin from BOT_SKIN_POOL for visual variety.
172
- * - Random chance to also carry `atlas_pistol_mk2` weapon.
173
- * - Random count within BOT_RANGE, random positions, random dimensions.
174
- * - Uses the BOT palette color as fallback.
175
- *
176
- * @param {{ gridX: number, gridY: number }} mapDims
177
- * @param {Array<{ key: string, r: number, g: number, b: number, a: number }>} colors
178
- * @param {object} [opts]
179
- * @param {number} [opts.count] Override count (ignores range).
180
- * @param {number} [opts.spawnRadius]
181
- * @param {number} [opts.aggroRange]
182
- * @param {number} [opts.maxLife]
183
- * @param {OccupancyGrid} [opts.grid] If provided, places bots only on walkable cells.
184
- * @returns {object[]}
185
- */
186
- function generateBots(mapDims, colors, opts = {}) {
187
- const count = opts.count ?? randInt(BOT_RANGE[0], BOT_RANGE[1]);
188
- const { spawnRadius = 5, aggroRange = 10, maxLife = 100 } = opts;
189
- const botColor = findColor(colors, 'BOT');
190
- const rgba = botColor ? colorToRgba(botColor) : 'rgba(255, 128, 0, 1)';
191
-
192
- const entities = [];
193
- for (let i = 0; i < count; i++) {
194
- const dim = randInt(DEFAULT_BOT_DIM_RANGE[0], DEFAULT_BOT_DIM_RANGE[1]);
195
-
196
- let cellX, cellY;
197
- if (opts.grid) {
198
- const pos = opts.grid.findPosition(dim, dim);
199
- if (!pos) continue;
200
- opts.grid.block(pos.x, pos.y, dim, dim);
201
- cellX = pos.x;
202
- cellY = pos.y;
203
- } else {
204
- const maxX = Math.max(0, mapDims.gridX - dim);
205
- const maxY = Math.max(0, mapDims.gridY - dim);
206
- cellX = randInt(0, maxX);
207
- cellY = randInt(0, maxY);
208
- }
209
-
210
- const skin = BOT_SKIN_POOL[Math.floor(Math.random() * BOT_SKIN_POOL.length)];
211
- const hasWeapon = Math.random() < BOT_WEAPON_CHANCE;
212
- const itemIds = hasWeapon ? [skin, 'atlas_pistol_mk2'] : [skin];
213
-
214
- entities.push({
215
- entityType: 'bot',
216
- initCellX: cellX,
217
- initCellY: cellY,
218
- dimX: dim,
219
- dimY: dim,
220
- color: rgba,
221
- objectLayerItemIds: itemIds,
222
- spawnRadius,
223
- aggroRange,
224
- maxLife,
225
- lifeRegen: 0,
226
- });
227
- }
228
- return entities;
229
- }
230
40
 
231
41
  // ── Single map generator ─────────────────────────────────────────────────────
232
42
 
@@ -241,6 +51,7 @@ function generateBots(mapDims, colors, opts = {}) {
241
51
  * @param {number} [opts.obstacleCount]
242
52
  * @param {number} [opts.foregroundCount]
243
53
  * @param {number} [opts.botCount]
54
+ * @param {number} [opts.resourceCount]
244
55
  * @returns {object} CyberiaMap-shaped plain object.
245
56
  */
246
57
  function generateFallbackMap(mapCode, colors, opts = {}) {
@@ -263,10 +74,13 @@ function generateFallbackMap(mapCode, colors, opts = {}) {
263
74
  // 5. Bots — placed on walkable cells (avoids obstacles and portals)
264
75
  const bots = generateBots(mapDims, colors, { count: opts.botCount, grid });
265
76
 
266
- // 6. Foregrounddecorative, no collision restriction
77
+ // 6. Resourcesstatic exploitable entities placed on walkable cells
78
+ const resources = generateResources(mapDims, colors, { count: opts.resourceCount, grid });
79
+
80
+ // 7. Foreground — decorative, no collision restriction
267
81
  const foreground = generateForeground(mapDims, colors, { count: opts.foregroundCount });
268
82
 
269
- const entities = [...floors, ...obstacles, ...portalEntities, ...foreground, ...bots];
83
+ const entities = [...floors, ...obstacles, ...portalEntities, ...foreground, ...bots, ...resources];
270
84
 
271
85
  return {
272
86
  code: mapCode,
@@ -296,6 +110,7 @@ function generateFallbackMap(mapCode, colors, opts = {}) {
296
110
  * @param {number} [opts.obstacleCount] Obstacles per map (random if omitted).
297
111
  * @param {number} [opts.foregroundCount] Foreground entities per map (random if omitted).
298
112
  * @param {number} [opts.botCount] Bots per map (random if omitted).
113
+ * @param {number} [opts.resourceCount] Resources per map (random if omitted).
299
114
  * @param {Array} [opts.colors] Override palette.
300
115
  * @returns {{
301
116
  * instance: object,
@@ -313,6 +128,7 @@ function generateFallbackWorld(opts = {}) {
313
128
  obstacleCount,
314
129
  foregroundCount,
315
130
  botCount,
131
+ resourceCount,
316
132
  colors = CYBERIA_INSTANCE_CONF_DEFAULTS.colors,
317
133
  } = opts;
318
134
 
@@ -329,6 +145,7 @@ function generateFallbackWorld(opts = {}) {
329
145
  obstacleCount,
330
146
  foregroundCount,
331
147
  botCount,
148
+ resourceCount,
332
149
  }),
333
150
  );
334
151
 
@@ -358,11 +175,4 @@ function generateFallbackWorld(opts = {}) {
358
175
 
359
176
  // ── Public API ───────────────────────────────────────────────────────────────
360
177
 
361
- export {
362
- generateFallbackWorld,
363
- generateFallbackMap,
364
- generateFloorEntities,
365
- generatePortalEntity,
366
- generatePortalEntities,
367
- generateBots,
368
- };
178
+ export { generateFallbackWorld, generateFallbackMap };
@@ -3,8 +3,8 @@ import { CyberiaInstanceService } from './cyberia-instance.service.js';
3
3
 
4
4
  const logger = loggerFactory(import.meta);
5
5
 
6
- const CyberiaInstanceController = {
7
- fallbackWorld: async (req, res, options) => {
6
+ class CyberiaInstanceController {
7
+ static fallbackWorld = async (req, res, options) => {
8
8
  try {
9
9
  const result = await CyberiaInstanceService.fallbackWorld(req);
10
10
  return res.status(200).json({ status: 'success', data: result });
@@ -12,8 +12,8 @@ const CyberiaInstanceController = {
12
12
  logger.error(error, error.stack);
13
13
  return res.status(400).json({ status: 'error', message: error.message });
14
14
  }
15
- },
16
- portalConnect: async (req, res, options) => {
15
+ };
16
+ static portalConnect = async (req, res, options) => {
17
17
  try {
18
18
  const result = await CyberiaInstanceService.portalConnect(req, res, options);
19
19
  return res.status(200).json({ status: 'success', data: result });
@@ -21,8 +21,8 @@ const CyberiaInstanceController = {
21
21
  logger.error(error, error.stack);
22
22
  return res.status(400).json({ status: 'error', message: error.message });
23
23
  }
24
- },
25
- post: async (req, res, options) => {
24
+ };
25
+ static post = async (req, res, options) => {
26
26
  try {
27
27
  const result = await CyberiaInstanceService.post(req, res, options);
28
28
  return res.status(200).json({
@@ -36,8 +36,8 @@ const CyberiaInstanceController = {
36
36
  message: error.message,
37
37
  });
38
38
  }
39
- },
40
- get: async (req, res, options) => {
39
+ };
40
+ static get = async (req, res, options) => {
41
41
  try {
42
42
  const { page, limit } = req.query;
43
43
  const result = await CyberiaInstanceService.get(
@@ -56,8 +56,8 @@ const CyberiaInstanceController = {
56
56
  message: error.message,
57
57
  });
58
58
  }
59
- },
60
- put: async (req, res, options) => {
59
+ };
60
+ static put = async (req, res, options) => {
61
61
  try {
62
62
  const result = await CyberiaInstanceService.put(req, res, options);
63
63
  return res.status(200).json({
@@ -71,8 +71,8 @@ const CyberiaInstanceController = {
71
71
  message: error.message,
72
72
  });
73
73
  }
74
- },
75
- delete: async (req, res, options) => {
74
+ };
75
+ static delete = async (req, res, options) => {
76
76
  try {
77
77
  const result = await CyberiaInstanceService.delete(req, res, options);
78
78
  return res.status(200).json({
@@ -86,7 +86,7 @@ const CyberiaInstanceController = {
86
86
  message: error.message,
87
87
  });
88
88
  }
89
- },
90
- };
89
+ };
90
+ }
91
91
 
92
92
  export { CyberiaInstanceController };
@@ -52,6 +52,9 @@ const CyberiaInstanceSchema = new Schema(
52
52
  // Vertex set of the graph
53
53
  cyberiaMapCodes: { type: [String], default: [] },
54
54
 
55
+ // Instance-level object layer item IDs.
56
+ itemIds: { type: [String], default: [] },
57
+
55
58
  // Directed edge set of the graph
56
59
  portals: { type: [PortalEdgeSchema], default: [] },
57
60
 
@@ -1,14 +1,13 @@
1
1
  import { DataBaseProvider } from '../../db/DataBaseProvider.js';
2
2
  import { loggerFactory } from '../../server/logger.js';
3
3
  import { DataQuery } from '../../server/data-query.js';
4
- import { connectPortals, generateProceduralEntities } from './cyberia-portal-connector.js';
4
+ import { connectPortals } from './cyberia-portal-connector.js';
5
5
  import { generateFallbackWorld } from './cyberia-fallback-world.js';
6
- import { CYBERIA_INSTANCE_CONF_DEFAULTS } from '../cyberia-instance-conf/cyberia-instance-conf.defaults.js';
7
6
 
8
7
  const logger = loggerFactory(import.meta);
9
8
 
10
- const CyberiaInstanceService = {
11
- post: async (req, res, options) => {
9
+ class CyberiaInstanceService {
10
+ static post = async (req, res, options) => {
12
11
  /** @type {import('./cyberia-instance.model.js').CyberiaInstanceModel} */
13
12
  const CyberiaInstance = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaInstance;
14
13
  const CyberiaInstanceConf =
@@ -23,7 +22,7 @@ const CyberiaInstanceService = {
23
22
  const conf = await CyberiaInstanceConf.findOneAndUpdate(
24
23
  { instanceCode: instance.code },
25
24
  { $setOnInsert: { instanceCode: instance.code } },
26
- { upsert: true, new: true },
25
+ { upsert: true, returnDocument: 'after' },
27
26
  );
28
27
  if (conf && !instance.conf) {
29
28
  await CyberiaInstance.findByIdAndUpdate(instance._id, { conf: conf._id });
@@ -35,8 +34,8 @@ const CyberiaInstanceService = {
35
34
  }
36
35
 
37
36
  return instance;
38
- },
39
- get: async (req, res, options) => {
37
+ };
38
+ static get = async (req, res, options) => {
40
39
  /** @type {import('./cyberia-instance.model.js').CyberiaInstanceModel} */
41
40
  const CyberiaInstance = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaInstance;
42
41
  const populateCreator = { path: 'creator', model: 'User', select: '_id username' };
@@ -52,8 +51,8 @@ const CyberiaInstanceService = {
52
51
 
53
52
  const totalPages = Math.ceil(total / limit);
54
53
  return { data, total, page, totalPages };
55
- },
56
- put: async (req, res, options) => {
54
+ };
55
+ static put = async (req, res, options) => {
57
56
  /** @type {import('./cyberia-instance.model.js').CyberiaInstanceModel} */
58
57
  const CyberiaInstance = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaInstance;
59
58
  const instance = await CyberiaInstance.findById(req.params.id);
@@ -65,7 +64,7 @@ const CyberiaInstanceService = {
65
64
  await File.findByIdAndDelete(instance.thumbnail);
66
65
  }
67
66
  return await CyberiaInstance.findByIdAndUpdate(req.params.id, req.body, { returnDocument: 'after' });
68
- },
67
+ };
69
68
  /**
70
69
  * Central portal connector endpoint.
71
70
  *
@@ -73,14 +72,14 @@ const CyberiaInstanceService = {
73
72
  * from cyberia-portal-connector.js so the same logic can be used by the
74
73
  * GUI without a DB dependency.
75
74
  *
76
- * Optionally generates procedural fallback obstacle/foreground entities
77
- * for maps that have none, controlled by query flags:
78
- * ?generateEntities=true — append procedural obstacles & foreground
79
- * ?obstacleCount=N — obstacles per map (default 5)
80
- * ?foregroundCount=N — foreground per map (default 3)
81
- * ?persist=true — save generated portals & entities to DB
75
+ * Builds a minimal ring connecting all maps and assigns random portal
76
+ * subtypes to remaining portals. Does NOT generate procedural entities
77
+ * entity generation is handled exclusively by the fallback world logic
78
+ * (cyberia-world-generator.js).
79
+ *
80
+ * ?persist=true — save generated portals to DB
82
81
  */
83
- portalConnect: async (req, res, options) => {
82
+ static portalConnect = async (req, res, options) => {
84
83
  const CyberiaInstance = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaInstance;
85
84
  const CyberiaMap = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaMap;
86
85
 
@@ -103,53 +102,19 @@ const CyberiaInstanceService = {
103
102
  // ── Portal topology (pure function) ──────────────────────────────────
104
103
  const result = connectPortals(mapCodes, mapDocs);
105
104
 
106
- // ── Procedural entity generation (optional) ──────────────────────────
107
- const colors = CYBERIA_INSTANCE_CONF_DEFAULTS.colors;
108
- const wantEntities = req.query?.generateEntities === 'true';
109
- const obstacleCount = req.query?.obstacleCount ? parseInt(req.query.obstacleCount, 10) : undefined;
110
- const foregroundCount = req.query?.foregroundCount ? parseInt(req.query.foregroundCount, 10) : undefined;
111
- const seed = instance.seed || '';
112
-
113
- const generatedEntities = {};
114
- if (wantEntities) {
115
- for (const doc of mapDocs) {
116
- const hasObstacles = (doc.entities || []).some((e) => e.entityType === 'obstacle');
117
- const hasForeground = (doc.entities || []).some((e) => e.entityType === 'foreground');
118
- if (!hasObstacles || !hasForeground) {
119
- const mapSeed = seed ? `${seed}:${doc.code}` : doc.code;
120
- const generated = generateProceduralEntities({ gridX: doc.gridX || 16, gridY: doc.gridY || 16 }, colors, {
121
- obstacleCount,
122
- foregroundCount,
123
- seed: mapSeed,
124
- });
125
- generatedEntities[doc.code] = {
126
- obstacles: hasObstacles ? [] : generated.obstacles,
127
- foreground: hasForeground ? [] : generated.foreground,
128
- };
129
- }
130
- }
131
- }
132
-
133
105
  // ── Persist to DB when requested ─────────────────────────────────────
134
106
  const persist = req.query?.persist === 'true';
135
107
  if (persist) {
136
108
  await CyberiaInstance.findByIdAndUpdate(req.params.id, { portals: result.portals });
137
- for (const [mapCode, ents] of Object.entries(generatedEntities)) {
138
- const toAdd = [...ents.obstacles, ...ents.foreground];
139
- if (toAdd.length > 0) {
140
- await CyberiaMap.findOneAndUpdate({ code: mapCode }, { $push: { entities: { $each: toAdd } } });
141
- }
142
- }
143
109
  }
144
110
 
145
111
  return {
146
112
  ...result,
147
- ...(wantEntities ? { generatedEntities } : {}),
148
113
  persisted: persist,
149
114
  };
150
- },
115
+ };
151
116
 
152
- delete: async (req, res, options) => {
117
+ static delete = async (req, res, options) => {
153
118
  /** @type {import('./cyberia-instance.model.js').CyberiaInstanceModel} */
154
119
  const CyberiaInstance = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaInstance;
155
120
  if (req.params.id) {
@@ -163,7 +128,7 @@ const CyberiaInstanceService = {
163
128
  }
164
129
  return await CyberiaInstance.findByIdAndDelete(req.params.id);
165
130
  } else return await CyberiaInstance.deleteMany();
166
- },
131
+ };
167
132
 
168
133
  /**
169
134
  * Return an in-memory procedural fallback world.
@@ -177,7 +142,7 @@ const CyberiaInstanceService = {
177
142
  * ?obstacleCount=<number> — obstacles per map (random 12–20 if omitted)
178
143
  * ?foregroundCount=<number>— foreground per map (random 6–12 if omitted)
179
144
  */
180
- fallbackWorld: async (req) => {
145
+ static fallbackWorld = async (req) => {
181
146
  const q = req.query || {};
182
147
  return generateFallbackWorld({
183
148
  mapCount: q.mapCount ? parseInt(q.mapCount, 10) : undefined,
@@ -185,7 +150,7 @@ const CyberiaInstanceService = {
185
150
  obstacleCount: q.obstacleCount ? parseInt(q.obstacleCount, 10) : undefined,
186
151
  foregroundCount: q.foregroundCount ? parseInt(q.foregroundCount, 10) : undefined,
187
152
  });
188
- },
189
- };
153
+ };
154
+ }
190
155
 
191
156
  export { CyberiaInstanceService };