22 KiB
挂机类手游技术栈方案(开源可商用)
版本: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 商业免费协议 | 商用免费,无运行时抽成 |
明确规避:SSPL(MongoDB、Redis 7.4+)、BSL(HashiCorp Consul)、RSAL(Redis 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 / Vulkan(Canvas 渲染,非 WebView) |
| 热更新 | 官方内置 Asset Bundle 热更,JS/TS 代码 + 资源均可热更,无需发版 |
选型理由:当前版本采用文字战报战斗模式(后续动画版本单独立项),需要频繁热更新活动玩法和战报文案,Cocos Creator Asset Bundle 热更机制成熟,官方支持鸿蒙 NEXT,是当前需求下最合适的组合。
2.2 客户端核心模块
├── UI 框架 Cocos Creator 内置 UI 系统(Canvas + Widget + Layout)
├── 场景渲染 2.5D 场景地图(TileMap + 层级遮挡)
├── 角色立绘 静态立绘 / 头像(按种族区分,无骨骼动画,当前版本)
├── 战斗战报 文字战报 UI(回合日志 + 血量条动画 + 高亮事件)
├── 资源管理 AssetManager(Bundle 分包 + 远程加载 + 版本管理)
├── 热更新 Asset Bundle 热更(差异包 + MD5 校验 + 回滚支持)
│ 战报文案、活动配置、场景资源均可热更,无需发版
├── 网络层 WebSocket(引擎内置)+ protobufjs(BSD,二进制协议)
├── HTTP 引擎内置 + axios 风格封装
├── 本地存储 sys.localStorage(引擎封装)
├── 音频 AudioManager(引擎内置)
├── 多语言 i18next(MIT)
└── 活动小程序 内嵌 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 游戏服务器框架
选型:Nakama(Apache 2.0)
| 项目 | 说明 |
|---|---|
| 许可证 | Apache 2.0,完全可商用 |
| 开发语言 | Go(服务端核心)+ Lua / TypeScript(自定义逻辑) |
| 内置能力 | 用户系统、排行榜、好友、邮件、实时对战、存储、RPC |
| 开服支持 | 无状态设计,Docker 容器化后可无限横向扩展 |
| 协议 | WebSocket + Protobuf / JSON |
备选:Pitaya(MIT)
| 项目 | 说明 |
|---|---|
| 许可证 | MIT |
| 来源 | 网易开源 |
| 特点 | 分布式集群架构,原生支持分区分服,etcd 服务发现 |
| 适用场景 | 对集群拓扑控制要求更高时选用 |
3.2 HTTP API 服务
语言:Go
框架:Gin(MIT)
用途:GM 后台接口、支付回调、第三方登录验证、运营活动接口
3.3 数据层
关系型数据库:PostgreSQL 16
| 项目 | 说明 |
|---|---|
| 许可证 | PostgreSQL License(类 MIT,完全可商用) |
| 用途 | 角色数据、装备、进度、订单、境界配置 |
| 扩展 | pg_partman 分区(MIT)、pgvector(MIT) |
缓存 / 排行榜:Valkey 8.x
| 项目 | 说明 |
|---|---|
| 许可证 | BSD 3-Clause |
| 来源 | Linux 基金会主导的 Redis 官方 fork,规避 Redis 7.4+ 的 RSAL+SSPL 问题 |
| 用途 | 在线状态、Session、离线收益缓存、境界排行榜(Sorted Set)、分布式锁 |
日志 / 非结构化数据
使用 PostgreSQL JSONB,规避 MongoDB SSPL:
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 Kafka(Apache 2.0)
| 用途 | 说明 |
|---|---|
| 跨境界活动广播 | 全服推送活动开启 / 关闭事件 |
| 飞升 / 回下界事件 | 异步处理境界迁移,解耦主流程 |
| 离线收益结算 | 玩家下线时异步计算,上线时消费 |
| 日志收集 | 行为日志异步写入 |
轻量备选:NATS(Apache 2.0),适合服务内部低延迟通信。
3.5 服务治理
| 组件 | 选型 | 许可证 | 用途 |
|---|---|---|---|
| 配置中心 | Nacos 2.x | Apache 2.0 | 境界配置下发、动态开关 |
| 服务注册 | Nacos 2.x | Apache 2.0 | 服务实例自动注册发现 |
| 网关 | OpenResty(Nginx + 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 模板化
# 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
开新服只需一条命令:
helm install game-server-s102 ./charts/game-server \
--set serverId=102 \
--set serverName="苍穹界" \
--set db.schema=server_102
4.3 CI/CD 流水线
代码推送 → Gitea(MIT)
↓
Jenkins(MIT)触发构建
↓
Docker 镜像构建 & 推送至 Harbor(Apache 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 数据模型
-- 境界配置表
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 过滤:
-- 境界排行榜(临时下界的上界玩家不参与本界排名)
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 |
| 后端框架 | Gin(Go) | MIT |
| 认证 | JWT(golang-jwt,MIT) | MIT |
| 权限模型 | Casbin RBAC | Apache 2.0 |
6.2 GM 后台核心功能
├── 服务器管理 开服 / 停服 / 合服操作
├── 境界管理 调整境界参数、飞升条件、下界代价
├── 玩家管理 封禁、补偿道具、强制迁移境界、重置密码
├── 活动管理 全服 / 跨境界活动配置,热更新活动 Bundle
├── 公告系统 全服公告、境界内公告、维护公告
├── 邮件系统 全服邮件、境界邮件、定向邮件
├── 数据报表 DAU / 付费 / 在线人数 / 各境界人口分布
└── 日志查询 玩家行为日志、飞升记录、下界记录检索
七、数据分析 & 埋点
选型:Apache Superset(Apache 2.0)+ 自建埋点
| 组件 | 说明 |
|---|---|
| 埋点上报 | 客户端 HTTP 上报至 Kafka,异步落库 PostgreSQL |
| 数据可视化 | Apache Superset(Apache 2.0)连接 PostgreSQL |
| 实时大盘 | Grafana(AGPL v3,自用可商用)+ PostgreSQL 数据源 |
| 境界分析 | 各境界玩家留存、飞升转化率、回下界频次等核心指标 |
八、安全方案
8.1 反作弊
离线收益校验 服务端计算最大离线收益上限,客户端提交值超限则截断
时间防篡改 使用服务端时间戳,客户端时间仅用于 UI 展示
协议加签 每个请求携带 HMAC-SHA256 签名(密钥存服务端)
速率限制 OpenResty 限流,防刷接口
境界校验 飞升 / 回下界操作全部服务端二次校验,客户端申请不可信
8.2 数据安全
传输加密 全链路 HTTPS / WSS(TLS 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) │
└────────┬────────┘ └────────┬────────┘
│ │
▼ ▼
┌──────────────────────────────────────────────────────┐
│ 数据层 │
│ PostgreSQL(players.current_realm 境界隔离) │
│ Valkey(realm:{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,商用受限 | Valkey(BSD) |
| MongoDB | SSPL,SaaS 场景受限 | PostgreSQL JSONB |
| HashiCorp Consul | BSL 1.1,竞品限制 | Nacos(Apache 2.0) |
| Unity | 运行时收费条款 | Cocos Creator(商业免费) |
| Flutter | AOT 编译不支持热更新,活动玩法无法绕过发版 | Cocos Creator(Asset Bundle 热更) |
| Vue3 + Capacitor | WebView 渲染,不适合游戏场景 | Cocos Creator(Canvas 渲染) |
| Elasticsearch | SSPL | PostgreSQL 全文检索 / OpenSearch(Apache 2.0) |
文档生成时间:2026-06-29 | 最后更新:2026-06-29(v1.2 客户端改回 Cocos Creator,新增境界隔离系统设计)