cyberia 3.2.9 → 3.2.12
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 +6 -0
- package/.github/workflows/npmpkg.ci.yml +1 -0
- package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
- package/.github/workflows/release.cd.yml +1 -0
- package/.vscode/extensions.json +9 -9
- package/.vscode/settings.json +20 -4
- package/CHANGELOG.md +213 -1
- package/CLI-HELP.md +92 -23
- package/README.md +190 -348
- package/bin/build.js +24 -8
- package/bin/build.template.js +187 -0
- package/bin/cyberia.js +229 -52
- package/bin/deploy.js +12 -2
- package/bin/index.js +229 -52
- package/bump.config.js +26 -0
- package/conf.js +130 -24
- package/deployment.yaml +4 -2
- package/hardhat/package-lock.json +113 -144
- package/hardhat/package.json +4 -3
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +4 -2
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +4 -2
- package/manifests/kind-config-dev.yaml +8 -0
- package/manifests/lxd/lxd-admin-profile.yaml +12 -3
- package/manifests/mongodb/pv-pvc.yaml +44 -8
- package/manifests/mongodb/statefulset.yaml +55 -68
- package/manifests/mongodb-4.4/headless-service.yaml +10 -0
- package/manifests/mongodb-4.4/kustomization.yaml +3 -1
- package/manifests/mongodb-4.4/mongodb-nodeport.yaml +17 -0
- package/manifests/mongodb-4.4/pv-pvc.yaml +10 -14
- package/manifests/mongodb-4.4/statefulset.yaml +79 -0
- package/manifests/mongodb-4.4/storage-class.yaml +9 -0
- package/manifests/valkey/statefulset.yaml +1 -1
- package/manifests/valkey/valkey-nodeport.yaml +17 -0
- package/package.json +27 -15
- package/scripts/ipxe-setup.sh +52 -49
- package/scripts/k3s-node-setup.sh +81 -46
- package/scripts/lxd-vm-setup.sh +193 -8
- package/scripts/maas-nat-firewalld.sh +145 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +38 -33
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +16 -16
- package/src/api/core/core.router.js +19 -14
- package/src/api/core/core.service.js +5 -5
- package/src/api/crypto/crypto.router.js +18 -12
- package/src/api/crypto/crypto.service.js +3 -3
- package/src/api/cyberia-action/cyberia-action.model.js +1 -1
- package/src/api/cyberia-action/cyberia-action.router.js +22 -18
- package/src/api/cyberia-action/cyberia-action.service.js +5 -5
- package/src/api/cyberia-client-hints/cyberia-client-hints.controller.js +74 -0
- package/src/api/cyberia-client-hints/cyberia-client-hints.model.js +99 -0
- package/src/api/cyberia-client-hints/cyberia-client-hints.router.js +98 -0
- package/src/api/cyberia-client-hints/cyberia-client-hints.service.js +152 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +25 -20
- package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +6 -6
- package/src/api/cyberia-entity/cyberia-entity.router.js +22 -18
- package/src/api/cyberia-entity/cyberia-entity.service.js +5 -5
- package/src/api/cyberia-instance/cyberia-fallback-world.js +79 -4
- package/src/api/cyberia-instance/cyberia-instance.router.js +57 -52
- package/src/api/cyberia-instance/cyberia-instance.service.js +10 -10
- package/src/api/cyberia-instance/cyberia-world-generator.js +3 -3
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +14 -48
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +22 -18
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +5 -5
- package/src/api/cyberia-map/cyberia-map.router.js +35 -30
- package/src/api/cyberia-map/cyberia-map.service.js +7 -7
- package/src/api/cyberia-quest/cyberia-quest.model.js +1 -1
- package/src/api/cyberia-quest/cyberia-quest.router.js +22 -18
- package/src/api/cyberia-quest/cyberia-quest.service.js +5 -5
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +22 -18
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +5 -5
- package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +451 -0
- package/src/api/default/default.router.js +22 -18
- package/src/api/default/default.service.js +5 -5
- package/src/api/document/document.router.js +28 -23
- package/src/api/document/document.service.js +100 -23
- package/src/api/file/file.router.js +19 -13
- package/src/api/file/file.service.js +9 -7
- package/src/api/instance/instance.router.js +29 -24
- package/src/api/instance/instance.service.js +6 -6
- package/src/api/ipfs/ipfs.router.js +21 -16
- package/src/api/ipfs/ipfs.service.js +8 -8
- package/src/api/object-layer/object-layer.router.js +512 -507
- package/src/api/object-layer/object-layer.service.js +17 -14
- package/src/api/object-layer-render-frames/object-layer-render-frames.router.js +22 -18
- package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +5 -5
- package/src/api/test/test.router.js +17 -12
- package/src/api/types.js +24 -0
- package/src/api/user/guest.service.js +5 -4
- package/src/api/user/user.router.js +297 -288
- package/src/api/user/user.service.js +100 -35
- package/src/cli/baremetal.js +132 -101
- package/src/cli/cluster.js +700 -232
- package/src/cli/db.js +59 -60
- package/src/cli/deploy.js +216 -137
- package/src/cli/fs.js +13 -3
- package/src/cli/index.js +80 -15
- package/src/cli/ipfs.js +4 -6
- package/src/cli/kubectl.js +4 -1
- package/src/cli/lxd.js +1099 -223
- package/src/cli/monitor.js +9 -3
- package/src/cli/release.js +334 -140
- package/src/cli/repository.js +68 -23
- package/src/cli/run.js +193 -49
- package/src/cli/secrets.js +11 -2
- package/src/cli/test.js +9 -3
- package/src/client/Default.index.js +9 -3
- package/src/client/components/core/Auth.js +5 -0
- package/src/client/components/core/ClientEvents.js +76 -0
- package/src/client/components/core/EventBus.js +4 -0
- package/src/client/components/core/Modal.js +82 -41
- package/src/client/components/core/PanelForm.js +56 -52
- package/src/client/components/core/Worker.js +162 -363
- package/src/client/components/cyberia/MapEngineCyberia.js +1 -1
- package/src/client/components/cyberia/SharedDefaultsCyberia.js +330 -0
- package/src/client/public/cyberia-docs/ARCHITECTURE.md +50 -410
- package/src/client/public/cyberia-docs/CYBERIA-CLI.md +114 -327
- package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +200 -222
- package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +203 -185
- package/src/client/public/cyberia-docs/CYBERIA.md +259 -0
- package/src/client/public/cyberia-docs/OFF-CHAIN-ECONOMY.md +2 -2
- package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
- package/src/client/public/cyberia-docs/UNDERPOST-PLATFORM.md +106 -0
- package/src/client/public/cyberia-docs/WHITE-PAPER.md +1 -1
- package/src/client/services/cyberia-client-hints/cyberia-client-hints.service.js +99 -0
- package/src/client/ssr/views/CyberiaServerMetrics.js +982 -0
- package/src/client/sw/core.sw.js +174 -112
- package/src/db/DataBaseProvider.js +115 -15
- package/src/db/mariadb/MariaDB.js +2 -1
- package/src/db/mongo/MongoBootstrap.js +657 -0
- package/src/db/mongo/MongooseDB.js +129 -21
- package/src/grpc/cyberia/grpc-server.js +25 -57
- package/src/index.js +1 -1
- package/src/runtime/cyberia-client/Dockerfile +24 -3
- package/src/runtime/cyberia-client/Dockerfile.dev +82 -0
- package/src/runtime/cyberia-server/Dockerfile +29 -4
- package/src/runtime/cyberia-server/Dockerfile.dev +71 -0
- package/src/runtime/express/Express.js +2 -2
- package/src/runtime/wp/Wp.js +8 -5
- package/src/server/auth.js +2 -2
- package/src/server/client-build-docs.js +1 -1
- package/src/server/client-build.js +94 -129
- package/src/server/conf.js +86 -83
- package/src/server/process.js +180 -19
- package/src/server/proxy.js +9 -2
- package/src/server/runtime.js +1 -1
- package/src/server/start.js +17 -5
- package/src/server/valkey.js +2 -0
- package/src/ws/IoInterface.js +16 -16
- package/src/ws/core/channels/core.ws.chat.js +11 -11
- package/src/ws/core/channels/core.ws.mailer.js +29 -29
- package/src/ws/core/channels/core.ws.stream.js +19 -19
- package/src/ws/core/core.ws.connection.js +8 -8
- package/src/ws/core/core.ws.server.js +6 -5
- package/src/ws/default/channels/default.ws.main.js +10 -10
- package/src/ws/default/default.ws.connection.js +4 -4
- package/src/ws/default/default.ws.server.js +4 -3
- package/bin/file.js +0 -202
- package/bin/vs.js +0 -74
- package/bin/zed.js +0 -84
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.defaults.js +0 -574
- package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +0 -467
- package/src/client/ssr/email/DefaultRecoverEmail.js +0 -21
- package/src/client/ssr/email/DefaultVerifyEmail.js +0 -17
- package/src/client/ssr/pages/CyberiaServerMetrics.js +0 -461
- /package/src/client/ssr/{offline → views}/Maintenance.js +0 -0
- /package/src/client/ssr/{offline → views}/NoNetworkConnection.js +0 -0
- /package/src/client/ssr/{pages → views}/Test.js +0 -0
|
@@ -1,443 +1,83 @@
|
|
|
1
|
-
# Cyberia
|
|
1
|
+
# Cyberia Architecture
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Cyberia is the MMO extension that runs on top of Underpost Platform. Keep the model simple:
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Cyberia Online is a real-time tap-based sandbox MMORPG built on three independent service layers communicating through well-defined binary and gRPC protocols. The system separates concerns across:
|
|
10
|
-
|
|
11
|
-
1. **Engine-Cyberia** (Node.js) — data persistence, gRPC data service, REST API, CI/CD tooling.
|
|
12
|
-
2. **cyberia-server** (Go) — real-time multiplayer game logic, binary WebSocket AOI protocol.
|
|
13
|
-
3. **cyberia-client** (C/WASM) — game rendering client compiled to WebAssembly.
|
|
5
|
+
- Underpost Platform provides the toolchain, deployment surface, PWA delivery, and base infrastructure.
|
|
6
|
+
- `engine-cyberia` is the content authority.
|
|
7
|
+
- `cyberia-server` is the authoritative simulation.
|
|
8
|
+
- `cyberia-client` is the presentation runtime.
|
|
14
9
|
|
|
15
10
|
---
|
|
16
11
|
|
|
17
|
-
##
|
|
18
|
-
|
|
19
|
-
```mermaid
|
|
20
|
-
graph TB
|
|
21
|
-
subgraph Client["cyberia-client (C/WASM)"]
|
|
22
|
-
SDL["SDL2 + OpenGL ES2\nRendering Pipeline"]
|
|
23
|
-
BinDecoder["Binary AOI Decoder"]
|
|
24
|
-
OLEngine["Object Layer Engine\nAtlas Sprite Compositor"]
|
|
25
|
-
Input["Tap/Click Input Handler"]
|
|
26
|
-
end
|
|
12
|
+
## System map
|
|
27
13
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
PathFinding["A* Pathfinding\n(Bot Navigation)"]
|
|
32
|
-
Skills["Skill Dispatcher\nProjectile · Doppelganger"]
|
|
33
|
-
Economy["Economy Module\nFountain & Sink"]
|
|
34
|
-
gRPCClient["gRPC Client\nWorld Builder"]
|
|
35
|
-
end
|
|
14
|
+
```text
|
|
15
|
+
Underpost Platform
|
|
16
|
+
-> toolchain, deploy, PWA build, static delivery, monitoring
|
|
36
17
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
MongoDB["MongoDB\nMongoose ORM"]
|
|
41
|
-
Valkey["Valkey\n(Redis-compatible)"]
|
|
42
|
-
IPFS["IPFS Cluster + Kubo\nAsset Pinning"]
|
|
43
|
-
end
|
|
18
|
+
engine-cyberia (Node.js)
|
|
19
|
+
-> content, validation, persistence, gRPC/REST data services, asset metadata
|
|
20
|
+
-> feeds cyberia-server and cyberia-client
|
|
44
21
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
22
|
+
cyberia-server (Go)
|
|
23
|
+
-> authoritative simulation and tick processing
|
|
24
|
+
-> feeds cyberia-client over WebSocket
|
|
48
25
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
GoServer <-->|"gRPC :50051\nGetFullInstance\nGetObjectLayerBatch\nGetMapData · Ping"| Engine
|
|
52
|
-
Engine <-->|"ethers.js\nEIP-712 + ERC-1155"| Blockchain
|
|
53
|
-
Engine <-->|"IPFS API"| IPFS
|
|
54
|
-
Engine <-->|"mongoose"| MongoDB
|
|
26
|
+
cyberia-client (C/WASM)
|
|
27
|
+
-> rendering, input, prediction, presentation
|
|
55
28
|
```
|
|
56
29
|
|
|
57
30
|
---
|
|
58
31
|
|
|
59
|
-
##
|
|
60
|
-
|
|
61
|
-
### Engine-Cyberia (Node.js)
|
|
32
|
+
## Responsibility split
|
|
62
33
|
|
|
63
|
-
|
|
34
|
+
| Service | Owns | Must not own |
|
|
35
|
+
| ---------------- | ------------------------------------------------------------------------- | --------------------------------------------- |
|
|
36
|
+
| `engine-cyberia` | content, validation, persistence, gRPC/REST data services, asset metadata | authoritative simulation, render policy |
|
|
37
|
+
| `cyberia-server` | authoritative simulation, world tick, gameplay mutation, AOI replication | content authority, presentation metadata |
|
|
38
|
+
| `cyberia-client` | rendering, input, prediction, interpolation, presentation | authoritative world state, gameplay authority |
|
|
64
39
|
|
|
65
|
-
|
|
40
|
+
Two boundaries are non-negotiable:
|
|
66
41
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
| `object-layer` | CRUD for ObjectLayer documents (AtomicPrefab) |
|
|
70
|
-
| `object-layer-render-frames` | Atlas frame matrix and color palette documents |
|
|
71
|
-
| `atlas-sprite-sheet` | Consolidated atlas PNG + metadata |
|
|
72
|
-
| `cyberia-instance` | Instance graph (maps + portal topology) |
|
|
73
|
-
| `cyberia-map` | Map grid, entity placements, metadata |
|
|
74
|
-
| `cyberia-entity` | Entity definitions |
|
|
75
|
-
| `cyberia-instance-conf` | Instance configuration (skills, economy, equipment) |
|
|
76
|
-
| `cyberia-quest` | Quest definitions |
|
|
77
|
-
| `cyberia-quest-progress` | Per-player quest progress |
|
|
78
|
-
| `cyberia-action` | NPC action definitions |
|
|
79
|
-
| `cyberia-dialogue` | Dialogue lines |
|
|
80
|
-
|
|
81
|
-
**gRPC Service (`CyberiaDataService`):**
|
|
82
|
-
|
|
83
|
-
| RPC | Description |
|
|
84
|
-
| ------------------------------- | ---------------------------------------------------------------- |
|
|
85
|
-
| `GetFullInstance(instanceCode)` | Instance graph + maps + entities + ObjectLayers + InstanceConfig |
|
|
86
|
-
| `GetMapData(mapCode)` | Single map grid and entity data |
|
|
87
|
-
| `GetObjectLayerBatch()` | Stream all ObjectLayers (cache warm-up) |
|
|
88
|
-
| `GetObjectLayer(itemId)` | Single ObjectLayer by item ID |
|
|
89
|
-
| `GetObjectLayerManifest()` | All `itemId + sha256` pairs (hot-reload diff) |
|
|
90
|
-
| `Ping()` | Engine liveness check |
|
|
91
|
-
|
|
92
|
-
**Fallback Instance:** When `GetFullInstance` is called with an unknown instance code, the Engine returns a minimal playable fallback (1 empty 64×64 map, no bots, no ObjectLayers) instead of `NOT_FOUND`.
|
|
42
|
+
- Do not move authoritative logic into the client.
|
|
43
|
+
- Do not move content-authority logic into the Go runtime.
|
|
93
44
|
|
|
94
45
|
---
|
|
95
46
|
|
|
96
|
-
|
|
47
|
+
## Data flow
|
|
97
48
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
graph LR
|
|
102
|
-
A["gRPC\nGetFullInstance"] --> B["BuildWorldFromInstance\ninstance_loader.go"]
|
|
103
|
-
B --> C["Maps + Portals\n+ Entity Registry"]
|
|
104
|
-
C --> D["Game Loop\nserver.go"]
|
|
105
|
-
D --> E["AOI Ticks\naoi_binary.go"]
|
|
106
|
-
E --> F["Binary WS Messages\nto C clients"]
|
|
49
|
+
```text
|
|
50
|
+
engine-cyberia --gRPC--> cyberia-server --WebSocket--> cyberia-client
|
|
51
|
+
engine-cyberia --REST-------------------------------> cyberia-client
|
|
107
52
|
```
|
|
108
53
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
| ----------------------- | ----------------------------------------------------- |
|
|
113
|
-
| `server.go` | WebSocket lifecycle, game loop, player registry |
|
|
114
|
-
| `aoi_binary.go` | Binary AOI wire format encoder/decoder |
|
|
115
|
-
| `object_layer.go` | ObjectLayer Go types mirroring the MongoDB schema |
|
|
116
|
-
| `collision.go` | Grid collision detection, portal transitions |
|
|
117
|
-
| `pathfinding.go` | A\* pathfinding for bot navigation |
|
|
118
|
-
| `skill.go` | Skill entry points: tap action trigger, on-kill hooks |
|
|
119
|
-
| `skill_dispatcher.go` | Skill registry: `InitSkills`, `DispatchSkill` |
|
|
120
|
-
| `skill_projectile.go` | Projectile skill handler |
|
|
121
|
-
| `skill_doppelganger.go` | Doppelganger skill handler |
|
|
122
|
-
| `economy.go` | Fountain & Sink coin economy |
|
|
123
|
-
| `frozen_state.go` | FrozenInteractionState (modal protection) |
|
|
124
|
-
| `entity_status.go` | Entity Status Indicator (ESI) computation |
|
|
125
|
-
| `life_regen.go` | HP regeneration loop |
|
|
126
|
-
| `ai.go` | Bot AI behavior (hostile/passive) |
|
|
127
|
-
| `stats.go` | Stat aggregation and sum-stats limit enforcement |
|
|
128
|
-
| `instance_loader.go` | World reconstruction from gRPC data |
|
|
129
|
-
| `handlers.go` | WebSocket message handlers |
|
|
130
|
-
| `grpcclient/` | gRPC client implementation |
|
|
54
|
+
- `engine-cyberia` publishes world content, validation rules, persistence-backed data, and asset metadata.
|
|
55
|
+
- `cyberia-server` loads authoritative world data, advances the simulation tick, and emits per-player AOI snapshots.
|
|
56
|
+
- `cyberia-client` sends typed input commands upstream and renders the result locally with prediction and interpolation.
|
|
131
57
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
### cyberia-client (C/WASM)
|
|
135
|
-
|
|
136
|
-
Game client compiled to WebAssembly with Emscripten. Runs in the browser.
|
|
137
|
-
|
|
138
|
-
**Key source files:**
|
|
139
|
-
|
|
140
|
-
| File | Responsibility |
|
|
141
|
-
| ---------------------------- | --------------------------------------- |
|
|
142
|
-
| `main.c` | Entry point, game loop |
|
|
143
|
-
| `game_render.c` | Main rendering pipeline |
|
|
144
|
-
| `game_state.c` | Client-side game state management |
|
|
145
|
-
| `network.c` | WebSocket connection + message dispatch |
|
|
146
|
-
| `binary_aoi_decoder.c` | Binary AOI message parser |
|
|
147
|
-
| `object_layer.c` | ObjectLayer metadata store |
|
|
148
|
-
| `object_layers_management.c` | Multi-layer management per entity |
|
|
149
|
-
| `entity_render.c` | Per-entity layer compositing |
|
|
150
|
-
| `layer_z_order.c` | Z-order sorting for rendering |
|
|
151
|
-
| `ol_as_animated_ico.c` | Animated Object Layer rendering |
|
|
152
|
-
| `ol_stack_ico.c` | Stacked icon rendering |
|
|
153
|
-
| `texture_manager.c` | Atlas texture loading and caching |
|
|
154
|
-
| `input.c` | Tap/click input handling |
|
|
155
|
-
| `floating_combat_text.c` | FCT event rendering |
|
|
156
|
-
| `inventory_bar.c` | Bottom inventory bar UI |
|
|
157
|
-
| `inventory_modal.c` | Full inventory modal |
|
|
158
|
-
| `entity_overhead_ui.c` | Nameplate + status icon rendering |
|
|
159
|
-
| `interaction_bubble.c` | NPC interaction prompt bubble |
|
|
160
|
-
| `tap_effect.c` | Tap visual feedback animation |
|
|
161
|
-
| `modal_dialogue.c` | NPC dialogue modal |
|
|
162
|
-
| `modal_player.c` | Player info modal |
|
|
163
|
-
| `message_parser.c` | Server message routing |
|
|
164
|
-
|
|
165
|
-
**Build system:**
|
|
58
|
+
There is one source of truth per concern:
|
|
166
59
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
# Production / release build
|
|
172
|
-
make -f Web.mk clean && make -f Web.mk web BUILD_MODE=RELEASE
|
|
173
|
-
```
|
|
60
|
+
- Content and world configuration: `engine-cyberia`
|
|
61
|
+
- Real-time authoritative state: `cyberia-server`
|
|
62
|
+
- Presentation and local interaction: `cyberia-client`
|
|
174
63
|
|
|
175
64
|
---
|
|
176
65
|
|
|
177
|
-
##
|
|
178
|
-
|
|
179
|
-
The Go server and C client communicate via a custom little-endian binary WebSocket protocol. Only render-essential data is transmitted; atlas binaries are fetched from the Engine REST API independently.
|
|
180
|
-
|
|
181
|
-
```
|
|
182
|
-
Header (5 bytes):
|
|
183
|
-
[0] u8 msgType
|
|
184
|
-
0x01 = aoi_update (partial delta update)
|
|
185
|
-
0x02 = init_data (full game config on connect)
|
|
186
|
-
0x03 = full_aoi (complete world snapshot)
|
|
187
|
-
0x04 = FCT (Floating Combat Text, 14 bytes fixed)
|
|
188
|
-
0x05 = ItemFCT (Item quantity FCT, variable)
|
|
189
|
-
[1..2] u16 reserved (0)
|
|
190
|
-
[3..4] u16 entityCount
|
|
66
|
+
## Operational guardrails
|
|
191
67
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
bit 4: has life data
|
|
197
|
-
bit 5: has respawn timer
|
|
198
|
-
bit 6: has behavior string
|
|
199
|
-
bit 7: has color data (RGBA)
|
|
200
|
-
[1..36] 36B entity UUID (zero-padded)
|
|
201
|
-
-- if not removed: --
|
|
202
|
-
f32 posX, posY, dimW, dimH
|
|
203
|
-
u8 direction (0–8: UP, UP_RIGHT, RIGHT, DOWN_RIGHT, DOWN, DOWN_LEFT, LEFT, UP_LEFT, NONE)
|
|
204
|
-
u8 mode (0=idle, 1=walking, 2=teleporting)
|
|
205
|
-
-- if bit 4: f32 life, f32 maxLife --
|
|
206
|
-
-- if bit 5: f32 respawnIn --
|
|
207
|
-
-- if bit 6: u8 behaviorLen + str behavior --
|
|
208
|
-
-- if bit 7: u8 r, g, b, a --
|
|
209
|
-
-- item ID stack: --
|
|
210
|
-
u8 itemIdCount
|
|
211
|
-
per item: u8 len + str itemId
|
|
212
|
-
|
|
213
|
-
Self-player section (appended after entity blocks):
|
|
214
|
-
<entity block fields>
|
|
215
|
-
f32 aoiMinX, aoiMinY, aoiMaxX, aoiMaxY
|
|
216
|
-
u8 onPortal
|
|
217
|
-
u16 sumStatsLimit
|
|
218
|
-
u16 activeStatsSum
|
|
219
|
-
u8+str mapCode
|
|
220
|
-
u8 pathLen
|
|
221
|
-
per path point: i16 x, i16 y
|
|
222
|
-
i16 targetPosX, targetPosY
|
|
223
|
-
u8+str activePortalID
|
|
224
|
-
u32 coinBalance
|
|
225
|
-
<full inventory>
|
|
226
|
-
u8 frozen (FrozenInteractionState)
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
**FCT message (14 bytes fixed):**
|
|
230
|
-
|
|
231
|
-
| `fctType` | Constant | Color | Display |
|
|
232
|
-
| --------- | ----------------- | ------ | -------------- |
|
|
233
|
-
| `0x00` | `FCTTypeDamage` | Red | `-N` HP lost |
|
|
234
|
-
| `0x01` | `FCTTypeRegen` | Green | `+N` HP gained |
|
|
235
|
-
| `0x02` | `FCTTypeCoinGain` | Yellow | `+N` coins |
|
|
236
|
-
| `0x03` | `FCTTypeCoinLoss` | Yellow | `-N` coins |
|
|
237
|
-
| `0x04` | `FCTTypeItemGain` | Cyan | `+N ItemID` |
|
|
238
|
-
| `0x05` | `FCTTypeItemLoss` | Purple | `-N ItemID` |
|
|
68
|
+
- Prefer one source of truth for config, deploy IDs, runtime selection, startup behavior, and generated assets.
|
|
69
|
+
- Reuse existing helpers and conventions instead of creating parallel implementations.
|
|
70
|
+
- Do not duplicate parsing, env resolution, or path normalization logic across modules.
|
|
71
|
+
- Treat generated artifacts as outputs only; never hand-edit them.
|
|
239
72
|
|
|
240
73
|
---
|
|
241
74
|
|
|
242
|
-
##
|
|
243
|
-
|
|
244
|
-
```mermaid
|
|
245
|
-
graph LR
|
|
246
|
-
Engine["Node.js Engine\nMongoDB + Express\ngrpc-server.js :50051"]
|
|
247
|
-
GoServer["Go Game Server\ncyberia-server\ngrpcclient/"]
|
|
248
|
-
|
|
249
|
-
Engine -->|"GetFullInstance\nGetObjectLayerBatch\nGetMapData · Ping\nGetObjectLayerManifest"| GoServer
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
**Data flow:**
|
|
253
|
-
|
|
254
|
-
```
|
|
255
|
-
MongoDB (CyberiaInstance + CyberiaMap + ObjectLayer)
|
|
256
|
-
│
|
|
257
|
-
▼
|
|
258
|
-
Node.js Engine (grpc-server.js)
|
|
259
|
-
│ GetFullInstance → instance graph + maps + entities + ObjectLayers + InstanceConfig
|
|
260
|
-
│ GetObjectLayerBatch → stream all ObjectLayers
|
|
261
|
-
│ GetObjectLayerManifest → itemId + sha256 pairs (hot-reload diffing)
|
|
262
|
-
│ Ping → liveness check
|
|
263
|
-
▼
|
|
264
|
-
Go Game Server (world_builder.go → instance_loader.go → server.go)
|
|
265
|
-
│ ApplyInstanceConfig → sets all game parameters from gRPC
|
|
266
|
-
│ BuildWorldFromInstance → builds maps, entities, portals
|
|
267
|
-
│ ReplaceObjectLayerCache → caches ObjectLayer metadata
|
|
268
|
-
▼
|
|
269
|
-
C/WASM Client (WebSocket binary AOI protocol)
|
|
270
|
-
│ init_data → game config, player state, grid dimensions
|
|
271
|
-
│ metadata → ObjectLayer cache (delivered once after connect)
|
|
272
|
-
│ aoi_update → binary-encoded entity positions, directions, modes, colors, item stacks
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
---
|
|
276
|
-
|
|
277
|
-
## Instance Topology
|
|
278
|
-
|
|
279
|
-
A `CyberiaInstance` is a directed graph:
|
|
280
|
-
|
|
281
|
-
- **Vertices** = `CyberiaMap` documents (grid-based maps).
|
|
282
|
-
- **Edges** = `PortalEdge` records connecting source cell → target map/cell.
|
|
283
|
-
|
|
284
|
-
**Portal modes:**
|
|
285
|
-
|
|
286
|
-
| Mode | Behavior |
|
|
287
|
-
| -------------- | ------------------------------------------- |
|
|
288
|
-
| `inter-portal` | Teleport to specific cell on target map |
|
|
289
|
-
| `inter-random` | Teleport to random valid cell on target map |
|
|
290
|
-
| `intra-portal` | Teleport within same map to specific cell |
|
|
291
|
-
| `intra-random` | Teleport within same map to random cell |
|
|
292
|
-
|
|
293
|
-
**Topology modes:** `linear`, `hub-spoke`, `open`, `grid`.
|
|
294
|
-
|
|
295
|
-
---
|
|
296
|
-
|
|
297
|
-
## Entity Types and Status Indicators
|
|
298
|
-
|
|
299
|
-
### Entity Types
|
|
300
|
-
|
|
301
|
-
| Type | Behavior | Description |
|
|
302
|
-
| -------------- | --------------------- | --------------------------- |
|
|
303
|
-
| `player` | interactive | Local player (self) |
|
|
304
|
-
| `other_player` | interactive | Remote players in AOI |
|
|
305
|
-
| `bot` | `hostile` / `passive` | AI-controlled entities |
|
|
306
|
-
| `skill` | `skill` | Runtime-spawned projectile |
|
|
307
|
-
| `coin` | `coin` | Runtime-spawned collectible |
|
|
308
|
-
| `floor` | static | Terrain tile |
|
|
309
|
-
| `obstacle` | static | Collision tile |
|
|
310
|
-
| `portal` | static | Zone transition trigger |
|
|
311
|
-
| `foreground` | static | Foreground decoration |
|
|
312
|
-
| `resource` | extractable | Exploitable world object |
|
|
313
|
-
|
|
314
|
-
### Entity Status Indicator (ESI)
|
|
315
|
-
|
|
316
|
-
The Go server computes a status `u8` per entity on each AOI tick. The C client renders the corresponding icon above the entity nameplate:
|
|
317
|
-
|
|
318
|
-
| `id` | Name | Icon | Description |
|
|
319
|
-
| ---- | -------------------- | --------------- | -------------------------------- |
|
|
320
|
-
| 0 | `none` | — | Skill/coin bots, world objects |
|
|
321
|
-
| 1 | `passive` | arrow-down-gray | Non-aggressive bot |
|
|
322
|
-
| 2 | `hostile` | arrow-down-red | Aggressive bot (will aggro) |
|
|
323
|
-
| 3 | `frozen` | chat | Player in FrozenInteractionState |
|
|
324
|
-
| 4 | `player` | arrow-down | Normal alive player |
|
|
325
|
-
| 5 | `dead` | skull | Dead / respawning entity |
|
|
326
|
-
| 6 | `resource` | arrow-down-gray | Static exploitable resource |
|
|
327
|
-
| 7 | `resource-extracted` | clock | Depleted resource (respawning) |
|
|
328
|
-
| 8 | `action-provider` | chat (bounce) | NPC with available actions |
|
|
329
|
-
|
|
330
|
-
---
|
|
331
|
-
|
|
332
|
-
## FrozenInteractionState
|
|
333
|
-
|
|
334
|
-
When a player opens a modal (dialogue, inventory, shop, craft), they enter **FrozenInteractionState**:
|
|
335
|
-
|
|
336
|
-
- Cannot deal or receive damage.
|
|
337
|
-
- Cannot send or receive movement events.
|
|
338
|
-
- The rest of the world continues normally.
|
|
339
|
-
- Managed exclusively by `FreezePlayer` / `ThawPlayer` in `frozen_state.go`.
|
|
340
|
-
|
|
341
|
-
---
|
|
342
|
-
|
|
343
|
-
## Skill System
|
|
344
|
-
|
|
345
|
-
### Item → Skill Mapping
|
|
346
|
-
|
|
347
|
-
```
|
|
348
|
-
CyberiaInstanceConf.skillConfig[]:
|
|
349
|
-
triggerItemId: "atlas_pistol_mk2" ← item in player's active object layers
|
|
350
|
-
logicEventIds: ["projectile"] ← ordered handler keys executed in sequence
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
### Skill Handlers
|
|
354
|
-
|
|
355
|
-
| `logicEventId` | Handler | Description |
|
|
356
|
-
| -------------------------- | ---------------------------- | ------------------------------------------------ |
|
|
357
|
-
| `projectile` | `executeProjectileSkill()` | Spawn a directional projectile entity |
|
|
358
|
-
| `doppelganger` | `executeDoppelgangerSkill()` | Spawn a temporary allied duplicate |
|
|
359
|
-
| `coin_drop_or_transaction` | economy handler | Spawn a coin entity at target position (economy) |
|
|
360
|
-
|
|
361
|
-
### Skill Parameters (SkillRules)
|
|
362
|
-
|
|
363
|
-
| Parameter | Description |
|
|
364
|
-
| --------------------------------- | ------------------------------------------------ |
|
|
365
|
-
| `projectileSpawnChance` | Probability of spawning a projectile per trigger |
|
|
366
|
-
| `projectileLifetimeMs` | Projectile lifetime in milliseconds |
|
|
367
|
-
| `projectileWidth/Height` | Projectile entity dimensions |
|
|
368
|
-
| `projectileSpeedMultiplier` | Speed relative to base entity speed |
|
|
369
|
-
| `doppelgangerSpawnChance` | Probability of spawning a doppelganger |
|
|
370
|
-
| `doppelgangerLifetimeMs` | Doppelganger lifetime |
|
|
371
|
-
| `doppelgangerSpawnRadius` | Max spawn distance from player |
|
|
372
|
-
| `doppelgangerInitialLifeFraction` | Initial HP as fraction of player max HP |
|
|
373
|
-
|
|
374
|
-
---
|
|
375
|
-
|
|
376
|
-
## Development Setup
|
|
377
|
-
|
|
378
|
-
```bash
|
|
379
|
-
# Terminal 1: Engine (Node.js)
|
|
380
|
-
cd /home/dd/engine
|
|
381
|
-
npm run dev
|
|
382
|
-
# Starts Express :4005+, gRPC :50051, connects to MongoDB
|
|
383
|
-
|
|
384
|
-
# Terminal 2: Go game server
|
|
385
|
-
cd /home/dd/engine/cyberia-server
|
|
386
|
-
cat > .env << 'EOF'
|
|
387
|
-
ENGINE_GRPC_ADDRESS=localhost:50051
|
|
388
|
-
INSTANCE_CODE=cyberia-main
|
|
389
|
-
ENGINE_API_BASE_URL=http://localhost:4005
|
|
390
|
-
SERVER_PORT=8081
|
|
391
|
-
EOF
|
|
392
|
-
go run main.go
|
|
393
|
-
|
|
394
|
-
# Terminal 3: C/WASM client
|
|
395
|
-
cd /home/dd/engine/cyberia-client
|
|
396
|
-
# Edit src/config.h: WS_URL="ws://localhost:8081/ws", API_BASE_URL="http://localhost:4005"
|
|
397
|
-
source ~/.emsdk/emsdk_env.sh
|
|
398
|
-
make -f Web.mk clean && make -f Web.mk web
|
|
399
|
-
make -f Web.mk serve-development # http://localhost:8082
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
**Startup order is required:** Engine must start before the Go server dials gRPC; Go server must be running before the C client connects.
|
|
403
|
-
|
|
404
|
-
### Dev Port Summary
|
|
405
|
-
|
|
406
|
-
| Component | Port | Protocol |
|
|
407
|
-
| ------------------- | ----- | --------- |
|
|
408
|
-
| Engine Express | 4005+ | HTTP/REST |
|
|
409
|
-
| Engine gRPC | 50051 | gRPC |
|
|
410
|
-
| Go server | 8081 | HTTP + WS |
|
|
411
|
-
| C client dev server | 8082 | HTTP |
|
|
412
|
-
|
|
413
|
-
---
|
|
414
|
-
|
|
415
|
-
## Production Deployment
|
|
416
|
-
|
|
417
|
-
### Kubernetes Deployment Order
|
|
418
|
-
|
|
419
|
-
```
|
|
420
|
-
1. Engine (dd-cyberia) ← Express :4005–4014, gRPC :50051 (cluster-internal)
|
|
421
|
-
2. Go server (mmo-server) ← ENGINE_GRPC_ADDRESS=<engine-clusterIP>:50051
|
|
422
|
-
3. C client (mmo-client) ← static WASM files served on :8082
|
|
423
|
-
```
|
|
424
|
-
|
|
425
|
-
### Environment Variables
|
|
426
|
-
|
|
427
|
-
**Go Server:**
|
|
428
|
-
|
|
429
|
-
| Variable | Default | Description |
|
|
430
|
-
| --------------------------------- | ----------------- | ------------------------------------------------------------------------- |
|
|
431
|
-
| `ENGINE_GRPC_ADDRESS` | `localhost:50051` | Engine gRPC address (required) |
|
|
432
|
-
| `INSTANCE_CODE` | `default` | Instance code to load on startup |
|
|
433
|
-
| `SERVER_PORT` | `8081` | WebSocket + HTTP server listen port |
|
|
434
|
-
| `STATIC_DIR` | `./public` | Directory for static WASM client files |
|
|
435
|
-
| `ENGINE_GRPC_RELOAD_INTERVAL_SEC` | _(disabled)_ | ObjectLayer hot-reload polling interval |
|
|
436
|
-
| `READY_CMD` | _(empty)_ | Shell command to run after server starts (orchestration readiness signal) |
|
|
75
|
+
## Health states
|
|
437
76
|
|
|
438
|
-
|
|
77
|
+
| State | Meaning |
|
|
78
|
+
| ---------- | -------------------------------------------------------------------- |
|
|
79
|
+
| `healthy` | all three Cyberia services are up and connected |
|
|
80
|
+
| `degraded` | at least one service is reconnecting or unavailable |
|
|
81
|
+
| `standby` | gameplay is paused because the full three-service set is not healthy |
|
|
439
82
|
|
|
440
|
-
|
|
441
|
-
| -------------- | ------------------------ | ----------------------------------- |
|
|
442
|
-
| `WS_URL` | `ws://localhost:8081/ws` | `wss://server.cyberiaonline.com/ws` |
|
|
443
|
-
| `API_BASE_URL` | `http://localhost:4005` | `https://www.cyberiaonline.com` |
|
|
83
|
+
This is the model to document, operate, and monitor against.
|