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.
- package/.env.example +0 -2
- package/.github/workflows/engine-cyberia.cd.yml +10 -8
- package/.github/workflows/engine-cyberia.ci.yml +12 -29
- package/.github/workflows/ghpkg.ci.yml +4 -4
- package/.github/workflows/npmpkg.ci.yml +28 -11
- package/.github/workflows/publish.ci.yml +21 -2
- package/.github/workflows/pwa-microservices-template-page.cd.yml +4 -5
- package/.github/workflows/pwa-microservices-template-test.ci.yml +3 -3
- package/.github/workflows/release.cd.yml +14 -10
- package/CHANGELOG.md +783 -1
- package/CLI-HELP.md +95 -18
- package/Dockerfile +0 -2
- package/README.md +290 -220
- package/bin/build.js +24 -7
- package/bin/cyberia.js +2838 -252
- package/bin/deploy.js +747 -125
- package/bin/file.js +9 -0
- package/bin/index.js +2838 -252
- package/bin/vs.js +1 -1
- package/conf.js +99 -65
- package/deployment.yaml +18 -164
- package/hardhat/hardhat.config.js +13 -13
- package/hardhat/ignition/modules/ObjectLayerToken.js +1 -1
- package/hardhat/package-lock.json +2559 -5864
- package/hardhat/package.json +14 -23
- package/hardhat/scripts/deployObjectLayerToken.js +1 -1
- package/hardhat/test/ObjectLayerToken.js +4 -2
- package/hardhat/types/ethers-contracts/ObjectLayerToken.ts +690 -0
- package/hardhat/types/ethers-contracts/common.ts +92 -0
- package/hardhat/types/ethers-contracts/factories/ObjectLayerToken__factory.ts +1055 -0
- package/hardhat/types/ethers-contracts/factories/index.ts +4 -0
- package/hardhat/types/ethers-contracts/hardhat.d.ts +47 -0
- package/hardhat/types/ethers-contracts/index.ts +6 -0
- package/jsconfig.json +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +6 -5
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +6 -5
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +18 -164
- package/manifests/deployment/dd-cyberia-development/proxy.yaml +7 -79
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -6
- package/manifests/deployment/dd-test-development/deployment.yaml +112 -28
- package/manifests/deployment/dd-test-development/proxy.yaml +46 -1
- package/manifests/deployment/playwright/deployment.yaml +1 -1
- package/nodemon.json +1 -1
- package/package.json +39 -24
- package/proxy.yaml +7 -79
- package/scripts/k3s-node-setup.sh +2 -2
- package/scripts/nat-iptables.sh +103 -18
- package/scripts/rhel-grpc-setup.sh +56 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +58 -14
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +23 -14
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +5 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +148 -20
- package/src/api/core/core.controller.js +10 -10
- package/src/api/core/core.service.js +10 -10
- package/src/api/crypto/crypto.controller.js +8 -8
- package/src/api/crypto/crypto.service.js +8 -8
- package/src/api/cyberia-action/cyberia-action.controller.js +74 -0
- package/src/api/cyberia-action/cyberia-action.model.js +87 -0
- package/src/api/cyberia-action/cyberia-action.router.js +27 -0
- package/src/api/cyberia-action/cyberia-action.service.js +42 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +93 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +36 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +29 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +51 -0
- package/src/api/cyberia-entity/cyberia-entity.controller.js +74 -0
- package/src/api/cyberia-entity/cyberia-entity.model.js +24 -0
- package/src/api/cyberia-entity/cyberia-entity.router.js +27 -0
- package/src/api/cyberia-entity/cyberia-entity.service.js +42 -0
- package/src/api/cyberia-instance/cyberia-fallback-world.js +178 -0
- package/src/api/cyberia-instance/cyberia-instance.controller.js +92 -0
- package/src/api/cyberia-instance/cyberia-instance.model.js +87 -0
- package/src/api/cyberia-instance/cyberia-instance.router.js +63 -0
- package/src/api/cyberia-instance/cyberia-instance.service.js +156 -0
- package/src/api/cyberia-instance/cyberia-portal-connector.js +260 -0
- package/src/api/cyberia-instance/cyberia-world-generator.js +505 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +74 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.defaults.js +574 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +231 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +27 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +46 -0
- package/src/api/cyberia-map/cyberia-map.controller.js +79 -0
- package/src/api/cyberia-map/cyberia-map.model.js +30 -0
- package/src/api/cyberia-map/cyberia-map.router.js +40 -0
- package/src/api/cyberia-map/cyberia-map.service.js +74 -0
- package/src/api/cyberia-quest/cyberia-quest.controller.js +74 -0
- package/src/api/cyberia-quest/cyberia-quest.model.js +67 -0
- package/src/api/cyberia-quest/cyberia-quest.router.js +27 -0
- package/src/api/cyberia-quest/cyberia-quest.service.js +42 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.js +74 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +49 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +27 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +42 -0
- package/src/api/default/default.controller.js +10 -10
- package/src/api/default/default.service.js +10 -10
- package/src/api/document/document.controller.js +12 -12
- package/src/api/document/document.model.js +10 -16
- package/src/api/file/file.controller.js +8 -8
- package/src/api/file/file.model.js +10 -10
- package/src/api/file/file.ref.json +18 -0
- package/src/api/file/file.service.js +36 -36
- package/src/api/instance/instance.controller.js +10 -10
- package/src/api/instance/instance.model.js +4 -10
- package/src/api/instance/instance.service.js +10 -10
- package/src/api/ipfs/ipfs.controller.js +15 -36
- package/src/api/ipfs/ipfs.model.js +47 -47
- package/src/api/ipfs/ipfs.router.js +8 -13
- package/src/api/ipfs/ipfs.service.js +67 -129
- package/src/api/object-layer/object-layer.controller.js +12 -12
- package/src/api/object-layer/object-layer.model.js +4 -17
- package/src/api/object-layer/object-layer.router.js +30 -0
- package/src/api/object-layer/object-layer.service.js +126 -43
- package/src/api/object-layer-render-frames/object-layer-render-frames.controller.js +10 -10
- package/src/api/object-layer-render-frames/object-layer-render-frames.model.js +6 -16
- package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +18 -14
- package/src/api/test/test.controller.js +8 -8
- package/src/api/test/test.service.js +8 -8
- package/src/api/user/guest.service.js +99 -0
- package/src/api/user/user.controller.js +6 -6
- package/src/api/user/user.model.js +8 -13
- package/src/api/user/user.service.js +11 -27
- package/src/cli/cluster.js +68 -21
- package/src/cli/db.js +753 -825
- package/src/cli/deploy.js +215 -125
- package/src/cli/env.js +29 -0
- package/src/cli/fs.js +82 -8
- package/src/cli/image.js +43 -1
- package/src/cli/index.js +74 -3
- package/src/cli/kubectl.js +211 -0
- package/src/cli/release.js +340 -0
- package/src/cli/repository.js +475 -74
- package/src/cli/run.js +582 -43
- package/src/cli/secrets.js +73 -0
- package/src/cli/ssh.js +1 -1
- package/src/cli/static.js +43 -115
- package/src/cli/test.js +3 -3
- package/src/client/Cryptokoyn.index.js +18 -22
- package/src/client/CyberiaPortal.index.js +19 -24
- package/src/client/Default.index.js +21 -34
- package/src/client/Itemledger.index.js +20 -27
- package/src/client/Underpost.index.js +19 -24
- package/src/client/components/core/404.js +4 -4
- package/src/client/components/core/500.js +4 -4
- package/src/client/components/core/Account.js +73 -60
- package/src/client/components/core/AgGrid.js +23 -33
- package/src/client/components/core/Alert.js +12 -13
- package/src/client/components/core/AppStore.js +69 -0
- package/src/client/components/core/Auth.js +35 -37
- package/src/client/components/core/Badge.js +7 -13
- package/src/client/components/core/BtnIcon.js +15 -17
- package/src/client/components/core/CalendarCore.js +43 -64
- package/src/client/components/core/Chat.js +13 -15
- package/src/client/components/core/ClientEvents.js +87 -0
- package/src/client/components/core/ColorPaletteElement.js +309 -0
- package/src/client/components/core/Content.js +17 -14
- package/src/client/components/core/Css.js +15 -71
- package/src/client/components/core/CssCore.js +12 -16
- package/src/client/components/core/D3Chart.js +4 -4
- package/src/client/components/core/Docs.js +64 -91
- package/src/client/components/core/DropDown.js +194 -96
- package/src/client/components/core/EventBus.js +92 -0
- package/src/client/components/core/EventsUI.js +14 -17
- package/src/client/components/core/FileExplorer.js +96 -228
- package/src/client/components/core/FullScreen.js +47 -75
- package/src/client/components/core/Input.js +24 -69
- package/src/client/components/core/Keyboard.js +26 -19
- package/src/client/components/core/KeyboardAvoidance.js +145 -0
- package/src/client/components/core/LoadingAnimation.js +25 -31
- package/src/client/components/core/LogIn.js +43 -43
- package/src/client/components/core/LogOut.js +25 -16
- package/src/client/components/core/Modal.js +462 -179
- package/src/client/components/core/NotificationManager.js +14 -18
- package/src/client/components/core/Panel.js +54 -51
- package/src/client/components/core/PanelForm.js +44 -144
- package/src/client/components/core/Polyhedron.js +110 -214
- package/src/client/components/core/PublicProfile.js +39 -32
- package/src/client/components/core/Recover.js +48 -44
- package/src/client/components/core/Responsive.js +88 -32
- package/src/client/components/core/RichText.js +9 -18
- package/src/client/components/core/Router.js +24 -3
- package/src/client/components/core/SearchBox.js +37 -37
- package/src/client/components/core/SignUp.js +39 -30
- package/src/client/components/core/SocketIo.js +112 -30
- package/src/client/components/core/SocketIoHandler.js +75 -0
- package/src/client/components/core/Stream.js +143 -95
- package/src/client/components/core/ToggleSwitch.js +8 -20
- package/src/client/components/core/ToolTip.js +5 -17
- package/src/client/components/core/Translate.js +56 -59
- package/src/client/components/core/Validator.js +26 -16
- package/src/client/components/core/Wallet.js +15 -26
- package/src/client/components/core/Webhook.js +40 -7
- package/src/client/components/core/Worker.js +163 -27
- package/src/client/components/core/windowGetDimensions.js +7 -7
- package/src/client/components/cryptokoyn/{MenuCryptokoyn.js → AppShellCryptokoyn.js} +59 -59
- package/src/client/components/cryptokoyn/AppStoreCryptokoyn.js +5 -0
- package/src/client/components/cryptokoyn/CssCryptokoyn.js +15 -15
- package/src/client/components/cryptokoyn/LogInCryptokoyn.js +9 -7
- package/src/client/components/cryptokoyn/LogOutCryptokoyn.js +8 -6
- package/src/client/components/cryptokoyn/RouterCryptokoyn.js +37 -0
- package/src/client/components/cryptokoyn/SettingsCryptokoyn.js +4 -4
- package/src/client/components/cryptokoyn/SignUpCryptokoyn.js +6 -4
- package/src/client/components/cryptokoyn/SocketIoCryptokoyn.js +3 -51
- package/src/client/components/cyberia/InstanceEngineCyberia.js +781 -0
- package/src/client/components/cyberia/MapEngineCyberia.js +1836 -2
- package/src/client/components/cyberia/ObjectLayerEngine.js +19 -0
- package/src/client/components/cyberia/ObjectLayerEngineModal.js +1220 -99
- package/src/client/components/cyberia/ObjectLayerEngineViewer.js +252 -316
- package/src/client/components/cyberia-portal/{MenuCyberiaPortal.js → AppShellCyberiaPortal.js} +136 -103
- package/src/client/components/cyberia-portal/AppStoreCyberiaPortal.js +5 -0
- package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +462 -32
- package/src/client/components/cyberia-portal/CssCyberiaPortal.js +15 -15
- package/src/client/components/cyberia-portal/LogInCyberiaPortal.js +9 -7
- package/src/client/components/cyberia-portal/LogOutCyberiaPortal.js +8 -6
- package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +4 -4
- package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +60 -0
- package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +4 -4
- package/src/client/components/cyberia-portal/SignUpCyberiaPortal.js +6 -4
- package/src/client/components/cyberia-portal/SocketIoCyberiaPortal.js +3 -49
- package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +8 -4
- package/src/client/components/default/{MenuDefault.js → AppShellDefault.js} +91 -91
- package/src/client/components/default/AppStoreDefault.js +5 -0
- package/src/client/components/default/CssDefault.js +12 -12
- package/src/client/components/default/LogInDefault.js +9 -7
- package/src/client/components/default/LogOutDefault.js +8 -6
- package/src/client/components/default/RouterDefault.js +47 -0
- package/src/client/components/default/SettingsDefault.js +4 -4
- package/src/client/components/default/SignUpDefault.js +6 -4
- package/src/client/components/default/SocketIoDefault.js +3 -51
- package/src/client/components/default/TranslateDefault.js +3 -3
- package/src/client/components/itemledger/{MenuItemledger.js → AppShellItemledger.js} +59 -59
- package/src/client/components/itemledger/AppStoreItemledger.js +5 -0
- package/src/client/components/itemledger/CssItemledger.js +15 -15
- package/src/client/components/itemledger/LogInItemledger.js +9 -7
- package/src/client/components/itemledger/LogOutItemledger.js +8 -6
- package/src/client/components/itemledger/RouterItemledger.js +38 -0
- package/src/client/components/itemledger/SettingsItemledger.js +4 -4
- package/src/client/components/itemledger/SignUpItemledger.js +6 -4
- package/src/client/components/itemledger/SocketIoItemledger.js +3 -51
- package/src/client/components/itemledger/TranslateItemledger.js +3 -3
- package/src/client/components/underpost/{MenuUnderpost.js → AppShellUnderpost.js} +92 -92
- package/src/client/components/underpost/AppStoreUnderpost.js +5 -0
- package/src/client/components/underpost/CssUnderpost.js +14 -14
- package/src/client/components/underpost/CyberpunkBloggerUnderpost.js +4 -4
- package/src/client/components/underpost/DocumentSearchProvider.js +1 -1
- package/src/client/components/underpost/LabGalleryUnderpost.js +12 -15
- package/src/client/components/underpost/LogInUnderpost.js +9 -7
- package/src/client/components/underpost/LogOutUnderpost.js +8 -6
- package/src/client/components/underpost/RouterUnderpost.js +45 -0
- package/src/client/components/underpost/SettingsUnderpost.js +4 -4
- package/src/client/components/underpost/SignUpUnderpost.js +6 -4
- package/src/client/components/underpost/SocketIoUnderpost.js +3 -51
- package/src/client/components/underpost/TranslateUnderpost.js +4 -4
- package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +235 -0
- package/src/client/public/cyberia-docs/ARCHITECTURE.md +443 -0
- package/src/client/public/cyberia-docs/CYBERIA-CLI.md +417 -0
- package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +313 -0
- package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +260 -0
- package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +241 -0
- package/src/client/public/cyberia-docs/HARDHAT-MODULE.md +300 -0
- package/src/client/public/cyberia-docs/OFF-CHAIN-ECONOMY.md +279 -0
- package/src/client/public/cyberia-docs/QUEST-SYSTEM.md +206 -0
- package/src/client/public/cyberia-docs/ROADMAP.md +240 -0
- package/src/client/public/cyberia-docs/WHITE-PAPER.md +732 -0
- package/src/client/services/atlas-sprite-sheet/atlas-sprite-sheet.service.js +14 -20
- package/src/client/services/core/core.service.js +35 -55
- package/src/client/services/crypto/crypto.service.js +8 -13
- package/src/client/services/cyberia-action/cyberia-action.service.js +99 -0
- package/src/client/services/cyberia-dialogue/cyberia-dialogue.service.js +99 -0
- package/src/client/services/cyberia-entity/cyberia-entity.management.js +57 -0
- package/src/client/services/cyberia-entity/cyberia-entity.service.js +99 -0
- package/src/client/services/cyberia-instance/cyberia-instance.management.js +194 -0
- package/src/client/services/cyberia-instance/cyberia-instance.service.js +116 -0
- package/src/client/services/cyberia-instance-conf/cyberia-instance-conf.service.js +99 -0
- package/src/client/services/cyberia-map/cyberia-map.management.js +193 -0
- package/src/client/services/cyberia-map/cyberia-map.service.js +120 -0
- package/src/client/services/cyberia-quest/cyberia-quest.service.js +99 -0
- package/src/client/services/cyberia-quest-progress/cyberia-quest-progress.service.js +99 -0
- package/src/client/services/default/default.management.js +159 -267
- package/src/client/services/default/default.service.js +10 -16
- package/src/client/services/document/document.service.js +14 -19
- package/src/client/services/file/file.service.js +8 -13
- package/src/client/services/instance/instance.management.js +6 -6
- package/src/client/services/instance/instance.service.js +10 -15
- package/src/client/services/ipfs/ipfs.service.js +14 -40
- package/src/client/services/object-layer/object-layer.management.js +14 -14
- package/src/client/services/object-layer/object-layer.service.js +39 -24
- package/src/client/services/object-layer-render-frames/object-layer-render-frames.service.js +10 -16
- package/src/client/services/test/test.service.js +8 -13
- package/src/client/services/user/guest.service.js +86 -0
- package/src/client/services/user/user.management.js +6 -6
- package/src/client/services/user/user.service.js +14 -20
- package/src/client/ssr/body/404.js +3 -3
- package/src/client/ssr/body/500.js +3 -3
- package/src/client/ssr/body/CacheControl.js +5 -2
- package/src/client/ssr/body/DefaultSplashScreen.js +19 -12
- package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +13 -6
- package/src/client/ssr/head/PwaItemledger.js +197 -60
- package/src/client/ssr/mailer/DefaultRecoverEmail.js +19 -20
- package/src/client/ssr/mailer/DefaultVerifyEmail.js +15 -16
- package/src/client/ssr/offline/Maintenance.js +12 -11
- package/src/client/ssr/offline/NoNetworkConnection.js +3 -3
- package/src/client/ssr/pages/CyberiaServerMetrics.js +1 -1
- package/src/client/ssr/pages/Test.js +2 -2
- package/src/client/sw/core.sw.js +212 -0
- package/src/grpc/cyberia/grpc-server.js +642 -0
- package/src/index.js +24 -1
- package/src/runtime/cyberia-client/Dockerfile +80 -0
- package/src/runtime/cyberia-server/Dockerfile +37 -0
- package/src/runtime/express/Dockerfile +5 -1
- package/src/runtime/express/Express.js +18 -1
- package/src/runtime/lampp/Dockerfile +17 -5
- package/src/runtime/lampp/Lampp.js +27 -4
- package/src/runtime/wp/Dockerfile +62 -0
- package/src/runtime/wp/Wp.js +639 -0
- package/src/server/atlas-sprite-sheet-generator.js +4 -2
- package/src/server/auth.js +24 -1
- package/src/server/backup.js +37 -9
- package/src/server/client-build-docs.js +52 -46
- package/src/server/client-build.js +356 -82
- package/src/server/client-formatted.js +140 -57
- package/src/server/conf.js +29 -13
- package/src/server/cron.js +25 -23
- package/src/server/data-query.js +32 -20
- package/src/server/dns.js +24 -1
- package/src/server/ipfs-client.js +253 -89
- package/src/server/object-layer.js +150 -114
- package/src/server/peer.js +8 -0
- package/src/server/process.js +13 -27
- package/src/server/runtime.js +25 -1
- package/src/server/semantic-layer-generator-floor.js +319 -0
- package/src/server/semantic-layer-generator-resource.js +259 -0
- package/src/server/semantic-layer-generator-skin.js +1164 -0
- package/src/server/semantic-layer-generator.js +211 -542
- package/src/server/shape-generator.js +108 -0
- package/src/server/start.js +19 -5
- package/src/server/valkey.js +141 -235
- package/src/ws/IoInterface.js +1 -10
- package/src/ws/IoServer.js +14 -33
- package/src/ws/core/channels/core.ws.chat.js +65 -20
- package/src/ws/core/channels/core.ws.mailer.js +113 -32
- package/src/ws/core/channels/core.ws.stream.js +90 -31
- package/src/ws/core/core.ws.connection.js +12 -33
- package/src/ws/core/core.ws.emit.js +10 -26
- package/src/ws/core/core.ws.server.js +25 -58
- package/src/ws/default/channels/default.ws.main.js +53 -12
- package/src/ws/default/default.ws.connection.js +26 -13
- package/src/ws/default/default.ws.server.js +30 -12
- package/tsconfig.docs.json +15 -0
- package/typedoc.dd-cyberia.json +29 -0
- package/typedoc.json +29 -0
- package/WHITE-PAPER.md +0 -1540
- package/hardhat/README.md +0 -531
- package/hardhat/WHITE-PAPER.md +0 -1540
- package/jsdoc.dd-cyberia.json +0 -59
- package/jsdoc.json +0 -59
- package/src/api/object-layer/README.md +0 -347
- package/src/client/components/core/ColorPalette.js +0 -5267
- package/src/client/components/core/JoyStick.js +0 -80
- package/src/client/components/cryptokoyn/CommonCryptokoyn.js +0 -29
- package/src/client/components/cryptokoyn/ElementsCryptokoyn.js +0 -38
- package/src/client/components/cryptokoyn/RoutesCryptokoyn.js +0 -39
- package/src/client/components/cyberia-portal/ElementsCyberiaPortal.js +0 -38
- package/src/client/components/cyberia-portal/RoutesCyberiaPortal.js +0 -58
- package/src/client/components/cyberia-portal/ServerCyberiaPortal.js +0 -136
- package/src/client/components/default/ElementsDefault.js +0 -38
- package/src/client/components/default/RoutesDefault.js +0 -49
- package/src/client/components/itemledger/CommonItemledger.js +0 -29
- package/src/client/components/itemledger/ElementsItemledger.js +0 -38
- package/src/client/components/itemledger/RoutesItemledger.js +0 -40
- package/src/client/components/underpost/CommonUnderpost.js +0 -29
- package/src/client/components/underpost/ElementsUnderpost.js +0 -38
- package/src/client/components/underpost/RoutesUnderpost.js +0 -47
- package/src/client/sw/default.sw.js +0 -127
- package/src/client/sw/template.sw.js +0 -84
- package/src/ws/core/management/core.ws.chat.js +0 -8
- package/src/ws/core/management/core.ws.mailer.js +0 -16
- package/src/ws/core/management/core.ws.stream.js +0 -8
- 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
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
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}
|
|
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
|
|
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
|
|
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[]}
|
|
90
|
-
* @property {number[][]}
|
|
91
|
-
* @property {Object<string,number>}
|
|
92
|
-
* @property {Object<string,LayerSpec>} layers
|
|
93
|
-
* @property {string}
|
|
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
|
|
100
|
-
* @property {string[]} shapes
|
|
101
|
-
* @property {number} count
|
|
102
|
-
* @property {number} scaleVariance
|
|
103
|
-
* @property {number} rotationVariance
|
|
104
|
-
* @property {number} colorShift
|
|
105
|
-
* @property {number} jitter
|
|
106
|
-
* @property {number} noiseLevel
|
|
107
|
-
* @property {number} detailLevel
|
|
108
|
-
* @property {number} sparsity
|
|
109
|
-
* @property {number} [frameJitter]
|
|
110
|
-
* @property {number} [frameRotation]
|
|
111
|
-
* @property {number} [frameScale]
|
|
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
|
-
/* ──
|
|
153
|
-
|
|
154
|
-
registerSemantic
|
|
155
|
-
|
|
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
|
|
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;
|
|
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));
|
|
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);
|
|
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
|
-
|
|
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
|
|
660
|
-
* @param {number[][]} colors
|
|
331
|
+
* @param {number[][]} frameMatrix
|
|
332
|
+
* @param {number[][]} colors
|
|
661
333
|
* @param {string} shapeKey
|
|
662
|
-
* @param {Object} transform
|
|
663
|
-
* @param {number[]} color
|
|
334
|
+
* @param {Object} transform
|
|
335
|
+
* @param {number[]} color
|
|
664
336
|
* @param {number} noiseLevel
|
|
665
337
|
* @param {number} detailLevel
|
|
666
|
-
* @param {string} seed
|
|
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}
|
|
712
|
-
* @property {string}
|
|
713
|
-
* @property {number}
|
|
714
|
-
* @property {number}
|
|
715
|
-
* @property {number}
|
|
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}
|
|
722
|
-
* @property {string}
|
|
723
|
-
* @property {Object[]}
|
|
724
|
-
* @property {number[][]} frameMatrix
|
|
725
|
-
* @property {number[][]} colors
|
|
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}
|
|
732
|
-
* @property {string}
|
|
733
|
-
* @property {number}
|
|
404
|
+
* @property {string} itemId
|
|
405
|
+
* @property {string} seed
|
|
406
|
+
* @property {number} frameIndex
|
|
734
407
|
* @property {GeneratedLayer[]} layers
|
|
735
|
-
* @property {number[][]}
|
|
736
|
-
* @property {number[][]}
|
|
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
|
-
*
|
|
744
|
-
*
|
|
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
|
-
|
|
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
|
-
|
|
840
|
-
|
|
841
|
-
const
|
|
842
|
-
|
|
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}
|
|
934
|
-
* @property {string}
|
|
935
|
-
* @property {number}
|
|
601
|
+
* @property {string} itemId
|
|
602
|
+
* @property {string} seed
|
|
603
|
+
* @property {number} frameCount
|
|
936
604
|
* @property {GenerationResult[]} frames
|
|
937
|
-
* @property {Object}
|
|
938
|
-
* @property {Object}
|
|
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
|
|
944
|
-
* compatible with ObjectLayerEngine document creation.
|
|
611
|
+
* Generates N consecutive frames for an item-id.
|
|
945
612
|
*
|
|
946
|
-
*
|
|
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]
|
|
950
|
-
* @param {number} [options.startFrame=0]
|
|
951
|
-
* @param {number} [options.count=3]
|
|
952
|
-
* @param {number} [options.density=0.5]
|
|
953
|
-
* @param {number} [options.frameDuration=250]
|
|
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
|
-
|
|
969
|
-
|
|
639
|
+
// ── Dispatch to custom generator ─────────────────────────────────────────
|
|
640
|
+
if (typeof descriptor.customMultiFrameGenerator === 'function') {
|
|
641
|
+
return descriptor.customMultiFrameGenerator(options, descriptor);
|
|
642
|
+
}
|
|
970
643
|
|
|
971
|
-
//
|
|
644
|
+
// ── Default shape / noise-field pipeline ─────────────────────────────────
|
|
645
|
+
const frames = [];
|
|
972
646
|
for (let fi = 0; fi < frameCount; fi++) {
|
|
973
|
-
|
|
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 {
|
|
743
|
+
export {
|
|
744
|
+
hashString,
|
|
745
|
+
deriveLayerSeed,
|
|
746
|
+
deriveFrameSeed,
|
|
747
|
+
pickColor,
|
|
748
|
+
pickShape,
|
|
749
|
+
seedToUUIDv4,
|
|
750
|
+
GRID_DIM,
|
|
751
|
+
semanticRegistry,
|
|
752
|
+
BIOME_PALETTES,
|
|
753
|
+
};
|