cyberia 3.1.3 → 3.2.5
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 +13 -8
- package/CHANGELOG.md +433 -1
- package/CLI-HELP.md +57 -7
- package/Dockerfile +4 -2
- package/README.md +347 -22
- package/bin/build.js +5 -2
- package/bin/cyberia.js +1789 -112
- package/bin/deploy.js +177 -124
- package/bin/file.js +3 -0
- package/bin/index.js +1789 -112
- package/conf.js +64 -8
- package/deployment.yaml +92 -20
- package/hardhat/hardhat.config.js +13 -13
- package/hardhat/ignition/modules/ObjectLayerToken.js +1 -1
- package/hardhat/package-lock.json +2554 -5859
- package/hardhat/package.json +13 -22
- 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/jsdoc.dd-cyberia.json +64 -55
- package/jsdoc.json +64 -55
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +5 -4
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +5 -4
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +92 -20
- package/manifests/deployment/dd-cyberia-development/proxy.yaml +54 -18
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +88 -74
- package/manifests/deployment/dd-test-development/proxy.yaml +13 -4
- package/manifests/deployment/playwright/deployment.yaml +1 -1
- package/nodemon.json +1 -1
- package/package.json +22 -16
- package/proxy.yaml +54 -18
- package/scripts/rhel-grpc-setup.sh +56 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +44 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +16 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +5 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +80 -7
- 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 +368 -0
- package/src/api/cyberia-instance/cyberia-instance.controller.js +92 -0
- package/src/api/cyberia-instance/cyberia-instance.model.js +84 -0
- package/src/api/cyberia-instance/cyberia-instance.router.js +63 -0
- package/src/api/cyberia-instance/cyberia-instance.service.js +191 -0
- package/src/api/cyberia-instance/cyberia-portal-connector.js +486 -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 +413 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +228 -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 +42 -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/file/file.ref.json +18 -0
- package/src/api/ipfs/ipfs.controller.js +4 -25
- package/src/api/ipfs/ipfs.model.js +43 -34
- package/src/api/ipfs/ipfs.router.js +8 -13
- package/src/api/ipfs/ipfs.service.js +54 -102
- package/src/api/object-layer/README.md +347 -22
- package/src/api/object-layer/object-layer.router.js +30 -0
- package/src/api/object-layer/object-layer.service.js +114 -31
- package/src/api/user/user.service.js +8 -7
- package/src/cli/cluster.js +7 -7
- package/src/cli/db.js +710 -827
- package/src/cli/deploy.js +151 -93
- package/src/cli/env.js +29 -0
- package/src/cli/fs.js +5 -2
- package/src/cli/index.js +48 -2
- package/src/cli/kubectl.js +211 -0
- package/src/cli/release.js +284 -0
- package/src/cli/repository.js +438 -75
- package/src/cli/run.js +195 -35
- package/src/cli/secrets.js +73 -0
- package/src/cli/test.js +3 -3
- package/src/client/Cryptokoyn.index.js +3 -4
- package/src/client/CyberiaPortal.index.js +3 -4
- package/src/client/Default.index.js +3 -4
- package/src/client/Itemledger.index.js +3 -4
- package/src/client/Underpost.index.js +3 -4
- package/src/client/components/core/AppStore.js +69 -0
- package/src/client/components/core/CalendarCore.js +2 -2
- package/src/client/components/core/DropDown.js +137 -17
- package/src/client/components/core/Keyboard.js +2 -2
- package/src/client/components/core/LogIn.js +2 -2
- package/src/client/components/core/LogOut.js +2 -2
- package/src/client/components/core/Modal.js +0 -1
- package/src/client/components/core/Panel.js +0 -1
- package/src/client/components/core/PanelForm.js +19 -19
- package/src/client/components/core/SocketIo.js +82 -29
- package/src/client/components/core/SocketIoHandler.js +75 -0
- package/src/client/components/core/Stream.js +143 -95
- package/src/client/components/core/Webhook.js +40 -7
- package/src/client/components/cryptokoyn/AppStoreCryptokoyn.js +5 -0
- package/src/client/components/cryptokoyn/LogInCryptokoyn.js +3 -3
- package/src/client/components/cryptokoyn/LogOutCryptokoyn.js +2 -2
- package/src/client/components/cryptokoyn/MenuCryptokoyn.js +3 -3
- package/src/client/components/cryptokoyn/SocketIoCryptokoyn.js +3 -51
- package/src/client/components/cyberia/InstanceEngineCyberia.js +700 -0
- package/src/client/components/cyberia/MapEngineCyberia.js +1359 -2
- package/src/client/components/cyberia/ObjectLayerEngineModal.js +17 -6
- package/src/client/components/cyberia/ObjectLayerEngineViewer.js +92 -54
- package/src/client/components/cyberia-portal/AppStoreCyberiaPortal.js +5 -0
- package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +216 -30
- package/src/client/components/cyberia-portal/LogInCyberiaPortal.js +3 -3
- package/src/client/components/cyberia-portal/LogOutCyberiaPortal.js +2 -2
- package/src/client/components/cyberia-portal/MenuCyberiaPortal.js +40 -7
- package/src/client/components/cyberia-portal/RoutesCyberiaPortal.js +4 -0
- package/src/client/components/cyberia-portal/SocketIoCyberiaPortal.js +3 -49
- package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +4 -0
- package/src/client/components/default/AppStoreDefault.js +5 -0
- package/src/client/components/default/LogInDefault.js +3 -3
- package/src/client/components/default/LogOutDefault.js +2 -2
- package/src/client/components/default/MenuDefault.js +5 -5
- package/src/client/components/default/SocketIoDefault.js +3 -51
- package/src/client/components/itemledger/AppStoreItemledger.js +5 -0
- package/src/client/components/itemledger/LogInItemledger.js +3 -3
- package/src/client/components/itemledger/LogOutItemledger.js +2 -2
- package/src/client/components/itemledger/MenuItemledger.js +3 -3
- package/src/client/components/itemledger/SocketIoItemledger.js +3 -51
- package/src/client/components/underpost/AppStoreUnderpost.js +5 -0
- package/src/client/components/underpost/LogInUnderpost.js +3 -3
- package/src/client/components/underpost/LogOutUnderpost.js +2 -2
- package/src/client/components/underpost/MenuUnderpost.js +5 -5
- package/src/client/components/underpost/SocketIoUnderpost.js +3 -51
- package/src/client/services/core/core.service.js +20 -8
- package/src/client/services/cyberia-dialogue/cyberia-dialogue.service.js +105 -0
- package/src/client/services/cyberia-entity/cyberia-entity.management.js +57 -0
- package/src/client/services/cyberia-entity/cyberia-entity.service.js +105 -0
- package/src/client/services/cyberia-instance/cyberia-instance.management.js +194 -0
- package/src/client/services/cyberia-instance/cyberia-instance.service.js +122 -0
- package/src/client/services/cyberia-instance-conf/cyberia-instance-conf.service.js +105 -0
- package/src/client/services/cyberia-map/cyberia-map.management.js +193 -0
- package/src/client/services/cyberia-map/cyberia-map.service.js +126 -0
- package/src/client/services/instance/instance.management.js +2 -2
- package/src/client/services/ipfs/ipfs.service.js +3 -23
- package/src/client/services/object-layer/object-layer.management.js +3 -3
- package/src/client/services/object-layer/object-layer.service.js +21 -0
- package/src/client/services/user/user.management.js +2 -2
- package/src/client/ssr/pages/CyberiaServerMetrics.js +1 -1
- package/src/grpc/cyberia/OFF_CHAIN_ECONOMY.md +305 -0
- package/src/grpc/cyberia/README.md +326 -0
- package/src/grpc/cyberia/grpc-server.js +530 -0
- package/src/index.js +24 -1
- package/src/runtime/express/Dockerfile +4 -0
- package/src/runtime/express/Express.js +18 -1
- package/src/runtime/lampp/Dockerfile +13 -2
- package/src/runtime/lampp/Lampp.js +27 -4
- package/src/runtime/wp/Dockerfile +68 -0
- package/src/runtime/wp/Wp.js +639 -0
- package/src/server/auth.js +24 -1
- package/src/server/backup.js +37 -9
- package/src/server/client-build-docs.js +9 -2
- package/src/server/client-build.js +31 -31
- package/src/server/client-formatted.js +109 -57
- package/src/server/conf.js +24 -9
- package/src/server/cron.js +25 -23
- package/src/server/dns.js +2 -1
- package/src/server/ipfs-client.js +24 -1
- package/src/server/object-layer.js +149 -108
- package/src/server/peer.js +8 -0
- package/src/server/runtime.js +25 -1
- package/src/server/semantic-layer-generator-floor.js +359 -0
- package/src/server/semantic-layer-generator-skin.js +1294 -0
- package/src/server/semantic-layer-generator.js +116 -555
- package/src/server/start.js +2 -2
- 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/src/client/components/cryptokoyn/CommonCryptokoyn.js +0 -29
- package/src/client/components/cryptokoyn/ElementsCryptokoyn.js +0 -38
- package/src/client/components/cyberia-portal/ElementsCyberiaPortal.js +0 -38
- package/src/client/components/default/ElementsDefault.js +0 -38
- package/src/client/components/itemledger/CommonItemledger.js +0 -29
- package/src/client/components/itemledger/ElementsItemledger.js +0 -38
- package/src/client/components/underpost/CommonUnderpost.js +0 -29
- package/src/client/components/underpost/ElementsUnderpost.js +0 -38
- 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
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical default values and type definitions for a CyberiaInstanceConf document.
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth used by:
|
|
5
|
+
* - cyberia-instance-conf.model.js — Mongoose schema `default:` declarations
|
|
6
|
+
* - grpc-server.js — FALLBACK_CONFIG_DEFAULTS for missing instances
|
|
7
|
+
* - bin/cyberia.js — imports ITEM_TYPES for asset type enumeration
|
|
8
|
+
*
|
|
9
|
+
* @module src/api/cyberia-instance-conf/cyberia-instance-conf.defaults.js
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// ── Item type registry ───────────────────────────────────────────────────────
|
|
13
|
+
/**
|
|
14
|
+
* Canonical set of ObjectLayer item type names, used as asset directory names
|
|
15
|
+
* and as the `data.item.type` discriminator on ObjectLayer documents.
|
|
16
|
+
*
|
|
17
|
+
* Values intentionally equal their keys — the object is an enum of valid
|
|
18
|
+
* strings, NOT an integer→z-index map. Render layer ordering (z-order) is
|
|
19
|
+
* determined separately by `get_priority_for_type()` in entity_render.c.
|
|
20
|
+
*
|
|
21
|
+
* @constant
|
|
22
|
+
* @type {Readonly<{floor:string, skin:string, breastplate:string, weapon:string, skill:string, coin:string}>}
|
|
23
|
+
*/
|
|
24
|
+
export const ITEM_TYPES = Object.freeze({
|
|
25
|
+
floor: 'floor',
|
|
26
|
+
skin: 'skin',
|
|
27
|
+
breastplate: 'breastplate',
|
|
28
|
+
weapon: 'weapon',
|
|
29
|
+
skill: 'skill',
|
|
30
|
+
coin: 'coin',
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// ── Entity Status Indicator (ESI) registry ───────────────────────────────────
|
|
34
|
+
/**
|
|
35
|
+
* Canonical mapping of server-computed entity status icon IDs to the ui-icon
|
|
36
|
+
* filename stem served from /assets/ui-icons/{iconId}.png.
|
|
37
|
+
*
|
|
38
|
+
* The Go server assigns a status u8 per entity each AOI tick. The C client
|
|
39
|
+
* receives this mapping dynamically via init_data.statusIcons and uses it to
|
|
40
|
+
* resolve the u8 to an icon filename at runtime. This JS-side copy is the
|
|
41
|
+
* configuration source of truth; it supports instance-specific icon overrides.
|
|
42
|
+
*
|
|
43
|
+
* Industry standard name: "Overhead Status Indicator" (OSI).
|
|
44
|
+
* WoW: nameplate colour + debuff icons
|
|
45
|
+
* FFXIV: enmity/claim icons (red ◆, yellow ●)
|
|
46
|
+
* UO: skull for murderers, shield for invulnerables
|
|
47
|
+
*
|
|
48
|
+
* IMPORTANT: The numeric IDs MUST stay in sync with:
|
|
49
|
+
* - Go: cyberia-server/src/entity_status.go (StatusNone … StatusDead)
|
|
50
|
+
*
|
|
51
|
+
* @constant
|
|
52
|
+
*/
|
|
53
|
+
export const STATUS_ICONS = Object.freeze([
|
|
54
|
+
{
|
|
55
|
+
id: 0,
|
|
56
|
+
name: 'none',
|
|
57
|
+
iconId: null,
|
|
58
|
+
bounce: false,
|
|
59
|
+
borderColor: { r: 70, g: 70, b: 120, a: 200 },
|
|
60
|
+
description: 'No icon (skill/coin bots, world objects)',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
id: 1,
|
|
64
|
+
name: 'passive',
|
|
65
|
+
iconId: 'arrow-down-gray',
|
|
66
|
+
bounce: false,
|
|
67
|
+
borderColor: { r: 130, g: 140, b: 160, a: 200 },
|
|
68
|
+
description: 'Passive bot — no weapon, non-aggressive',
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: 2,
|
|
72
|
+
name: 'hostile',
|
|
73
|
+
iconId: 'arrow-down-red',
|
|
74
|
+
bounce: true,
|
|
75
|
+
borderColor: { r: 210, g: 50, b: 50, a: 240 },
|
|
76
|
+
description: 'Hostile bot — has weapon, will aggro',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
id: 3,
|
|
80
|
+
name: 'frozen',
|
|
81
|
+
iconId: 'chat',
|
|
82
|
+
bounce: true,
|
|
83
|
+
borderColor: { r: 80, g: 160, b: 220, a: 240 },
|
|
84
|
+
description: 'Player in FrozenInteractionState (modal open)',
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
id: 4,
|
|
88
|
+
name: 'player',
|
|
89
|
+
iconId: 'arrow-down',
|
|
90
|
+
bounce: false,
|
|
91
|
+
borderColor: { r: 60, g: 190, b: 90, a: 240 },
|
|
92
|
+
description: 'Normal player — alive, not frozen',
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: 5,
|
|
96
|
+
name: 'dead',
|
|
97
|
+
iconId: 'skull',
|
|
98
|
+
bounce: false,
|
|
99
|
+
borderColor: { r: 160, g: 130, b: 200, a: 200 },
|
|
100
|
+
description: 'Entity is dead / respawning',
|
|
101
|
+
},
|
|
102
|
+
]);
|
|
103
|
+
|
|
104
|
+
// ── Equipment rules ──────────────────────────────────────────────────────────
|
|
105
|
+
/**
|
|
106
|
+
* Equipment rules govern which ObjectLayer item types can be simultaneously
|
|
107
|
+
* active on a character entity and enforce the one-active-per-type constraint.
|
|
108
|
+
*
|
|
109
|
+
* The server validates every item_activation request against these rules:
|
|
110
|
+
* 1. Only item types listed in `activeItemTypes` may be activated.
|
|
111
|
+
* 2. When `onePerType` is true (default), activating an item of a given type
|
|
112
|
+
* automatically deactivates any other active item of the same type.
|
|
113
|
+
* 3. When `requireSkin` is true, the player must always have at least one
|
|
114
|
+
* active skin if they own any skin-type items.
|
|
115
|
+
*
|
|
116
|
+
* Item types NOT listed in `activeItemTypes` (e.g. 'coin', 'floor') are
|
|
117
|
+
* considered non-activable and their activation requests are rejected.
|
|
118
|
+
*
|
|
119
|
+
* @constant
|
|
120
|
+
* @type {Readonly<{activeItemTypes:string[], onePerType:boolean, requireSkin:boolean}>}
|
|
121
|
+
*/
|
|
122
|
+
export const EQUIPMENT_RULES_DEFAULTS = Object.freeze({
|
|
123
|
+
// Item types that players are allowed to activate (equip).
|
|
124
|
+
// Types not in this list are non-activable (coins, floors, etc.).
|
|
125
|
+
activeItemTypes: ['skin', 'breastplate', 'weapon'],
|
|
126
|
+
// Enforce at most one active item per item type.
|
|
127
|
+
onePerType: true,
|
|
128
|
+
// Require at least one active skin when the player owns any skin.
|
|
129
|
+
requireSkin: true,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// ── Entity type defaults ─────────────────────────────────────────────────────
|
|
133
|
+
/**
|
|
134
|
+
* Per-entity-type rendering defaults.
|
|
135
|
+
*
|
|
136
|
+
* Each entry defines the canonical visual configuration for ONE entity type:
|
|
137
|
+
*
|
|
138
|
+
* entityType — string used by the Go server and C client to identify the
|
|
139
|
+
* entity category (matches entity_type_str in game_render.c
|
|
140
|
+
* and Behavior for bot sub-types).
|
|
141
|
+
* liveItemIds — Array of ObjectLayer item IDs applied when the entity is
|
|
142
|
+
* alive/active and no explicit items are assigned. Empty array =
|
|
143
|
+
* no OL fallback, rely on colorKey solid fill.
|
|
144
|
+
* deadItemIds — Array of ObjectLayer item IDs for the dead / ghost / respawning
|
|
145
|
+
* state. Empty array = no dead-state OL; same solid fill as live.
|
|
146
|
+
* Replaces the old flat ghostItemId field for players.
|
|
147
|
+
* colorKey — Named palette colour key (see colors in CYBERIA_INSTANCE_CONF_DEFAULTS).
|
|
148
|
+
* Used as solid-colour fallback when the entity carries NO active
|
|
149
|
+
* ObjectLayer items, or while atlas textures are still loading.
|
|
150
|
+
* The Go server stamps this colour on every newly spawned entity
|
|
151
|
+
* so the binary AOI stream always carries the correct RGBA.
|
|
152
|
+
*
|
|
153
|
+
* Character entity types:
|
|
154
|
+
* player — the local (self) player
|
|
155
|
+
* other_player — remote players in the AOI
|
|
156
|
+
* bot — AI-controlled entities (behavior: hostile / passive)
|
|
157
|
+
* skill — skill-spawned projectile bot (behavior = "skill");
|
|
158
|
+
* NOT placed in maps — created at runtime by skill_projectile.go
|
|
159
|
+
* when a player/bot triggers a projectile skill.
|
|
160
|
+
* liveItemIds carries the skill-type OL (the projectile sprite).
|
|
161
|
+
* coin — skill-spawned collectible bot (behavior = "coin");
|
|
162
|
+
* NOT placed in maps — dropped at runtime on entity death.
|
|
163
|
+
*
|
|
164
|
+
* World object entity types:
|
|
165
|
+
* floor / obstacle / portal / foreground
|
|
166
|
+
*
|
|
167
|
+
* @constant
|
|
168
|
+
* @type {ReadonlyArray<{entityType:string, liveItemIds:string[], deadItemIds:string[], colorKey:string}>}
|
|
169
|
+
*/
|
|
170
|
+
export const ENTITY_TYPE_DEFAULTS = Object.freeze([
|
|
171
|
+
// ── Characters ─────────────────────────────────────────────────────────
|
|
172
|
+
{
|
|
173
|
+
entityType: 'player',
|
|
174
|
+
liveItemIds: ['anon', 'atlas_pistol_mk2'],
|
|
175
|
+
deadItemIds: ['ghost'],
|
|
176
|
+
colorKey: 'PLAYER',
|
|
177
|
+
// Full default ObjectLayer inventory for newly spawned players.
|
|
178
|
+
// active:false items appear in the inventory bar but are not worn.
|
|
179
|
+
// The coin slot is always active:false — coins are non-activable.
|
|
180
|
+
defaultObjectLayers: [
|
|
181
|
+
{ itemId: 'anon', active: true, quantity: 1 },
|
|
182
|
+
{ itemId: 'atlas_pistol_mk2', active: true, quantity: 1 },
|
|
183
|
+
{ itemId: 'purple', active: false, quantity: 1 },
|
|
184
|
+
{ itemId: 'ghost', active: false, quantity: 1 },
|
|
185
|
+
{ itemId: 'atlas_pistol_mk2_bullet', active: false, quantity: 5 },
|
|
186
|
+
{ itemId: 'lain', active: false, quantity: 1 },
|
|
187
|
+
{ itemId: 'hatchet', active: false, quantity: 1 },
|
|
188
|
+
{ itemId: 'wason', active: false, quantity: 1 },
|
|
189
|
+
{ itemId: 'scp-2040', active: false, quantity: 1 },
|
|
190
|
+
{ itemId: 'punk', active: false, quantity: 1 },
|
|
191
|
+
{ itemId: 'kaneki', active: false, quantity: 1 },
|
|
192
|
+
{ itemId: 'junko', active: false, quantity: 1 },
|
|
193
|
+
{ itemId: 'eiri', active: false, quantity: 1 },
|
|
194
|
+
{ itemId: 'alex', active: false, quantity: 1 },
|
|
195
|
+
{ itemId: 'agent', active: false, quantity: 1 },
|
|
196
|
+
{ itemId: 'coin', active: false, quantity: 0 },
|
|
197
|
+
],
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
entityType: 'other_player',
|
|
201
|
+
liveItemIds: ['anon', 'atlas_pistol_mk2'],
|
|
202
|
+
deadItemIds: ['ghost'],
|
|
203
|
+
colorKey: 'OTHER_PLAYER',
|
|
204
|
+
defaultObjectLayers: [
|
|
205
|
+
{ itemId: 'anon', active: true, quantity: 1 },
|
|
206
|
+
{ itemId: 'atlas_pistol_mk2', active: true, quantity: 1 },
|
|
207
|
+
{ itemId: 'purple', active: false, quantity: 1 },
|
|
208
|
+
{ itemId: 'ghost', active: false, quantity: 1 },
|
|
209
|
+
{ itemId: 'atlas_pistol_mk2_bullet', active: false, quantity: 5 },
|
|
210
|
+
{ itemId: 'lain', active: false, quantity: 1 },
|
|
211
|
+
{ itemId: 'hatchet', active: false, quantity: 1 },
|
|
212
|
+
{ itemId: 'wason', active: false, quantity: 1 },
|
|
213
|
+
{ itemId: 'scp-2040', active: false, quantity: 1 },
|
|
214
|
+
{ itemId: 'punk', active: false, quantity: 1 },
|
|
215
|
+
{ itemId: 'kaneki', active: false, quantity: 1 },
|
|
216
|
+
{ itemId: 'junko', active: false, quantity: 1 },
|
|
217
|
+
{ itemId: 'eiri', active: false, quantity: 1 },
|
|
218
|
+
{ itemId: 'alex', active: false, quantity: 1 },
|
|
219
|
+
{ itemId: 'agent', active: false, quantity: 1 },
|
|
220
|
+
{ itemId: 'coin', active: false, quantity: 0 },
|
|
221
|
+
],
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
entityType: 'bot',
|
|
225
|
+
liveItemIds: ['purple'],
|
|
226
|
+
deadItemIds: ['ghost'],
|
|
227
|
+
colorKey: 'BOT',
|
|
228
|
+
defaultObjectLayers: [
|
|
229
|
+
{ itemId: 'purple', active: true, quantity: 1 },
|
|
230
|
+
{ itemId: 'coin', active: false, quantity: 0 },
|
|
231
|
+
],
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
entityType: 'skill',
|
|
235
|
+
liveItemIds: ['atlas_pistol_mk2_bullet'],
|
|
236
|
+
deadItemIds: [],
|
|
237
|
+
colorKey: 'SKILL',
|
|
238
|
+
defaultObjectLayers: [{ itemId: 'atlas_pistol_mk2_bullet', active: true, quantity: 1 }],
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
entityType: 'coin',
|
|
242
|
+
liveItemIds: ['coin'],
|
|
243
|
+
deadItemIds: [],
|
|
244
|
+
colorKey: 'COIN',
|
|
245
|
+
defaultObjectLayers: [{ itemId: 'coin', active: true, quantity: 1 }],
|
|
246
|
+
},
|
|
247
|
+
// ── World objects ───────────────────────────────────────────────────────
|
|
248
|
+
{ entityType: 'floor', liveItemIds: ['grass'], deadItemIds: [], colorKey: 'FLOOR', defaultObjectLayers: [] },
|
|
249
|
+
{ entityType: 'obstacle', liveItemIds: [], deadItemIds: [], colorKey: 'OBSTACLE', defaultObjectLayers: [] },
|
|
250
|
+
{ entityType: 'portal', liveItemIds: [], deadItemIds: [], colorKey: 'PORTAL', defaultObjectLayers: [] },
|
|
251
|
+
{ entityType: 'portal', liveItemIds: [], deadItemIds: [], colorKey: 'PORTAL_INTER_PORTAL', defaultObjectLayers: [] },
|
|
252
|
+
{ entityType: 'portal', liveItemIds: [], deadItemIds: [], colorKey: 'PORTAL_INTER_RANDOM', defaultObjectLayers: [] },
|
|
253
|
+
{ entityType: 'portal', liveItemIds: [], deadItemIds: [], colorKey: 'PORTAL_INTRA_RANDOM', defaultObjectLayers: [] },
|
|
254
|
+
{ entityType: 'portal', liveItemIds: [], deadItemIds: [], colorKey: 'PORTAL_INTRA_PORTAL', defaultObjectLayers: [] },
|
|
255
|
+
{ entityType: 'foreground', liveItemIds: [], deadItemIds: [], colorKey: 'FOREGROUND', defaultObjectLayers: [] },
|
|
256
|
+
]);
|
|
257
|
+
|
|
258
|
+
// ── Instance configuration defaults ─────────────────────────────────────────
|
|
259
|
+
export const CYBERIA_INSTANCE_CONF_DEFAULTS = {
|
|
260
|
+
// ── Rendering / camera ─────────────────────────────────────────────
|
|
261
|
+
cellSize: 45,
|
|
262
|
+
fps: 60,
|
|
263
|
+
interpolationMs: 100,
|
|
264
|
+
defaultObjWidth: 1,
|
|
265
|
+
defaultObjHeight: 1,
|
|
266
|
+
cameraSmoothing: 0.1,
|
|
267
|
+
cameraZoom: 1.0,
|
|
268
|
+
defaultWidthScreenFactor: 1,
|
|
269
|
+
defaultHeightScreenFactor: 1,
|
|
270
|
+
devUi: false,
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Named colour palette forwarded to Go server and C client via the WebSocket
|
|
274
|
+
* init payload. Entity colour keys (PLAYER, BOT, SKILL, …) are consumed via
|
|
275
|
+
* entityDefaults[n].colorKey as the solid fallback for that entity type when
|
|
276
|
+
* no ObjectLayer items are assigned.
|
|
277
|
+
* The WEAPON key is kept for UI use (weapon-stat highlights) only.
|
|
278
|
+
*/
|
|
279
|
+
colors: [
|
|
280
|
+
// ── World ─────────────────────────────────────────────────────
|
|
281
|
+
{ key: 'BACKGROUND', r: 30, g: 30, b: 30, a: 255 }, // rgba(30, 30, 30, 1)
|
|
282
|
+
{ key: 'FLOOR_BACKGROUND', r: 45, g: 45, b: 45, a: 255 }, // rgba(45, 45, 45, 1)
|
|
283
|
+
{ key: 'FLOOR', r: 60, g: 60, b: 60, a: 255 }, // rgba(60, 60, 60, 1)
|
|
284
|
+
{ key: 'OBSTACLE', r: 80, g: 80, b: 80, a: 255 }, // rgba(80, 80, 80, 1)
|
|
285
|
+
{ key: 'PORTAL', r: 0, g: 200, b: 200, a: 255 }, // rgba(0, 200, 200, 1) — generic fallback
|
|
286
|
+
{ key: 'PORTAL_INTER_PORTAL', r: 0, g: 200, b: 200, a: 255 }, // cyan — to portal on another map
|
|
287
|
+
{ key: 'PORTAL_INTER_RANDOM', r: 80, g: 130, b: 255, a: 255 }, // blue — to random pos on another map
|
|
288
|
+
{ key: 'PORTAL_INTRA_RANDOM', r: 220, g: 200, b: 50, a: 255 }, // yellow — to random pos on same map
|
|
289
|
+
{ key: 'PORTAL_INTRA_PORTAL', r: 200, g: 80, b: 200, a: 255 }, // magenta — to portal on same map
|
|
290
|
+
{ key: 'FOREGROUND', r: 255, g: 255, b: 255, a: 189 }, // rgba(255, 255, 255, 0.73)
|
|
291
|
+
// ── Entity solid-colour fallbacks (matched by entityDefaults[n].colorKey) ──
|
|
292
|
+
{ key: 'PLAYER', r: 0, g: 255, b: 0, a: 255 }, // rgba(0, 255, 0, 1)
|
|
293
|
+
{ key: 'OTHER_PLAYER', r: 128, g: 128, b: 255, a: 255 }, // rgba(128, 128, 255, 1)
|
|
294
|
+
{ key: 'BOT', r: 255, g: 128, b: 0, a: 255 }, // rgba(255, 128, 0, 1)
|
|
295
|
+
{ key: 'GHOST', r: 200, g: 200, b: 255, a: 100 }, // rgba(200, 200, 255, 0.39)
|
|
296
|
+
{ key: 'COIN', r: 255, g: 215, b: 0, a: 255 }, // rgba(255, 215, 0, 1)
|
|
297
|
+
{ key: 'SKILL', r: 255, g: 255, b: 50, a: 255 }, // rgba(255, 255, 50, 1)
|
|
298
|
+
// ── UI-only ────────────────────────────────────────────────────
|
|
299
|
+
{ key: 'WEAPON', r: 180, g: 50, b: 50, a: 255 }, // rgba(180, 50, 50, 1)
|
|
300
|
+
// ── Interaction overlay — self-player bubble/panel border ──────
|
|
301
|
+
{ key: 'SELF_BORDER', r: 220, g: 190, b: 60, a: 240 }, // rgba(220, 190, 60, 0.94) — gold
|
|
302
|
+
],
|
|
303
|
+
|
|
304
|
+
// ── World / AOI ────────────────────────────────────────────────────
|
|
305
|
+
aoiRadius: 10,
|
|
306
|
+
portalHoldTimeMs: 1000,
|
|
307
|
+
portalSpawnRadius: 3,
|
|
308
|
+
|
|
309
|
+
// ── Entity base stats ──────────────────────────────────────────────
|
|
310
|
+
entityBaseSpeed: 5,
|
|
311
|
+
entityBaseMaxLife: 100,
|
|
312
|
+
entityBaseActionCooldownMs: 500,
|
|
313
|
+
entityBaseMinActionCooldownMs: 100,
|
|
314
|
+
|
|
315
|
+
// ── Bot defaults ───────────────────────────────────────────────────
|
|
316
|
+
botAggroRange: 10,
|
|
317
|
+
|
|
318
|
+
// ── Player defaults ────────────────────────────────────────────────
|
|
319
|
+
defaultPlayerWidth: 2,
|
|
320
|
+
defaultPlayerHeight: 2,
|
|
321
|
+
playerBaseLifeRegenMin: 0.5,
|
|
322
|
+
playerBaseLifeRegenMax: 1.5,
|
|
323
|
+
sumStatsLimit: 500,
|
|
324
|
+
maxActiveLayers: 4,
|
|
325
|
+
initialLifeFraction: 1.0,
|
|
326
|
+
|
|
327
|
+
// ── Combat / death ─────────────────────────────────────────────────
|
|
328
|
+
respawnDurationMs: 3000,
|
|
329
|
+
collisionLifeLoss: 10,
|
|
330
|
+
|
|
331
|
+
// ── Economy — Fountain & Sink Model ────────────────────────────────
|
|
332
|
+
//
|
|
333
|
+
// All economy parameters live under a single `economyRules` sub-document,
|
|
334
|
+
// mirroring the `skillRules` pattern used by the skill system.
|
|
335
|
+
//
|
|
336
|
+
// This system follows the Fountain & Sink model used by industry-standard
|
|
337
|
+
// MMORPGs (Ultima Online, EverQuest, WoW, EVE Online).
|
|
338
|
+
// Fountains — inject new coins into the economy on spawn events.
|
|
339
|
+
// Kill Transfer — zero-sum redistribution between kill participants.
|
|
340
|
+
// Sinks — destroy coins permanently (alpha: all disabled / 0).
|
|
341
|
+
//
|
|
342
|
+
// On-chain bridge (future):
|
|
343
|
+
// Off-chain coins map 1-to-1 with the CKY token (token ID 0) of the
|
|
344
|
+
// ObjectLayerToken ERC-1155 contract on Hyperledger Besu. On auth the
|
|
345
|
+
// server credits the on-chain balance and this wallet becomes a hot cache.
|
|
346
|
+
// See hardhat/WHITE-PAPER.md §7 "Tokenomics" and OFF_CHAIN_ECONOMY.md.
|
|
347
|
+
economyRules: {
|
|
348
|
+
// ── Fountains ────────────────────────────────────────────────────
|
|
349
|
+
// Coins bots carry at spawn and on every respawn (infinite mint).
|
|
350
|
+
// Bots always reset to this value so the PvE reward loop never dries up.
|
|
351
|
+
botSpawnCoins: 50,
|
|
352
|
+
// Player starting wallet. No persistence — resets on reconnect (guest mode).
|
|
353
|
+
// Persists only when authenticated with an on-chain wallet (future).
|
|
354
|
+
playerSpawnCoins: 50,
|
|
355
|
+
|
|
356
|
+
// ── Kill Transfer (zero-sum redistribution) ───────────────────────
|
|
357
|
+
// Fraction [0,1] of victim coins taken per kill when killing a bot (PvE).
|
|
358
|
+
coinKillPercentVsBot: 0.4,
|
|
359
|
+
// Fraction [0,1] of victim coins taken in PvP — intentionally gentler.
|
|
360
|
+
coinKillPercentVsPlayer: 0.15,
|
|
361
|
+
// Hard floor per kill: guarantees at least this many coins per successful kill.
|
|
362
|
+
coinKillMinAmount: 10,
|
|
363
|
+
|
|
364
|
+
// ── Sinks (alpha stubs — all disabled by default) ─────────────────
|
|
365
|
+
// Fraction [0,1] of dead player's coins burned on respawn (0 = disabled).
|
|
366
|
+
respawnCostPercent: 0.0,
|
|
367
|
+
// Flat coins burned per portal use — travel tax (0 = disabled).
|
|
368
|
+
portalFee: 0,
|
|
369
|
+
// Fraction [0,1] of item value burned per crafting action (0 = disabled).
|
|
370
|
+
craftingFeePercent: 0.0,
|
|
371
|
+
},
|
|
372
|
+
|
|
373
|
+
// ── Regen ──────────────────────────────────────────────────────────
|
|
374
|
+
lifeRegenChance: 300,
|
|
375
|
+
maxChance: 10000,
|
|
376
|
+
|
|
377
|
+
// ── Entity type rendering defaults ─────────────────────────────────
|
|
378
|
+
// Replaces flat fields: userDefaultItemId, botDefaultItemId, ghostItemId,
|
|
379
|
+
// coinItemId, defaultFloorItemId, weaponDefaultItemId.
|
|
380
|
+
// See ENTITY_TYPE_DEFAULTS for documentation of each field.
|
|
381
|
+
// liveItemIds / deadItemIds are arrays of ObjectLayer item IDs.
|
|
382
|
+
entityDefaults: ENTITY_TYPE_DEFAULTS.map((e) => ({ ...e })),
|
|
383
|
+
|
|
384
|
+
// ── Entity Status Indicators (ESI) ─────────────────────────────────
|
|
385
|
+
// Overhead icon mapping — documents the u8→icon relationship.
|
|
386
|
+
// Stored in config for future instance-specific overrides.
|
|
387
|
+
// See STATUS_ICONS constant for documentation.
|
|
388
|
+
statusIcons: STATUS_ICONS.map((s) => ({ ...s })),
|
|
389
|
+
|
|
390
|
+
// ── Skill system ───────────────────────────────────────────────────
|
|
391
|
+
skillConfig: [
|
|
392
|
+
{ triggerItemId: 'atlas_pistol_mk2', logicEventIds: ['atlas_pistol_mk2_logic'] },
|
|
393
|
+
{ triggerItemId: 'coin', logicEventIds: ['coin_drop_or_transaction'] },
|
|
394
|
+
{ triggerItemId: 'anon', logicEventIds: ['doppelganger'] },
|
|
395
|
+
],
|
|
396
|
+
|
|
397
|
+
skillRules: {
|
|
398
|
+
projectileSpawnChance: 0.5,
|
|
399
|
+
projectileLifetimeMs: 2000,
|
|
400
|
+
projectileWidth: 1,
|
|
401
|
+
projectileHeight: 1,
|
|
402
|
+
projectileSpeedMultiplier: 3,
|
|
403
|
+
doppelgangerSpawnChance: 0.5,
|
|
404
|
+
doppelgangerLifetimeMs: 5000,
|
|
405
|
+
doppelgangerSpawnRadius: 3,
|
|
406
|
+
doppelgangerInitialLifeFraction: 1.0,
|
|
407
|
+
},
|
|
408
|
+
|
|
409
|
+
// ── Equipment Rules ────────────────────────────────────────────────
|
|
410
|
+
// Governs which item types can be equipped (activated) and enforces
|
|
411
|
+
// the one-active-per-type constraint. See EQUIPMENT_RULES_DEFAULTS.
|
|
412
|
+
equipmentRules: { ...EQUIPMENT_RULES_DEFAULTS },
|
|
413
|
+
};
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { Schema, model } from 'mongoose';
|
|
2
|
+
import { CYBERIA_INSTANCE_CONF_DEFAULTS as D } from './cyberia-instance-conf.defaults.js';
|
|
3
|
+
|
|
4
|
+
const ColorEntrySchema = new Schema(
|
|
5
|
+
{
|
|
6
|
+
key: { type: String, required: true },
|
|
7
|
+
r: { type: Number, default: 0 },
|
|
8
|
+
g: { type: Number, default: 0 },
|
|
9
|
+
b: { type: Number, default: 0 },
|
|
10
|
+
a: { type: Number, default: 255 },
|
|
11
|
+
},
|
|
12
|
+
{ _id: false },
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
// ObjectLayer inventory slot: itemId + whether it starts active + initial quantity.
|
|
16
|
+
// Used by EntityDefaultSchema.defaultObjectLayers.
|
|
17
|
+
const ObjectLayerSlotSchema = new Schema(
|
|
18
|
+
{
|
|
19
|
+
itemId: { type: String, required: true },
|
|
20
|
+
active: { type: Boolean, default: false },
|
|
21
|
+
quantity: { type: Number, default: 1 },
|
|
22
|
+
},
|
|
23
|
+
{ _id: false },
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
const EntityDefaultSchema = new Schema(
|
|
27
|
+
{
|
|
28
|
+
// Entity category string (matches entity_type_str / bot Behavior in game engine)
|
|
29
|
+
entityType: { type: String, required: true },
|
|
30
|
+
// Default ObjectLayer item IDs when the entity is alive and carries no assigned items.
|
|
31
|
+
liveItemIds: { type: [String], default: [] },
|
|
32
|
+
// Default ObjectLayer item IDs for the dead / ghost / respawning state.
|
|
33
|
+
// Empty array = use liveItemIds solid fill color.
|
|
34
|
+
deadItemIds: { type: [String], default: [] },
|
|
35
|
+
// Palette key for solid-color fallback when no OL items are assigned.
|
|
36
|
+
colorKey: { type: String, default: '' },
|
|
37
|
+
// Full default ObjectLayer inventory for this entity type.
|
|
38
|
+
// Each entry specifies itemId, whether it starts active, and its initial quantity.
|
|
39
|
+
// The coin slot must always have active:false — coins are non-activable.
|
|
40
|
+
// When non-empty this supersedes liveItemIds for inventory initialization.
|
|
41
|
+
defaultObjectLayers: { type: [ObjectLayerSlotSchema], default: [] },
|
|
42
|
+
},
|
|
43
|
+
{ _id: false },
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const SkillConfigEntrySchema = new Schema(
|
|
47
|
+
{
|
|
48
|
+
triggerItemId: { type: String, required: true },
|
|
49
|
+
logicEventIds: { type: [String], default: [] },
|
|
50
|
+
},
|
|
51
|
+
{ _id: false },
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
// ── StatusIconEntrySchema ────────────────────────────────────────────────────
|
|
55
|
+
// Maps a u8 status ID to an overhead icon and a border colour used by the
|
|
56
|
+
// interaction bubble / interact overlay on the C/WASM client.
|
|
57
|
+
// See STATUS_ICONS in cyberia-instance-conf.defaults.js.
|
|
58
|
+
const StatusIconBorderColorSchema = new Schema(
|
|
59
|
+
{
|
|
60
|
+
r: { type: Number, default: 100 },
|
|
61
|
+
g: { type: Number, default: 100 },
|
|
62
|
+
b: { type: Number, default: 100 },
|
|
63
|
+
a: { type: Number, default: 200 },
|
|
64
|
+
},
|
|
65
|
+
{ _id: false },
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
const StatusIconEntrySchema = new Schema(
|
|
69
|
+
{
|
|
70
|
+
id: { type: Number, required: true },
|
|
71
|
+
name: { type: String, default: '' },
|
|
72
|
+
iconId: { type: String, default: null },
|
|
73
|
+
bounce: { type: Boolean, default: false },
|
|
74
|
+
borderColor: { type: StatusIconBorderColorSchema },
|
|
75
|
+
description: { type: String, default: '' },
|
|
76
|
+
},
|
|
77
|
+
{ _id: false },
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
// ── EconomyRulesSchema ───────────────────────────────────────────────────────
|
|
81
|
+
// Mirrors the EconomyRules proto message and the economyRules sub-document in
|
|
82
|
+
// cyberia-instance-conf.defaults.js. All fields default from those canonical
|
|
83
|
+
// values so a freshly created document is immediately playable.
|
|
84
|
+
// See OFF_CHAIN_ECONOMY.md for the full Fountain & Sink architecture.
|
|
85
|
+
const EconomyRulesSchema = new Schema(
|
|
86
|
+
{
|
|
87
|
+
// ── Fountains ───────────────────────────────────────────────────────────
|
|
88
|
+
botSpawnCoins: { type: Number, default: D.economyRules.botSpawnCoins },
|
|
89
|
+
playerSpawnCoins: { type: Number, default: D.economyRules.playerSpawnCoins },
|
|
90
|
+
// ── Kill Transfer ───────────────────────────────────────────────────────
|
|
91
|
+
coinKillPercentVsBot: { type: Number, default: D.economyRules.coinKillPercentVsBot },
|
|
92
|
+
coinKillPercentVsPlayer: { type: Number, default: D.economyRules.coinKillPercentVsPlayer },
|
|
93
|
+
coinKillMinAmount: { type: Number, default: D.economyRules.coinKillMinAmount },
|
|
94
|
+
// ── Sinks ───────────────────────────────────────────────────────────────
|
|
95
|
+
respawnCostPercent: { type: Number, default: D.economyRules.respawnCostPercent },
|
|
96
|
+
portalFee: { type: Number, default: D.economyRules.portalFee },
|
|
97
|
+
craftingFeePercent: { type: Number, default: D.economyRules.craftingFeePercent },
|
|
98
|
+
},
|
|
99
|
+
{ _id: false },
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
// ── EquipmentRulesSchema ─────────────────────────────────────────────────────
|
|
103
|
+
// Governs which ObjectLayer item types can be simultaneously active on a
|
|
104
|
+
// character entity and enforces the one-active-per-type constraint.
|
|
105
|
+
// See EQUIPMENT_RULES_DEFAULTS in cyberia-instance-conf.defaults.js.
|
|
106
|
+
const EquipmentRulesSchema = new Schema(
|
|
107
|
+
{
|
|
108
|
+
// Item types that players are allowed to activate (equip).
|
|
109
|
+
// Types not in this list are non-activable (coins, floors, etc.).
|
|
110
|
+
activeItemTypes: { type: [String], default: D.equipmentRules.activeItemTypes },
|
|
111
|
+
// Enforce at most one active item per item type.
|
|
112
|
+
onePerType: { type: Boolean, default: D.equipmentRules.onePerType },
|
|
113
|
+
// Require at least one active skin when the player owns any skin.
|
|
114
|
+
requireSkin: { type: Boolean, default: D.equipmentRules.requireSkin },
|
|
115
|
+
},
|
|
116
|
+
{ _id: false },
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
const SkillRulesSchema = new Schema(
|
|
120
|
+
{
|
|
121
|
+
projectileSpawnChance: { type: Number, default: D.skillRules.projectileSpawnChance },
|
|
122
|
+
projectileLifetimeMs: { type: Number, default: D.skillRules.projectileLifetimeMs },
|
|
123
|
+
projectileWidth: { type: Number, default: D.skillRules.projectileWidth },
|
|
124
|
+
projectileHeight: { type: Number, default: D.skillRules.projectileHeight },
|
|
125
|
+
projectileSpeedMultiplier: { type: Number, default: D.skillRules.projectileSpeedMultiplier },
|
|
126
|
+
doppelgangerSpawnChance: { type: Number, default: D.skillRules.doppelgangerSpawnChance },
|
|
127
|
+
doppelgangerLifetimeMs: { type: Number, default: D.skillRules.doppelgangerLifetimeMs },
|
|
128
|
+
doppelgangerSpawnRadius: { type: Number, default: D.skillRules.doppelgangerSpawnRadius },
|
|
129
|
+
doppelgangerInitialLifeFraction: { type: Number, default: D.skillRules.doppelgangerInitialLifeFraction },
|
|
130
|
+
},
|
|
131
|
+
{ _id: false },
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Game server configuration for a Cyberia instance.
|
|
136
|
+
* Separated from CyberiaInstance so the GUI never overwrites live server parameters
|
|
137
|
+
* when editing instance identity / map-graph fields.
|
|
138
|
+
*
|
|
139
|
+
* Linked from CyberiaInstance.conf (ObjectId ref).
|
|
140
|
+
* Looked up by instanceCode for CLI / gRPC use.
|
|
141
|
+
*/
|
|
142
|
+
const CyberiaInstanceConfSchema = new Schema(
|
|
143
|
+
{
|
|
144
|
+
// Back-reference to the owning instance (indexed for fast lookup by code).
|
|
145
|
+
instanceCode: { type: String, required: true, unique: true, trim: true },
|
|
146
|
+
|
|
147
|
+
// ── Rendering / camera ──────────────────────────────────────────
|
|
148
|
+
cellSize: { type: Number, default: D.cellSize },
|
|
149
|
+
fps: { type: Number, default: D.fps },
|
|
150
|
+
interpolationMs: { type: Number, default: D.interpolationMs },
|
|
151
|
+
defaultObjWidth: { type: Number, default: D.defaultObjWidth },
|
|
152
|
+
defaultObjHeight: { type: Number, default: D.defaultObjHeight },
|
|
153
|
+
cameraSmoothing: { type: Number, default: D.cameraSmoothing },
|
|
154
|
+
cameraZoom: { type: Number, default: D.cameraZoom },
|
|
155
|
+
defaultWidthScreenFactor: { type: Number, default: D.defaultWidthScreenFactor },
|
|
156
|
+
defaultHeightScreenFactor: { type: Number, default: D.defaultHeightScreenFactor },
|
|
157
|
+
devUi: { type: Boolean, default: D.devUi },
|
|
158
|
+
// Empty array by default — colours must be configured per-instance.
|
|
159
|
+
// toInstanceConfig() fills in CYBERIA_INSTANCE_CONF_DEFAULTS.colors when the array is empty.
|
|
160
|
+
colors: { type: [ColorEntrySchema], default: [] },
|
|
161
|
+
|
|
162
|
+
// ── World / AOI ─────────────────────────────────────────────────
|
|
163
|
+
aoiRadius: { type: Number, default: D.aoiRadius },
|
|
164
|
+
portalHoldTimeMs: { type: Number, default: D.portalHoldTimeMs },
|
|
165
|
+
portalSpawnRadius: { type: Number, default: D.portalSpawnRadius },
|
|
166
|
+
|
|
167
|
+
// ── Entity base stats ────────────────────────────────────────────
|
|
168
|
+
entityBaseSpeed: { type: Number, default: D.entityBaseSpeed },
|
|
169
|
+
entityBaseMaxLife: { type: Number, default: D.entityBaseMaxLife },
|
|
170
|
+
entityBaseActionCooldownMs: { type: Number, default: D.entityBaseActionCooldownMs },
|
|
171
|
+
entityBaseMinActionCooldownMs: { type: Number, default: D.entityBaseMinActionCooldownMs },
|
|
172
|
+
|
|
173
|
+
// ── Bot defaults ─────────────────────────────────────────────────
|
|
174
|
+
botAggroRange: { type: Number, default: D.botAggroRange },
|
|
175
|
+
|
|
176
|
+
// ── Player defaults ──────────────────────────────────────────────
|
|
177
|
+
defaultPlayerWidth: { type: Number, default: D.defaultPlayerWidth },
|
|
178
|
+
defaultPlayerHeight: { type: Number, default: D.defaultPlayerHeight },
|
|
179
|
+
playerBaseLifeRegenMin: { type: Number, default: D.playerBaseLifeRegenMin },
|
|
180
|
+
playerBaseLifeRegenMax: { type: Number, default: D.playerBaseLifeRegenMax },
|
|
181
|
+
sumStatsLimit: { type: Number, default: D.sumStatsLimit },
|
|
182
|
+
maxActiveLayers: { type: Number, default: D.maxActiveLayers },
|
|
183
|
+
initialLifeFraction: { type: Number, default: D.initialLifeFraction },
|
|
184
|
+
|
|
185
|
+
// ── Combat / death ───────────────────────────────────────────────
|
|
186
|
+
respawnDurationMs: { type: Number, default: D.respawnDurationMs },
|
|
187
|
+
collisionLifeLoss: { type: Number, default: D.collisionLifeLoss },
|
|
188
|
+
|
|
189
|
+
// ── Economy ──────────────────────────────────────────────────────
|
|
190
|
+
// Fountain & Sink parameters. See EconomyRulesSchema and OFF_CHAIN_ECONOMY.md.
|
|
191
|
+
economyRules: { type: EconomyRulesSchema },
|
|
192
|
+
|
|
193
|
+
// ── Regen ────────────────────────────────────────────────────────
|
|
194
|
+
lifeRegenChance: { type: Number, default: D.lifeRegenChance },
|
|
195
|
+
maxChance: { type: Number, default: D.maxChance },
|
|
196
|
+
|
|
197
|
+
// ── Entity type rendering defaults ───────────────────────────────
|
|
198
|
+
// Replaces flat fields: userDefaultItemId, botDefaultItemId, ghostItemId,
|
|
199
|
+
// coinItemId, defaultFloorItemId, weaponDefaultItemId.
|
|
200
|
+
// Each entry: { entityType, liveItemIds, deadItemIds, colorKey }.
|
|
201
|
+
entityDefaults: { type: [EntityDefaultSchema], default: D.entityDefaults },
|
|
202
|
+
|
|
203
|
+
// ── Entity Status Indicators ────────────────────────────────────
|
|
204
|
+
// Overhead icon mapping + per-status border colour.
|
|
205
|
+
// See STATUS_ICONS in cyberia-instance-conf.defaults.js.
|
|
206
|
+
statusIcons: { type: [StatusIconEntrySchema], default: D.statusIcons },
|
|
207
|
+
|
|
208
|
+
// ── Skill system ─────────────────────────────────────────────────
|
|
209
|
+
// Each entry maps a trigger item to an ordered list of logic handler keys.
|
|
210
|
+
// Spawning entities (e.g. projectiles) is handled inside the logic handler itself.
|
|
211
|
+
skillConfig: { type: [SkillConfigEntrySchema], default: [] },
|
|
212
|
+
|
|
213
|
+
// Numeric tuning parameters for each skill archetype.
|
|
214
|
+
skillRules: { type: SkillRulesSchema },
|
|
215
|
+
|
|
216
|
+
// ── Equipment rules ──────────────────────────────────────────────
|
|
217
|
+
// Governs which item types can be simultaneously active and enforces
|
|
218
|
+
// the one-active-per-type constraint. See EQUIPMENT_RULES_DEFAULTS.
|
|
219
|
+
equipmentRules: { type: EquipmentRulesSchema },
|
|
220
|
+
},
|
|
221
|
+
{ timestamps: true },
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
const CyberiaInstanceConfModel = model('CyberiaInstanceConf', CyberiaInstanceConfSchema);
|
|
225
|
+
|
|
226
|
+
const ProviderSchema = CyberiaInstanceConfSchema;
|
|
227
|
+
|
|
228
|
+
export { CyberiaInstanceConfSchema, CyberiaInstanceConfModel, ProviderSchema };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { loggerFactory } from '../../server/logger.js';
|
|
2
|
+
import { CyberiaInstanceConfController } from './cyberia-instance-conf.controller.js';
|
|
3
|
+
import express from 'express';
|
|
4
|
+
|
|
5
|
+
const logger = loggerFactory(import.meta);
|
|
6
|
+
|
|
7
|
+
const CyberiaInstanceConfRouter = (options) => {
|
|
8
|
+
const router = express.Router();
|
|
9
|
+
const authMiddleware = options.authMiddleware;
|
|
10
|
+
router.post(`/:id`, async (req, res) => await CyberiaInstanceConfController.post(req, res, options));
|
|
11
|
+
router.post(`/`, async (req, res) => await CyberiaInstanceConfController.post(req, res, options));
|
|
12
|
+
router.get(
|
|
13
|
+
`/:id`,
|
|
14
|
+
// authMiddleware,
|
|
15
|
+
async (req, res) => await CyberiaInstanceConfController.get(req, res, options),
|
|
16
|
+
);
|
|
17
|
+
router.get(`/`, async (req, res) => await CyberiaInstanceConfController.get(req, res, options));
|
|
18
|
+
router.put(`/:id`, async (req, res) => await CyberiaInstanceConfController.put(req, res, options));
|
|
19
|
+
router.put(`/`, async (req, res) => await CyberiaInstanceConfController.put(req, res, options));
|
|
20
|
+
router.delete(`/:id`, async (req, res) => await CyberiaInstanceConfController.delete(req, res, options));
|
|
21
|
+
router.delete(`/`, async (req, res) => await CyberiaInstanceConfController.delete(req, res, options));
|
|
22
|
+
return router;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const ApiRouter = CyberiaInstanceConfRouter;
|
|
26
|
+
|
|
27
|
+
export { ApiRouter, CyberiaInstanceConfRouter };
|