lawless/挂机手游技术栈方案.md

578 行
22 KiB
Markdown

# 挂机类手游技术栈方案(开源可商用)
> 版本1.2
> 日期2026-06-29
> 适用平台Android、iOS、鸿蒙HarmonyOS NEXT
> 核心约束:所有组件必须开源且可商用,无 SSPL / BSL / RSAL 等限制性许可证
---
## 一、许可证基准说明
本方案所有组件须满足以下许可证之一:
| 许可证 | 商用限制 |
|--------|----------|
| MIT | 无 |
| Apache 2.0 | 无 |
| BSD 2/3-Clause | 无 |
| PostgreSQL License | 无(类 MIT |
| MPL 2.0 | 修改须开源,独立使用无限制 |
| Cocos 商业免费协议 | 商用免费,无运行时抽成 |
**明确规避**SSPLMongoDB、Redis 7.4+、BSLHashiCorp Consul、RSALRedis 7.4+、Unity Runtime Fee。
---
## 二、客户端技术栈
### 2.1 游戏引擎
**选型Cocos Creator 3.x**
| 项目 | 说明 |
|------|------|
| 许可证 | Cocos 商业免费协议,无运行时抽成 |
| Android | 原生导出,支持 APK / AAB |
| iOS | 原生导出,支持 App Store 上架 |
| 鸿蒙 NEXT | 官方支持导出 ArkTS 工程,支持 AppGallery 上架 |
| 开发语言 | TypeScript |
| 渲染 | OpenGL ES / Metal / VulkanCanvas 渲染,非 WebView |
| 热更新 | 官方内置 Asset Bundle 热更,JS/TS 代码 + 资源均可热更,无需发版 |
**选型理由**当前版本采用文字战报战斗模式后续动画版本单独立项,需要频繁热更新活动玩法和战报文案,Cocos Creator Asset Bundle 热更机制成熟,官方支持鸿蒙 NEXT,是当前需求下最合适的组合。
### 2.2 客户端核心模块
```
├── UI 框架 Cocos Creator 内置 UI 系统Canvas + Widget + Layout
├── 场景渲染 2.5D 场景地图TileMap + 层级遮挡)
├── 角色立绘 静态立绘 / 头像(按种族区分,无骨骼动画,当前版本)
├── 战斗战报 文字战报 UI回合日志 + 血量条动画 + 高亮事件)
├── 资源管理 AssetManagerBundle 分包 + 远程加载 + 版本管理)
├── 热更新 Asset Bundle 热更(差异包 + MD5 校验 + 回滚支持)
│ 战报文案、活动配置、场景资源均可热更,无需发版
├── 网络层 WebSocket引擎内置+ protobufjsBSD,二进制协议
├── HTTP 引擎内置 + axios 风格封装
├── 本地存储 sys.localStorage引擎封装
├── 音频 AudioManager引擎内置
├── 多语言 i18nextMIT
└── 活动小程序 内嵌 WebView 组件加载 H5 活动页(按需热更)
```
> **后续动画版本**当前版本无骨骼动画,角色以静态立绘展示。动画版本Spine 骨骼动画)作为后续独立迭代项目,核心玩法验证完成后再立项,通过 Asset Bundle 热更上线,不需要重新发版。
### 2.3 热更新方案
| 更新类型 | 机制 | 是否需要发版 |
|----------|------|-------------|
| 数值配置(掉落表、技能参数) | 服务端 JSON 下发,客户端启动时拉取 | 否 |
| 活动玩法 UI + 逻辑 | Asset Bundle 热更,CDN 分发差异包 | 否 |
| 小程序式活动 | WebView 加载 H5,完全绕过商店审核 | 否 |
| 引擎底层 / 原生插件变更 | 商店发版 | 是(必须) |
```
热更流程:
客户端启动 → 请求版本接口 → 比对本地 manifest
→ 有差异 → 下载差异 Bundle → 校验 MD5 → 加载新 Bundle
→ 无差异 → 直接进入游戏
```
### 2.4 三端差异处理
| 能力 | Android | iOS | 鸿蒙 NEXT |
|------|---------|-----|-----------|
| 推送 | FCM免费 | APNs免费 | 华为 Push Kit免费 |
| 支付 | Google Play Billing | App Store IAP | 华为 IAP |
| 登录 | Google One Tap / 自建 | Sign in with Apple / 自建 | 华为 Account Kit / 自建 |
| 权限配置 | AndroidManifest | Info.plist | module.json5 |
| 热更新 | Asset Bundle | Asset Bundle | Asset Bundle官方支持 |
---
## 三、服务端技术栈
### 3.1 游戏服务器框架
**选型NakamaApache 2.0**
| 项目 | 说明 |
|------|------|
| 许可证 | Apache 2.0,完全可商用 |
| 开发语言 | Go服务端核心+ Lua / TypeScript自定义逻辑 |
| 内置能力 | 用户系统、排行榜、好友、邮件、实时对战、存储、RPC |
| 开服支持 | 无状态设计,Docker 容器化后可无限横向扩展 |
| 协议 | WebSocket + Protobuf / JSON |
**备选PitayaMIT**
| 项目 | 说明 |
|------|------|
| 许可证 | MIT |
| 来源 | 网易开源 |
| 特点 | 分布式集群架构,原生支持分区分服,etcd 服务发现 |
| 适用场景 | 对集群拓扑控制要求更高时选用 |
### 3.2 HTTP API 服务
```
语言Go
框架GinMIT
用途GM 后台接口、支付回调、第三方登录验证、运营活动接口
```
### 3.3 数据层
#### 关系型数据库PostgreSQL 16
| 项目 | 说明 |
|------|------|
| 许可证 | PostgreSQL License类 MIT,完全可商用 |
| 用途 | 角色数据、装备、进度、订单、境界配置 |
| 扩展 | pg_partman 分区MIT、pgvectorMIT |
#### 缓存 / 排行榜Valkey 8.x
| 项目 | 说明 |
|------|------|
| 许可证 | BSD 3-Clause |
| 来源 | Linux 基金会主导的 Redis 官方 fork,规避 Redis 7.4+ 的 RSAL+SSPL 问题 |
| 用途 | 在线状态、Session、离线收益缓存、境界排行榜Sorted Set、分布式锁 |
#### 日志 / 非结构化数据
使用 PostgreSQL JSONB,规避 MongoDB SSPL
```sql
CREATE TABLE game_logs (
id BIGSERIAL PRIMARY KEY,
player_id BIGINT NOT NULL,
event_type VARCHAR(64) NOT NULL,
payload JSONB,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX ON game_logs USING GIN (payload);
```
### 3.4 消息队列
**选型Apache KafkaApache 2.0**
| 用途 | 说明 |
|------|------|
| 跨境界活动广播 | 全服推送活动开启 / 关闭事件 |
| 飞升 / 回下界事件 | 异步处理境界迁移,解耦主流程 |
| 离线收益结算 | 玩家下线时异步计算,上线时消费 |
| 日志收集 | 行为日志异步写入 |
**轻量备选NATSApache 2.0**,适合服务内部低延迟通信。
### 3.5 服务治理
| 组件 | 选型 | 许可证 | 用途 |
|------|------|--------|------|
| 配置中心 | Nacos 2.x | Apache 2.0 | 境界配置下发、动态开关 |
| 服务注册 | Nacos 2.x | Apache 2.0 | 服务实例自动注册发现 |
| 网关 | OpenRestyNginx + LuaJIT | BSD | SSL 终止、路由、限流 |
| 备选网关 | Traefik v3 | MIT | K8s 环境下动态路由 |
---
## 四、开服自动化方案
### 4.1 容器化
```
game-server:latest # Nakama 游戏逻辑服
api-server:latest # Gin HTTP API 服
gm-backend:latest # GM 后台服务
```
### 4.2 Helm Chart 模板化
```yaml
# charts/game-server/values.yaml
serverId: 101
serverName: "天元界"
db:
host: pg.internal
schema: server_101
valkey:
keyPrefix: "s101:"
nacos:
group: GAME_SERVER
dataId: server-101
```
开新服只需一条命令:
```bash
helm install game-server-s102 ./charts/game-server \
--set serverId=102 \
--set serverName="苍穹界" \
--set db.schema=server_102
```
### 4.3 CI/CD 流水线
```
代码推送 → GiteaMIT
JenkinsMIT触发构建
Docker 镜像构建 & 推送至 HarborApache 2.0
Helm upgrade --install 部署至 K8s
Nacos 自动注册新服信息
客户端服务器列表更新
```
### 4.4 开服流程时序
```
运营后台点击"开新服" → 调用 GM API
→ Jenkins Job 触发(参数:服务器编号、名称、开放时间)
→ 创建 PostgreSQL Schema + 初始化表结构 + 初始化境界数据
→ Helm install 拉起服务器容器
→ Nacos 注册服务器信息(状态=待开放)
→ 定时任务到达开放时间 → 状态改为 open
→ 客户端轮询 Nacos,自动显示新服
```
---
## 五、境界隔离系统设计
### 5.1 设计概述
游戏对外表现为单服务器,所有玩家在同一逻辑空间内,但按修炼境界划分竞争池。玩家只能看到、交互、竞争同境界的其他玩家,感知不到其他境界的存在。达到条件后可永久飞升上界;上界玩家可消耗代价临时回下界。
```
凡人界Tier 1→ 炼气界Tier 2→ 筑基界Tier 3→ 金丹界Tier 4→ 元婴界 / 上界Tier 5
新手区 顶级玩家区
```
### 5.2 数据模型
```sql
-- 境界配置表
CREATE TABLE realm_tiers (
tier SMALLINT PRIMARY KEY,
name VARCHAR(32) NOT NULL, -- 凡人界、炼气界...
ascend_min_level INT NOT NULL, -- 飞升所需最低等级
ascend_min_power BIGINT NOT NULL, -- 飞升所需最低战力
ascend_cost JSONB NOT NULL, -- {"item_id":1001,"count":10}
descend_cost JSONB, -- {"item_id":2001,"count":1},NULL 表示不可回下界
descend_duration INTERVAL DEFAULT '24 hours' -- 临时下界持续时长
);
-- 玩家核心字段(附加到 players 表)
ALTER TABLE players ADD COLUMN realm_tier SMALLINT NOT NULL DEFAULT 1; -- 归属境界(永久)
ALTER TABLE players ADD COLUMN current_realm SMALLINT NOT NULL DEFAULT 1; -- 当前所在境界
ALTER TABLE players ADD COLUMN descend_expires TIMESTAMPTZ; -- 临时回下界到期,NULL=未回下界
```
**字段说明**
- `realm_tier`:玩家真实所属境界,飞升后永久改变,不随临时下界变化
- `current_realm`:玩家当前实际所在境界,决定能看到哪些排行榜、聊天、玩家
- `descend_expires`:临时下界到期时间,到期后自动迁回 `realm_tier`
### 5.3 境界隔离查询规则
所有涉及玩家互动的查询均以 `current_realm` 过滤:
```sql
-- 境界排行榜(临时下界的上界玩家不参与本界排名)
SELECT id, name, power
FROM players
WHERE current_realm = $1
AND realm_tier = $1 -- 排除临时下界的高境界玩家
ORDER BY power DESC
LIMIT 100;
-- 境界内玩家列表(含临时下界的访客)
SELECT id, name, realm_tier, current_realm
FROM players
WHERE current_realm = $1;
-- 匹配系统PVP 只在同 realm_tier 之间匹配
SELECT id, name, power
FROM players
WHERE realm_tier = $1 -- 按真实境界匹配,防止回下界玩家刷分
AND current_realm = $1
ORDER BY ABS(power - $2) -- 最近战力优先
LIMIT 10;
```
### 5.4 Valkey 缓存结构
```
realm:{tier}:rank Sorted Set 境界排行榜,score = 战力
realm:{tier}:online Set 境界在线玩家 ID
realm:{tier}:chat:world Stream 境界世界频道
realm:{tier}:chat:system Stream 系统公告
player:{id}:realm String 玩家当前境界(网关路由用,低延迟读取)
descend:expire:{id} String+TTL 临时下界到期标记,TTL 到期触发回上界检测
```
### 5.5 飞升流程
```
客户端发起飞升申请
服务端校验:等级 ≥ ascend_min_level AND 战力 ≥ ascend_min_power AND 持有飞升道具
↓(校验通过)
扣除飞升道具
BEGIN TRANSACTION
UPDATE players SET realm_tier = tier+1, current_realm = tier+1 WHERE id = $id
INSERT INTO ascension_log (player_id, from_tier, to_tier, ascended_at) VALUES (...)
COMMIT
清除旧境界缓存(排行榜、在线列表)
初始化新境界缓存(加入新境界排行榜 Sorted Set
Kafka 发布 ascension 事件 → 全服广播"XXX 飞升上界"
客户端收到响应,进入上界场景
```
### 5.6 临时回下界流程
```
上界玩家申请回下界(选择目标境界 target_tier < realm_tier
服务端校验:持有下界令 AND realm_tiers[target_tier].descend_cost 不为 NULL
↓(校验通过)
扣除下界令
BEGIN TRANSACTION
UPDATE players
SET current_realm = target_tier,
descend_expires = NOW() + descend_duration
WHERE id = $id
COMMIT
Valkey 写入 descend:expire:{id},TTL = descend_duration
加入目标境界在线列表(不加入排行榜、不参与 PVP 匹配)
属性封印生效:战力压制到 target_tier 天花板,上界专属技能禁用
客户端显示"仙人下凡"标识
```
**临时下界的行为限制:**
| 行为 | 是否允许 | 说明 |
|------|----------|------|
| 查看下界好友 / 聊天 | ✅ | 主要使用场景 |
| 购买下界交易行物品 | ✅ | 不影响市场均衡(只买不卖) |
| 帮助帮派任务 | ✅ | 有助于活跃帮派 |
| 参与下界 PVP 匹配 | ❌ | 防止破坏下界战力平衡 |
| 参与下界排行榜 | ❌ | 不纳入 realm_tier = target 的排行计算 |
| 占领下界资源点 | ❌ | 防止垄断 |
| 使用上界专属技能 | ❌ | 属性封印 |
| 在下界交易行出售物品 | ❌ | 防止上界物资流入扰乱经济 |
### 5.7 到期自动回上界
```
方案 A推荐Valkey keyspace 通知
配置 notify-keyspace-events Ex
监听 descend:expire:{id} 的 expired 事件
→ 触发回上界逻辑
→ UPDATE players SET current_realm = realm_tier, descend_expires = NULL
→ 更新缓存
方案 B定时扫描兜底与 A 并用)
每 60 秒扫描 descend_expires < NOW() 的玩家
执行回上界逻辑(处理 keyspace 通知漏掉的边界情况)
```
### 5.8 服务器压力评估
境界隔离是**数据过滤层**,不引入新的计算量,服务器压力与传统分服相当:
| 维度 | 影响 | 说明 |
|------|------|------|
| 数据库查询 | 无显著增加 | WHERE 多一个 current_realm 条件,走索引 |
| 排行榜计算 | 无显著增加 | 每境界独立 Sorted Set,与传统分区排行榜相同 |
| 在线人数 | 按境界均摊 | 5 境界 × N 玩家 ≈ N/5 玩家/境界,单境界压力低于全服汇聚 |
| 临时下界玩家 | 极低 | 消耗代价门槛高,占比极少,双态逻辑复杂度可控 |
| 跨境界全局活动 | 需设计 | 限制频率(如每天 1 次),聚合查询走只读副本 |
**水平扩容策略(玩家量大时):**
```
按境界分片部署,对外仍是单服感知:
Tier 1-2 → 实例组 A新手多,需要更多资源
Tier 3-4 → 实例组 B
Tier 5 → 实例组 C顶级玩家,高活跃
路由层OpenResty根据 player:{id}:realm 缓存值分发请求
```
---
## 六、GM 后台 & 运营平台
### 6.1 技术选型
| 层 | 选型 | 许可证 |
|----|------|--------|
| 前端框架 | Vue 3 | MIT |
| UI 组件库 | Naive UI | MIT |
| 图表 | Apache ECharts | Apache 2.0 |
| 后端框架 | GinGo | MIT |
| 认证 | JWTgolang-jwt,MIT | MIT |
| 权限模型 | Casbin RBAC | Apache 2.0 |
### 6.2 GM 后台核心功能
```
├── 服务器管理 开服 / 停服 / 合服操作
├── 境界管理 调整境界参数、飞升条件、下界代价
├── 玩家管理 封禁、补偿道具、强制迁移境界、重置密码
├── 活动管理 全服 / 跨境界活动配置,热更新活动 Bundle
├── 公告系统 全服公告、境界内公告、维护公告
├── 邮件系统 全服邮件、境界邮件、定向邮件
├── 数据报表 DAU / 付费 / 在线人数 / 各境界人口分布
└── 日志查询 玩家行为日志、飞升记录、下界记录检索
```
---
## 七、数据分析 & 埋点
**选型Apache SupersetApache 2.0+ 自建埋点**
| 组件 | 说明 |
|------|------|
| 埋点上报 | 客户端 HTTP 上报至 Kafka,异步落库 PostgreSQL |
| 数据可视化 | Apache SupersetApache 2.0)连接 PostgreSQL |
| 实时大盘 | GrafanaAGPL v3,自用可商用+ PostgreSQL 数据源 |
| 境界分析 | 各境界玩家留存、飞升转化率、回下界频次等核心指标 |
---
## 八、安全方案
### 8.1 反作弊
```
离线收益校验 服务端计算最大离线收益上限,客户端提交值超限则截断
时间防篡改 使用服务端时间戳,客户端时间仅用于 UI 展示
协议加签 每个请求携带 HMAC-SHA256 签名(密钥存服务端)
速率限制 OpenResty 限流,防刷接口
境界校验 飞升 / 回下界操作全部服务端二次校验,客户端申请不可信
```
### 8.2 数据安全
```
传输加密 全链路 HTTPS / WSSTLS 1.3
存储加密 敏感字段 AES-256 加密存储
数据库 PostgreSQL 行级安全策略RLS,境界数据按 realm_tier 行隔离
```
---
## 九、完整架构图
```
┌──────────────────────────────────────────────────────┐
│ 客户端Cocos Creator 3.x
│ Android │ iOS │ HarmonyOS NEXT │
│ Asset Bundle 热更 │ WebView 小程序活动 │
└───────────────────────┬──────────────────────────────┘
│ WebSocket + Protobuf / HTTPS
┌──────────────────────────────────────────────────────┐
│ OpenResty / Traefik 网关层 │
│ SSL 终止 │ 路由(按 player:realm 分发)│ 限流 │
└──────┬───────────────────────────────────────────────┘
├──────────────────────────┐
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ 游戏逻辑服 │ │ 游戏逻辑服 │ ... 按境界或按量扩展
│ Nakama │ │ Nakama │
│ (Docker) │ │ (Docker) │
└────────┬────────┘ └────────┬────────┘
│ │
▼ ▼
┌──────────────────────────────────────────────────────┐
│ 数据层 │
│ PostgreSQLplayers.current_realm 境界隔离) │
│ Valkeyrealm:{tier}:rank / online / chat
└───────────────────────┬──────────────────────────────┘
┌──────────────┼──────────────────┐
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌──────────────┐
│ Kafka │ │ Nacos │ │ Gin API 服 │
│ 消息队列 │ │ 配置中心 │ │ GM 后台接口 │
│ 飞升事件 │ │ 境界参数 │ │ 支付回调 │
└───────────┘ └───────────┘ └──────┬───────┘
┌───────▼────────┐
│ GM 后台 │
│ Vue3 + ECharts │
└────────────────┘
Jenkins + Gitea + Helm + Harbor
CI/CD 自动化开服
```
---
## 十、组件清单与许可证汇总
| 组件 | 版本 | 许可证 | 用途 |
|------|------|--------|------|
| Cocos Creator | 3.x | Cocos 商业免费 | 客户端引擎 + 热更新 |
| protobufjs | latest | BSD | 客户端协议序列化 |
| i18next | latest | MIT | 多语言 |
| Nakama | 3.x | Apache 2.0 | 游戏服务器 |
| Pitaya | latest | MIT | 备选游戏服务器 |
| Go | 1.22+ | BSD | 服务端语言 |
| Gin | latest | MIT | HTTP 框架 |
| PostgreSQL | 16 | PostgreSQL License | 主数据库(境界数据) |
| Valkey | 8.x | BSD 3-Clause | 缓存 / 境界排行榜 |
| Apache Kafka | 3.x | Apache 2.0 | 消息队列(飞升事件等) |
| NATS | 2.x | Apache 2.0 | 轻量消息(服务内部) |
| Nacos | 2.x | Apache 2.0 | 配置 & 注册中心 |
| OpenResty | latest | BSD | 网关(境界路由) |
| Traefik | v3 | MIT | 备选网关 |
| Docker (Moby) | latest | Apache 2.0 | 容器化 |
| Kubernetes | 1.30+ | Apache 2.0 | 容器编排 |
| Helm | 3.x | Apache 2.0 | 服务器模板化 |
| Harbor | 2.x | Apache 2.0 | 私有镜像仓库 |
| Jenkins | 2.x | MIT | CI/CD |
| Gitea | 1.x | MIT | Git 服务 |
| Vue 3 | latest | MIT | GM 后台前端 |
| Naive UI | latest | MIT | UI 组件库 |
| Apache ECharts | 5.x | Apache 2.0 | 图表 |
| Casbin | latest | Apache 2.0 | 权限控制 |
| Apache Superset | latest | Apache 2.0 | 数据分析 |
| Grafana | latest | AGPL v3 | 监控大盘(自用) |
---
## 十一、需规避的方案
| 组件 | 问题 | 替代方案 |
|------|------|----------|
| Redis 7.4+ | RSAL + SSPL,商用受限 | ValkeyBSD |
| MongoDB | SSPL,SaaS 场景受限 | PostgreSQL JSONB |
| HashiCorp Consul | BSL 1.1,竞品限制 | NacosApache 2.0 |
| Unity | 运行时收费条款 | Cocos Creator商业免费 |
| Flutter | AOT 编译不支持热更新,活动玩法无法绕过发版 | Cocos CreatorAsset Bundle 热更) |
| Vue3 + Capacitor | WebView 渲染,不适合游戏场景 | Cocos CreatorCanvas 渲染) |
| Elasticsearch | SSPL | PostgreSQL 全文检索 / OpenSearchApache 2.0 |
---
*文档生成时间2026-06-29 | 最后更新2026-06-29v1.2 客户端改回 Cocos Creator,新增境界隔离系统设计*