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.
- package/.github/workflows/engine-cyberia.cd.yml +2 -2
- package/.github/workflows/release.cd.yml +1 -2
- package/CHANGELOG.md +351 -1
- package/CLI-HELP.md +40 -13
- package/Dockerfile +0 -4
- package/README.md +242 -497
- package/bin/build.js +19 -5
- package/bin/cyberia.js +1149 -240
- package/bin/deploy.js +570 -1
- package/bin/file.js +6 -0
- package/bin/index.js +1149 -240
- package/bin/vs.js +1 -1
- package/conf.js +67 -89
- package/deployment.yaml +4 -222
- package/hardhat/package-lock.json +32 -32
- package/hardhat/package.json +3 -3
- package/jsconfig.json +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +2 -2
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +2 -2
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +4 -222
- package/manifests/deployment/dd-cyberia-development/proxy.yaml +10 -118
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -6
- package/manifests/deployment/dd-test-development/deployment.yaml +136 -66
- package/manifests/deployment/dd-test-development/proxy.yaml +41 -5
- package/package.json +23 -14
- package/proxy.yaml +10 -118
- package/scripts/k3s-node-setup.sh +2 -2
- package/scripts/nat-iptables.sh +103 -18
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +18 -18
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +7 -14
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +76 -21
- 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 +13 -13
- package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +11 -11
- package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +2 -2
- package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +16 -16
- package/src/api/cyberia-entity/cyberia-entity.controller.js +10 -10
- package/src/api/cyberia-entity/cyberia-entity.service.js +10 -10
- package/src/api/cyberia-instance/cyberia-fallback-world.js +19 -209
- package/src/api/cyberia-instance/cyberia-instance.controller.js +14 -14
- package/src/api/cyberia-instance/cyberia-instance.model.js +3 -0
- package/src/api/cyberia-instance/cyberia-instance.service.js +22 -57
- package/src/api/cyberia-instance/cyberia-portal-connector.js +20 -246
- package/src/api/cyberia-instance/cyberia-world-generator.js +505 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +10 -10
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.defaults.js +216 -55
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +4 -1
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +18 -14
- package/src/api/cyberia-map/cyberia-map.controller.js +10 -10
- package/src/api/cyberia-map/cyberia-map.service.js +10 -10
- 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.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 +12 -12
- package/src/api/ipfs/ipfs.model.js +4 -13
- package/src/api/ipfs/ipfs.service.js +14 -28
- 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.service.js +12 -12
- 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 +3 -20
- package/src/cli/cluster.js +61 -14
- package/src/cli/db.js +47 -2
- package/src/cli/deploy.js +67 -35
- package/src/cli/fs.js +79 -8
- package/src/cli/image.js +43 -1
- package/src/cli/index.js +26 -1
- package/src/cli/release.js +57 -1
- package/src/cli/repository.js +69 -31
- package/src/cli/run.js +415 -36
- package/src/cli/ssh.js +1 -1
- package/src/cli/static.js +43 -115
- package/src/client/Cryptokoyn.index.js +18 -21
- package/src/client/CyberiaPortal.index.js +19 -23
- package/src/client/Default.index.js +21 -33
- package/src/client/Itemledger.index.js +20 -26
- package/src/client/Underpost.index.js +19 -23
- 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 +1 -1
- 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 +42 -63
- 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 +69 -91
- 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 +25 -18
- 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 +41 -41
- package/src/client/components/core/LogOut.js +23 -14
- package/src/client/components/core/Modal.js +462 -178
- package/src/client/components/core/NotificationManager.js +14 -18
- package/src/client/components/core/Panel.js +54 -50
- package/src/client/components/core/PanelForm.js +25 -125
- 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 +31 -2
- package/src/client/components/core/SocketIoHandler.js +6 -6
- 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/Worker.js +163 -27
- package/src/client/components/core/windowGetDimensions.js +7 -7
- package/src/client/components/cryptokoyn/{MenuCryptokoyn.js → AppShellCryptokoyn.js} +57 -57
- package/src/client/components/cryptokoyn/CssCryptokoyn.js +15 -15
- package/src/client/components/cryptokoyn/LogInCryptokoyn.js +6 -4
- package/src/client/components/cryptokoyn/LogOutCryptokoyn.js +6 -4
- 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/cyberia/InstanceEngineCyberia.js +141 -60
- package/src/client/components/cyberia/MapEngineCyberia.js +691 -214
- package/src/client/components/cyberia/ObjectLayerEngine.js +19 -0
- package/src/client/components/cyberia/ObjectLayerEngineModal.js +1204 -94
- package/src/client/components/cyberia/ObjectLayerEngineViewer.js +196 -298
- package/src/client/components/cyberia-portal/{MenuCyberiaPortal.js → AppShellCyberiaPortal.js} +102 -102
- package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +305 -61
- package/src/client/components/cyberia-portal/CssCyberiaPortal.js +15 -15
- package/src/client/components/cyberia-portal/LogInCyberiaPortal.js +6 -4
- package/src/client/components/cyberia-portal/LogOutCyberiaPortal.js +6 -4
- 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/TranslateCyberiaPortal.js +4 -4
- package/src/client/components/default/{MenuDefault.js → AppShellDefault.js} +87 -87
- package/src/client/components/default/CssDefault.js +12 -12
- package/src/client/components/default/LogInDefault.js +6 -4
- package/src/client/components/default/LogOutDefault.js +6 -4
- 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/TranslateDefault.js +3 -3
- package/src/client/components/itemledger/{MenuItemledger.js → AppShellItemledger.js} +57 -57
- package/src/client/components/itemledger/CssItemledger.js +15 -15
- package/src/client/components/itemledger/LogInItemledger.js +6 -4
- package/src/client/components/itemledger/LogOutItemledger.js +6 -4
- 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/TranslateItemledger.js +3 -3
- package/src/client/components/underpost/{MenuUnderpost.js → AppShellUnderpost.js} +88 -88
- 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 +6 -4
- package/src/client/components/underpost/LogOutUnderpost.js +6 -4
- 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/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 +17 -49
- 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 +10 -16
- package/src/client/services/cyberia-entity/cyberia-entity.management.js +5 -5
- package/src/client/services/cyberia-entity/cyberia-entity.service.js +10 -16
- package/src/client/services/cyberia-instance/cyberia-instance.management.js +6 -6
- package/src/client/services/cyberia-instance/cyberia-instance.service.js +12 -18
- package/src/client/services/cyberia-instance-conf/cyberia-instance-conf.service.js +10 -16
- package/src/client/services/cyberia-map/cyberia-map.management.js +6 -6
- package/src/client/services/cyberia-map/cyberia-map.service.js +12 -18
- 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 +5 -5
- package/src/client/services/instance/instance.service.js +10 -15
- package/src/client/services/ipfs/ipfs.service.js +12 -18
- package/src/client/services/object-layer/object-layer.management.js +12 -12
- package/src/client/services/object-layer/object-layer.service.js +20 -26
- 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 +5 -5
- 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/Test.js +2 -2
- package/src/client/sw/core.sw.js +212 -0
- package/src/grpc/cyberia/grpc-server.js +179 -67
- package/src/index.js +1 -1
- package/src/runtime/cyberia-client/Dockerfile +80 -0
- package/src/runtime/cyberia-server/Dockerfile +37 -0
- package/src/runtime/express/Dockerfile +4 -4
- package/src/runtime/lampp/Dockerfile +8 -7
- package/src/runtime/wp/Dockerfile +11 -17
- package/src/server/atlas-sprite-sheet-generator.js +4 -2
- package/src/server/client-build-docs.js +45 -46
- package/src/server/client-build.js +334 -60
- package/src/server/client-formatted.js +47 -16
- package/src/server/conf.js +5 -4
- package/src/server/data-query.js +32 -20
- package/src/server/dns.js +22 -0
- package/src/server/ipfs-client.js +232 -91
- package/src/server/object-layer.js +1 -6
- package/src/server/process.js +13 -27
- package/src/server/semantic-layer-generator-floor.js +11 -51
- package/src/server/semantic-layer-generator-resource.js +259 -0
- package/src/server/semantic-layer-generator-skin.js +41 -171
- package/src/server/semantic-layer-generator.js +122 -14
- package/src/server/shape-generator.js +108 -0
- package/src/server/start.js +17 -3
- package/src/server/valkey.js +141 -235
- 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 -68
- package/jsdoc.json +0 -68
- package/src/api/object-layer/README.md +0 -672
- package/src/client/components/core/ColorPalette.js +0 -5267
- package/src/client/components/core/JoyStick.js +0 -80
- package/src/client/components/cryptokoyn/RoutesCryptokoyn.js +0 -39
- package/src/client/components/cyberia-portal/RoutesCyberiaPortal.js +0 -62
- package/src/client/components/cyberia-portal/ServerCyberiaPortal.js +0 -136
- package/src/client/components/default/RoutesDefault.js +0 -49
- package/src/client/components/itemledger/RoutesItemledger.js +0 -40
- 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/grpc/cyberia/OFF_CHAIN_ECONOMY.md +0 -305
- package/src/grpc/cyberia/README.md +0 -326
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
# Off-Chain Economy: Fountain & Sink Architecture
|
|
2
|
+
|
|
3
|
+
**Module:** `cyberia-server/src/economy.go` · `src/api/cyberia-instance-conf`
|
|
4
|
+
|
|
5
|
+
> **Status:** Alpha (sinks disabled by default; all values reset on reconnect).
|
|
6
|
+
> **On-chain bridge:** CKY ERC-1155 token (ID 0) on Hyperledger Besu.
|
|
7
|
+
> See [WHITE-PAPER.md](WHITE-PAPER.md) §7 for the bridge protocol.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 1. Model Overview
|
|
12
|
+
|
|
13
|
+
Cyberia Online uses the **Fountain & Sink** economy — the industry standard for sustainable in-game economies, pioneered by _Ultima Online_ and refined in _EVE Online_ and _World of Warcraft_.
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
┌─────────────────────────────┐
|
|
17
|
+
│ FOUNTAINS │
|
|
18
|
+
│ (inject coins into economy) │
|
|
19
|
+
│ │
|
|
20
|
+
│ botSpawnCoins ──► Bot │
|
|
21
|
+
│ playerSpawnCoins ► Player │
|
|
22
|
+
└──────────────┬──────────────┘
|
|
23
|
+
│ new coins
|
|
24
|
+
▼
|
|
25
|
+
┌──────────────────────────────┐
|
|
26
|
+
│ CIRCULATING SUPPLY │
|
|
27
|
+
│ (player & bot wallets) │
|
|
28
|
+
└──────┬───────────────────────┘
|
|
29
|
+
│
|
|
30
|
+
┌────────────┴────────────┐
|
|
31
|
+
│ KILL TRANSFER │ zero-sum redistribution
|
|
32
|
+
│ loser → winner │
|
|
33
|
+
│ │
|
|
34
|
+
│ PvE: coinKillPercentVsBot │
|
|
35
|
+
│ PvP: coinKillPercentVsPlayer │
|
|
36
|
+
│ floor: coinKillMinAmount │
|
|
37
|
+
└────────────┬────────────┘
|
|
38
|
+
│
|
|
39
|
+
┌──────▼──────────────────────┐
|
|
40
|
+
│ SINKS │
|
|
41
|
+
│ (destroy coins — alpha=0) │
|
|
42
|
+
│ │
|
|
43
|
+
│ respawnCostPercent │
|
|
44
|
+
│ portalFee │
|
|
45
|
+
│ craftingFeePercent │
|
|
46
|
+
└─────────────────────────────┘
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Core Rules
|
|
50
|
+
|
|
51
|
+
| Rule | Description |
|
|
52
|
+
| ----------------------------- | ----------------------------------------------------------------------------------------------- |
|
|
53
|
+
| **Bots are infinite mint** | Every bot respawn resets wallet to `botSpawnCoins`. Supply bounded by player kill rate. |
|
|
54
|
+
| **Players are zero-sum** | Killing a player transfers coins but creates no new ones. PvP is redistribution only. |
|
|
55
|
+
| **Kill floor** | `coinKillMinAmount` guarantees every successful kill pays out even against a near-empty wallet. |
|
|
56
|
+
| **Sinks scale with activity** | Fees burn a fraction — more activity = more burn, preventing indefinite inflation. |
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 2. Configuration Structure
|
|
61
|
+
|
|
62
|
+
Economy parameters live in `CyberiaInstanceConf.economyRules`. A document without an `economyRules` sub-document receives canonical defaults automatically.
|
|
63
|
+
|
|
64
|
+
### 2.1 JavaScript Defaults (`cyberia-instance-conf.defaults.js`)
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
economyRules: {
|
|
68
|
+
// ── Fountains ──────────────────────────────────────────
|
|
69
|
+
botSpawnCoins: 50, // coins on bot spawn/respawn (infinite mint)
|
|
70
|
+
playerSpawnCoins: 50, // guest starting wallet (resets on reconnect)
|
|
71
|
+
|
|
72
|
+
// ── Kill Transfer ───────────────────────────────────────
|
|
73
|
+
coinKillPercentVsBot: 0.40, // 40% of bot wallet → killer on PvE kill
|
|
74
|
+
coinKillPercentVsPlayer: 0.15, // 15% of player wallet → killer on PvP kill
|
|
75
|
+
coinKillMinAmount: 10, // minimum coins per kill (hard floor)
|
|
76
|
+
|
|
77
|
+
// ── Sinks (alpha: all 0 = disabled) ────────────────────
|
|
78
|
+
respawnCostPercent: 0.0, // fraction burned on player death
|
|
79
|
+
portalFee: 0, // flat coins burned per portal use
|
|
80
|
+
craftingFeePercent: 0.0, // fraction burned per crafting action
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 2.2 Protobuf Message (`proto/cyberia.proto`)
|
|
85
|
+
|
|
86
|
+
```proto
|
|
87
|
+
message EconomyRules {
|
|
88
|
+
int32 bot_spawn_coins = 1;
|
|
89
|
+
int32 player_spawn_coins = 2;
|
|
90
|
+
double coin_kill_percent_vs_bot = 3;
|
|
91
|
+
double coin_kill_percent_vs_player = 4;
|
|
92
|
+
int32 coin_kill_min_amount = 5;
|
|
93
|
+
double respawn_cost_percent = 6;
|
|
94
|
+
int32 portal_fee = 7;
|
|
95
|
+
double crafting_fee_percent = 8;
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 2.3 Go Server (`server.go → ApplyInstanceConfig`)
|
|
100
|
+
|
|
101
|
+
```go
|
|
102
|
+
er := cfg.GetEconomyRules()
|
|
103
|
+
if er == nil { er = &pb.EconomyRules{} }
|
|
104
|
+
|
|
105
|
+
s.botSpawnCoins = int(er.GetBotSpawnCoins())
|
|
106
|
+
s.playerSpawnCoins = int(er.GetPlayerSpawnCoins())
|
|
107
|
+
s.coinKillPercentVsBot = er.GetCoinKillPercentVsBot()
|
|
108
|
+
s.coinKillPercentVsPlayer = er.GetCoinKillPercentVsPlayer()
|
|
109
|
+
s.coinKillMinAmount = int(er.GetCoinKillMinAmount())
|
|
110
|
+
s.respawnCostPercent = er.GetRespawnCostPercent()
|
|
111
|
+
s.portalFee = int(er.GetPortalFee())
|
|
112
|
+
s.craftingFeePercent = er.GetCraftingFeePercent()
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## 3. Runtime Economy API (`economy.go`)
|
|
118
|
+
|
|
119
|
+
All economy logic is encapsulated in a single file enforcing the single-source principle. Callers (`handlers.go`, `collision.go`, `skill.go`) call named methods and never manipulate coin wallets directly.
|
|
120
|
+
|
|
121
|
+
### Method Reference
|
|
122
|
+
|
|
123
|
+
| Method | Caller | Description |
|
|
124
|
+
| ------------------------------------- | ---------------------------------- | ---------------------------------------------------- |
|
|
125
|
+
| `FountainInitPlayer(player)` | `handlers.go` on WebSocket connect | Credits `playerSpawnCoins` to new player |
|
|
126
|
+
| `FountainInitBot(bot)` | `collision.go` on bot respawn | Resets bot wallet to `botSpawnCoins` (infinite mint) |
|
|
127
|
+
| `ExecuteKillTransfer(caster, victim)` | `skill.go HandleOnKillSkills` | Transfers coins based on kill scenario |
|
|
128
|
+
| `SinkRespawnCost(player)` | `collision.go handlePlayerDeath` | Burns `respawnCostPercent`% of player coins |
|
|
129
|
+
| `SinkPortalFee(player)` | Portal handler | Burns flat `portalFee` coins on portal use |
|
|
130
|
+
| `SinkCraftingFee(player, item)` | Craft handler | Burns `craftingFeePercent`% on crafting |
|
|
131
|
+
|
|
132
|
+
### Kill Transfer Logic
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
ExecuteKillTransfer(caster, victim):
|
|
136
|
+
|
|
137
|
+
if caster=Player, victim=Bot → rate = coinKillPercentVsBot (PvE farming)
|
|
138
|
+
if caster=Player, victim=Player → rate = coinKillPercentVsPlayer (PvP)
|
|
139
|
+
if caster=Bot, victim=Player → rate = coinKillPercentVsPlayer (bot kills player)
|
|
140
|
+
if caster=Bot, victim=Bot → rate = coinKillPercentVsBot (bot-on-bot)
|
|
141
|
+
|
|
142
|
+
transfer = max(floor(victim.coins × rate), coinKillMinAmount)
|
|
143
|
+
transfer = min(transfer, victim.coins) // can't take more than available
|
|
144
|
+
|
|
145
|
+
victim.coins -= transfer
|
|
146
|
+
caster.coins += transfer // bots ignore received coins
|
|
147
|
+
→ sendFCT(caster, FCTTypeCoinGain, worldX, worldY, transfer)
|
|
148
|
+
→ sendFCT(victim, FCTTypeCoinLoss, worldX, worldY, transfer)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## 4. Coin Balance Architecture
|
|
154
|
+
|
|
155
|
+
Coins use a **flat + display split** design:
|
|
156
|
+
|
|
157
|
+
| Field | Type | Role |
|
|
158
|
+
| ----------------------------- | ----------------------------------------------------- | ----------------------------------------------------------------- |
|
|
159
|
+
| `entity.Coins` | `uint32` | **Single source of truth** — O(1) read/write for all economy math |
|
|
160
|
+
| `coinItemId` ObjectLayer slot | `ObjectLayerState { Active: false, Quantity: Coins }` | **Display only** — synced by `syncCoinOL()` on every mutation |
|
|
161
|
+
|
|
162
|
+
**Why split:**
|
|
163
|
+
|
|
164
|
+
- Economy math uses `Coins` directly (O(1)); no OL iteration.
|
|
165
|
+
- Coin slot is always `Active: false` — the inventory UI automatically renders it with a lock indicator (non-activable).
|
|
166
|
+
- No risk of coin OL being activated by the `item_activation` handler.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## 5. Floating Combat Text (FCT) Wire Protocol
|
|
171
|
+
|
|
172
|
+
Economy events trigger client-side visual feedback via the binary AOI protocol.
|
|
173
|
+
|
|
174
|
+
**Coin FCT (14 bytes, fixed):**
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
MsgTypeFCT = 0x04
|
|
178
|
+
|
|
179
|
+
Offset Size Field
|
|
180
|
+
────── ──── ─────────────────────────────
|
|
181
|
+
0 u8 message type (0x04)
|
|
182
|
+
1 u8 fct_type (see table)
|
|
183
|
+
2 f32 world_x (entity position)
|
|
184
|
+
6 f32 world_y
|
|
185
|
+
10 u32 value (always positive; sign implied by type)
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**Item FCT (variable length):**
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
MsgTypeItemFCT = 0x05
|
|
192
|
+
|
|
193
|
+
Offset Size Field
|
|
194
|
+
────── ──── ─────────────────────────────
|
|
195
|
+
0 u8 message type (0x05)
|
|
196
|
+
1 u8 fct_type (FCTTypeItemGain or FCTTypeItemLoss)
|
|
197
|
+
2 f32 world_x
|
|
198
|
+
6 f32 world_y
|
|
199
|
+
10 u32 quantity
|
|
200
|
+
14 u8 itemId length
|
|
201
|
+
15 str itemId bytes
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
| `fct_type` | Constant | Color | Display |
|
|
205
|
+
| ---------- | ----------------- | ------ | -------------- |
|
|
206
|
+
| `0x00` | `FCTTypeDamage` | Red | `-N` HP lost |
|
|
207
|
+
| `0x01` | `FCTTypeRegen` | Green | `+N` HP gained |
|
|
208
|
+
| `0x02` | `FCTTypeCoinGain` | Yellow | `+N` coins |
|
|
209
|
+
| `0x03` | `FCTTypeCoinLoss` | Yellow | `-N` coins |
|
|
210
|
+
| `0x04` | `FCTTypeItemGain` | Cyan | `+N ItemID` |
|
|
211
|
+
| `0x05` | `FCTTypeItemLoss` | Purple | `-N ItemID` |
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## 6. MongoDB Document Example
|
|
216
|
+
|
|
217
|
+
```json
|
|
218
|
+
{
|
|
219
|
+
"instanceCode": "alpha-01",
|
|
220
|
+
"economyRules": {
|
|
221
|
+
"botSpawnCoins": 50,
|
|
222
|
+
"playerSpawnCoins": 50,
|
|
223
|
+
"coinKillPercentVsBot": 0.4,
|
|
224
|
+
"coinKillPercentVsPlayer": 0.15,
|
|
225
|
+
"coinKillMinAmount": 10,
|
|
226
|
+
"respawnCostPercent": 0.0,
|
|
227
|
+
"portalFee": 0,
|
|
228
|
+
"craftingFeePercent": 0.0
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## 7. gRPC Config Builder
|
|
236
|
+
|
|
237
|
+
The `toInstanceConfig()` function in `grpc-server.js` resolves `economyRules` with a two-tier fallback:
|
|
238
|
+
|
|
239
|
+
```
|
|
240
|
+
priority: gc.economyRules.field (instance document in MongoDB)
|
|
241
|
+
→ fb.economyRules.field (CYBERIA_INSTANCE_CONF_DEFAULTS — always set)
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## 8. On-Chain Bridge
|
|
247
|
+
|
|
248
|
+
The off-chain `coin` balance maps to the on-chain **CKY token (ERC-1155 Token ID 0)** on Hyperledger Besu:
|
|
249
|
+
|
|
250
|
+
```
|
|
251
|
+
Off-chain Coins (uint32)
|
|
252
|
+
↕ conversion (via cryptokoyn.net withdrawal protocol)
|
|
253
|
+
On-chain CKY (ERC-1155, Token ID 0, 18-decimal precision)
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**Bridge mechanics:**
|
|
257
|
+
|
|
258
|
+
- **Withdrawal:** Player requests conversion of off-chain coins to on-chain CKY via cryptokoyn.net.
|
|
259
|
+
- **Deposit:** Player deposits on-chain CKY to top up off-chain balance.
|
|
260
|
+
- **CKY Minting Fee:** Converting off-chain items to ERC-1155 tokens requires a CKY fee — the primary on-chain sink mechanism.
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## 9. Enabling Sinks (Alpha → Beta)
|
|
265
|
+
|
|
266
|
+
To activate economy pressure:
|
|
267
|
+
|
|
268
|
+
```javascript
|
|
269
|
+
// Update CyberiaInstanceConf in MongoDB for the target instance
|
|
270
|
+
{
|
|
271
|
+
"economyRules": {
|
|
272
|
+
"respawnCostPercent": 0.05, // 5% burned on death
|
|
273
|
+
"portalFee": 5, // 5 coins burned per portal use
|
|
274
|
+
"craftingFeePercent": 0.03 // 3% burned on each crafting action
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
The Go server picks up updated config via gRPC hot-reload (`GetFullInstance` polling at `ENGINE_GRPC_RELOAD_INTERVAL_SEC`).
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Quest System
|
|
2
|
+
|
|
3
|
+
**Module:** `src/api/cyberia-quest` · `src/api/cyberia-quest-progress`
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
The Quest System is a **chain/tree-structured progression framework** linking NPC entities, player actions, map coordinates, and item rewards. Quests are the primary mechanism for guided player progression in Cyberia Online.
|
|
10
|
+
|
|
11
|
+
Quests are defined server-side as MongoDB documents and delivered to the client through the Engine REST API. Progress is tracked per-player in `CyberiaQuestProgress` documents.
|
|
12
|
+
|
|
13
|
+
> **Implementation status — Pre-alpha:** The Quest and QuestProgress MongoDB schemas and Engine REST API (`src/api/cyberia-quest`, `src/api/cyberia-quest-progress`) are defined and seeded. Go server integration (quest tracking, objective evaluation, reward delivery via FCT) is planned for the **Alpha milestone**. For pre-alpha, quest progress is ephemeral: it lives in the client session only and resets on page reload.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Data Model
|
|
18
|
+
|
|
19
|
+
### CyberiaQuest Schema
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
CyberiaQuest {
|
|
23
|
+
code: String // stable slug, e.g. "fallback-intro-quest"
|
|
24
|
+
title: String
|
|
25
|
+
description: String
|
|
26
|
+
|
|
27
|
+
// Spatial origin — the NPC/entity cell that grants this quest
|
|
28
|
+
sourceMapCode: String
|
|
29
|
+
sourceCellX: Number
|
|
30
|
+
sourceCellY: Number
|
|
31
|
+
|
|
32
|
+
// Chain / tree unlock structure
|
|
33
|
+
prerequisiteCodes: [String] // AND logic — all must be completed to unlock
|
|
34
|
+
unlocksQuestCodes: [String] // quests activated on completion (chain or tree)
|
|
35
|
+
|
|
36
|
+
// Ordered linear step sequence
|
|
37
|
+
steps: [{
|
|
38
|
+
id: String
|
|
39
|
+
description: String
|
|
40
|
+
objectives: [{
|
|
41
|
+
type: String // 'collect' | 'talk' | 'kill'
|
|
42
|
+
itemId: String // semantic target (see Objective Types below)
|
|
43
|
+
quantity: Number // default: 1
|
|
44
|
+
}]
|
|
45
|
+
}]
|
|
46
|
+
|
|
47
|
+
// Rewards granted on quest completion
|
|
48
|
+
rewards: [{
|
|
49
|
+
itemId: String
|
|
50
|
+
quantity: Number
|
|
51
|
+
}]
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### CyberiaQuestProgress Schema
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
CyberiaQuestProgress {
|
|
59
|
+
playerId: String // Go server player UUID
|
|
60
|
+
questCode: String // references CyberiaQuest.code
|
|
61
|
+
status: String // 'active' | 'completed'
|
|
62
|
+
|
|
63
|
+
stepProgress: [{
|
|
64
|
+
stepId: String
|
|
65
|
+
objectiveProgress: [{
|
|
66
|
+
current: Number // current count toward objective
|
|
67
|
+
required: Number // denormalized from quest definition
|
|
68
|
+
}]
|
|
69
|
+
}]
|
|
70
|
+
|
|
71
|
+
startedAt: Date
|
|
72
|
+
completedAt: Date | null
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Completeness is always computed, never stored.** A step is complete when all `objectiveProgress[i].current >= objectiveProgress[i].required`. The active step is always the first step where not all objectives are done.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Objective Types
|
|
81
|
+
|
|
82
|
+
| `type` | `itemId` semantics | Completion trigger |
|
|
83
|
+
| --------- | -------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
|
|
84
|
+
| `collect` | ObjectLayer item ID that must appear in the player's inventory | Player inventory contains `>= quantity` of `itemId` |
|
|
85
|
+
| `talk` | `CyberiaAction.provideItemId` of the NPC to interact with | Player triggers a talk action where `provideItemId === itemId` and all `questDialogueCodes` viewed |
|
|
86
|
+
| `kill` | Skin item ID of the target entity (e.g. `"wason"`) | Player kills an entity whose active skin matches `itemId` |
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Quest Graph (Chain and Tree)
|
|
91
|
+
|
|
92
|
+
Quests form a **directed acyclic graph** via `prerequisiteCodes` → `unlocksQuestCodes`:
|
|
93
|
+
|
|
94
|
+
```mermaid
|
|
95
|
+
graph LR
|
|
96
|
+
A["intro-quest\n(no prerequisites)"]
|
|
97
|
+
B["village-quest\n(requires: intro-quest)"]
|
|
98
|
+
C["forest-quest\n(requires: intro-quest)"]
|
|
99
|
+
D["final-quest\n(requires: village-quest AND forest-quest)"]
|
|
100
|
+
|
|
101
|
+
A -->|unlocksQuestCodes| B
|
|
102
|
+
A -->|unlocksQuestCodes| C
|
|
103
|
+
B -->|unlocksQuestCodes| D
|
|
104
|
+
C -->|unlocksQuestCodes| D
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**AND logic on prerequisites:** A quest only becomes available when **all** listed `prerequisiteCodes` are completed.
|
|
108
|
+
|
|
109
|
+
**Tree branching:** A quest can list multiple `unlocksQuestCodes`, enabling parallel quest branches that reconverge later.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Quest Lifecycle
|
|
114
|
+
|
|
115
|
+
```mermaid
|
|
116
|
+
sequenceDiagram
|
|
117
|
+
participant P as Player
|
|
118
|
+
participant G as Go Server
|
|
119
|
+
participant E as Engine (Node.js)
|
|
120
|
+
participant DB as MongoDB
|
|
121
|
+
|
|
122
|
+
P->>G: Tap NPC with grantQuestCode
|
|
123
|
+
G->>E: POST /api/cyberia-quest-progress (grant quest)
|
|
124
|
+
E->>DB: Create CyberiaQuestProgress { status: 'active' }
|
|
125
|
+
E-->>G: Progress document
|
|
126
|
+
|
|
127
|
+
loop For each game event (kill / collect / talk)
|
|
128
|
+
G->>E: PATCH /api/cyberia-quest-progress (increment objective)
|
|
129
|
+
E->>DB: objectiveProgress[i].current++
|
|
130
|
+
E-->>G: Updated progress
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
Note over G,E: All steps complete
|
|
134
|
+
G->>E: PATCH status → 'completed'
|
|
135
|
+
E->>DB: completedAt = now
|
|
136
|
+
G->>E: GET unlocksQuestCodes → activate successor quests
|
|
137
|
+
E->>DB: Create CyberiaQuestProgress for each unlocked quest
|
|
138
|
+
G-->>P: Deliver reward items (inventory grant + FCT ItemGain events)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Spatial Binding
|
|
144
|
+
|
|
145
|
+
Each `CyberiaQuest` can declare `sourceMapCode + sourceCellX + sourceCellY`, linking it to the map entity at that cell. This binding is used during instance initialization:
|
|
146
|
+
|
|
147
|
+
- `instance_loader.go` reads `CyberiaEntity.initCellX/initCellY` and correlates with quest `sourceCellX/sourceCellY` to assign quest-granting behaviors to the correct NPC entity at world construction time.
|
|
148
|
+
- The `ObjectLayerEngineModal` (Engine UI) allows editors to assign quest codes to entity cells visually.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Reward Delivery
|
|
153
|
+
|
|
154
|
+
On quest completion, the Engine grants each `rewards[].{itemId, quantity}` to the player's inventory:
|
|
155
|
+
|
|
156
|
+
- Off-chain items are added to the player's `ObjectLayers` array in the Go server.
|
|
157
|
+
- If the item has an on-chain ERC-1155 token, the server relayer calls `mint(playerAddress, tokenId, quantity)` on the `ObjectLayerToken` contract.
|
|
158
|
+
- FCT `ItemGain` events (`MsgTypeItemFCT`, `FCTTypeItemGain`) are broadcast to the client for visual feedback.
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Step Progression Rules
|
|
163
|
+
|
|
164
|
+
1. Steps are always processed in **declared order** — step N cannot advance until step N-1 is complete.
|
|
165
|
+
2. Within a step, all objectives must be satisfied (any order).
|
|
166
|
+
3. Quests do not fail — they remain `active` until completed or explicitly abandoned.
|
|
167
|
+
4. The `required` count is **denormalized** from the quest definition into each `objectiveProgress` record at quest grant time, enabling O(1) progress checks without re-fetching the quest definition.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Indexes
|
|
172
|
+
|
|
173
|
+
```javascript
|
|
174
|
+
// CyberiaQuest
|
|
175
|
+
{ code: 1 } // unique
|
|
176
|
+
{ sourceMapCode: 1, sourceCellX: 1, sourceCellY: 1 }
|
|
177
|
+
|
|
178
|
+
// CyberiaQuestProgress
|
|
179
|
+
{ playerId: 1, questCode: 1 } // unique
|
|
180
|
+
{ playerId: 1, status: 1 }
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Example Quest Document
|
|
186
|
+
|
|
187
|
+
```json
|
|
188
|
+
{
|
|
189
|
+
"code": "wason-intro",
|
|
190
|
+
"title": "Meet Wason",
|
|
191
|
+
"description": "Find the village elder to begin your journey.",
|
|
192
|
+
"sourceMapCode": "cyberia-village",
|
|
193
|
+
"sourceCellX": 12,
|
|
194
|
+
"sourceCellY": 8,
|
|
195
|
+
"prerequisiteCodes": [],
|
|
196
|
+
"unlocksQuestCodes": ["wason-collection"],
|
|
197
|
+
"steps": [
|
|
198
|
+
{
|
|
199
|
+
"id": "step-talk",
|
|
200
|
+
"description": "Speak with Wason.",
|
|
201
|
+
"objectives": [{ "type": "talk", "itemId": "wason", "quantity": 1 }]
|
|
202
|
+
}
|
|
203
|
+
],
|
|
204
|
+
"rewards": [{ "itemId": "health-potion", "quantity": 2 }]
|
|
205
|
+
}
|
|
206
|
+
```
|