Ch23 BigWorld 与 KBEngine 对照
核心问题:两套项目解决的是同一类问题(大规模 MMO 服务器),但做了哪些不同的取舍?这些取舍的后果是什么?如果让你选,该怎么选?
23.1 全景对照表
先给一张总览,后面逐项展开。
| 维度 | BigWorld | KBEngine | 取向 |
|---|---|---|---|
| 项目性质 | 商业引擎,闭源 | 开源引擎,社区驱动 | 开源 vs 商业 |
| 目标规模 | 10 万+ CCU | 千级 CCU | 量级不同 |
| 进程模型 | 更细粒度拆分 | 更粗粒度合并 | 完备 vs 简洁 |
| 实体模型 | Base + Cell + Ghost + Witness | Base + Cell + Ghost + Witness | 基本相同 |
| RPC 模型 | 单向 + TwoWay + Deferred | 纯单向 + CallbackMgr | 完备 vs 简化 |
| 空间模型 | BSP 树动态拓扑 | 简化空间管理 | 复杂 vs 简单 |
| AOI 模型 | 可插拔 aoi_update_schemes | 固定十字链表 | 可扩展 vs 固定 |
| 持久化 | MySQL + XML + Primary/Secondary + 属性级映射 | MySQL + Redis + 表级映射 | 更完善 vs 更实用 |
| 负载均衡 | CellAppGroup + MetaBalance + Rendezvous Hash | 简化分配 | 自动化 vs 手动 |
| 容错 | Reviver + BackupSender + Archiver | EntityLog + rndUUID 重连 + Archiver/Backuper | 完整灾备 vs 基础收束 |
| 网络层 | 内部 UDP + 自建可靠性(Mercury),四级 ReliableType,isLocalRegular 节奏优化 | Channel 统一抽象,具体可挂 TCP/UDP/KCP,无共享内存 | 高度定制 vs 统一封装 |
| 脚本层 | Twisted Deferred + 完整绑定层 | 简化回调 + 精简绑定 | 表现力 vs 简洁 |
| 可观测性 | ForwardingWatcher + 三级 Profiler + 结构化日志 | 单机 Watcher + ProfileVal + 集中日志 | 运维友好 vs 开发够用 |
| 安全 | Login Challenge (Cuckoo Cycle PoW) + 可插拔加密 | Blowfish 加密 + rndUUID | 更完善 vs 基础 |
| 运维工具 | Reviver + consolidate_dbs + transfer_db + sync_db + Bots 多种控制器 | Bots (ClientApp 继承) | 工具链完整 vs 最小集 |
23.2 进程模型对照
BigWorld:细粒度拆分
LoginApp → 接入层
BaseApp → Base 逻辑
BaseAppMgr → Base 协调
CellApp → Cell 空间逻辑
CellAppMgr → Cell 协调
DBApp → 数据库操作
DBAppMgr → 数据库协调
Reviver → 进程守护
bwmachined → 机器级注册中心
message_logger → 日志聚合
关键设计:
- DBApp + DBAppMgr 拆分:DBApp 做实际数据库操作,DBAppMgr 做集群协调。多 DBApp 可水平扩展
- 独立的 Reviver 进程:专门监控和拉起死亡组件
- bwmachined 是独立系统进程:跨机器的集群管理,有 birth/death 监听器、持久化注册表
KBEngine:粗粒度合并
LoginApp → 接入层
BaseApp → Base 逻辑
BaseAppMgr → Base 协调
CellApp → Cell 空间逻辑
CellAppMgr → Cell 协调
DBMgr → 数据库(合并了 DBApp + DBAppMgr)
Machine → 注册中心(简化版 bwmachined)
Logger → 日志聚合
关键差异:
- DBMgr 合二为一:数据库操作和协调由同一进程负责,无法水平扩展数据库操作
- 无 Reviver:进程死亡需外部脚本或人工干预
- Machine 极简:UDP 广播 + 查询,无监听器、无持久化
取舍分析
| 选择 | 好处 | 代价 |
|---|---|---|
| BigWorld 细粒度 | 可水平扩展(DBApp)、独立守护(Reviver) | 运维复杂度高,进程多 |
| KBEngine 粗粒度 | 部署简单,进程少,上手快 | 数据库层单点,容错靠人工 |
23.2.1 组件身份分配:bwmachined vs checkComponentID()
两套系统都需要回答同一个问题:组件进程启动后,如何拿到可路由、可运维、可收敛的稳定身份。
| 维度 | BigWorld | KBEngine |
|---|---|---|
| 身份分配入口 | bwmachined 统一管理和分配 | checkComponentID() 收束 |
| 显式指定 | 主要通过管理链路/启动控制面编排 | 可直接 --cid=... |
| 自动分配 | 由 bwmachined 体系完成 | IDComponentQuerier -> machine.queryComponentID |
| 自举处理 | 注册中心先行,组件后挂载 | machine/logger 支持本地公式分配,避免循环依赖 |
| 运维侧重点 | 注册中心一致性与进程编排 | 关键组件固定 CID + 弹性组件自动兜底 |
避免误读:两者都不是“纯硬件指纹生成身份”的设计。
在云/虚拟化环境中,重建实例、热迁移、模板克隆、容器网络重建都可能让网卡标识漂移或重复;如果只靠硬件编码,容易出现身份漂移或冲突。
实务建议(两者通用):
- 关键组件身份要可预测、可审计(固定映射或固定参数)
- 弹性工作组件允许自动分配,但必须有冲突消解机制
- 把身份变更纳入发布与回滚流程,避免“隐式漂移”
- 监控身份冲突/重复注册/异常重连,把问题前置到运维告警
23.3 实体模型对照
两套项目的实体模型基本相同——都继承自 BigWorld 的 Base/Cell 分离模型:
| 概念 | BigWorld | KBEngine | 差异 |
|---|---|---|---|
| Base | 运行在 BaseApp | 运行在 BaseApp | 相同 |
| Cell | 运行在 CellApp | 运行在 CellApp | 相同 |
| Ghost | Cell 的轻量副本 | Cell 的轻量副本 | 相同 |
| Witness | 与客户端绑定的观察者 | 与客户端绑定的观察者 | 相同 |
| Proxy | Base 的特殊子类,代表玩家 | 同 | 相同 |
| EntityCall | 对应 Mailbox | 对应 EntityCall | 名异实同 |
| EntityDef | .def 文件 + Python | .def 文件 + Python | 格式略有不同 |
核心一致:Base/Cell 分离、real/ghost 区分、Witness 机制——这些都是 BigWorld 架构的核心贡献,KBEngine 完整继承。
细微差异:
- BigWorld 的
Entity继承链更深:ScriptObject → Entity(多了ScriptApp层) - KBEngine 的实体定义更平面化,组件系统(
EntityComponent)是后来添加的 - BigWorld 的
EntityType有更丰富的元数据(标签、类别、优先级等)
23.4 RPC 模型对照
BigWorld:双向 + Deferred
┌──────────────────────────────┐
│ BigWorld RPC │
├──────────────────────────────┤
单向 (Fire-and-forget) │ Mailbox.method(args) │
双向 (TwoWay) │ BWTwoWay + PyDeferred │
回调链 (Callback Chain) │ Deferred.addCallback() │
└──────────────────────────────┘
BigWorld 的 BWTwoWay + PyDeferred 基于 Twisted Deferred 模式:
# BigWorld 脚本层用法(示意)
def onRemoteCall(self, result):
# result 是 TwoWay 的返回值
pass
deferred = someEntity.method.twoWay(args)
deferred.addCallback(onRemoteCall)
deferred.addErrback(onError)
特点:
- TwoWay:发出去等回复,支持超时和错误回调
- PyDeferred:callback/errback 链式处理,可以组合多个异步操作
- ReturnValuesHandler:C++ 层处理 TwoWay 的回复路由
避免误读:BigWorld 的 Mailbox 模型同样显式区分 Cell/Base/Client 执行域,不是把这层架构隐藏起来;这点与 KBEngine 的
entity.base/entity.cell属于同源设计。
KBEngine:纯单向 + CallbackMgr
┌──────────────────────────────┐
│ KBEngine RPC │
├──────────────────────────────┤
单向 (Fire-and-forget) │ EntityCall.method(args)│
模拟回调 │ CallbackMgr │
└──────────────────────────────┘
KBEngine 砍掉了 TwoWay,用 CallbackMgr 模拟:
# KBEngine 脚本层用法(示意)
callbackID = KBEngine.addCallback(self.onRemoteCall)
someEntity.method(args, callbackID)
特点:
- EntityCall 是纯单向:发出即忘,没有内置的"等回复"机制
- CallbackMgr:手动管理 callbackID → 回调函数映射
- 牺牲组合能力:不能链式
.then(),但更简单直接
对比
| 维度 | BigWorld TwoWay + Deferred | KBEngine 单向 + CallbackMgr |
|---|---|---|
| 编程模型 | 异步链式调用 | 手动回调注册 |
| 执行域感知 | 显式(Cell/Base/Client Mailbox) | 显式(base/cell EntityCall) |
| 组合能力 | deferred.addCallback().addCallback() | 无 |
| 错误处理 | 内置 errback 链 | 需手动处理 |
| 学习曲线 | 较陡(需理解 Deferred) | 平缓 |
| 性能 | TwoWay 需维护回复路由表 | 无额外开销 |
| 适用场景 | 复杂异步编排 | 简单回调 |
KBEngine 为什么砍掉 TwoWay:简化实现。MMO 中大多数 RPC 是 fire-and-forget(属性同步、EntityCall 触发),只有少数场景(DB 查询、跨进程验证)需要"等回复",这些用 CallbackMgr 够用。
避免误读:两者的核心差异在“是否内建 TwoWay/Deferred”与接口设计,不在“是否让客户端理解 Base/Cell 执行域”。
23.5 空间模型对照
BigWorld:BSP 树动态拓扑
Space (整个游戏世界)
│
┌───────┴───────┐
│ InternalNode │ (水平分割)
├───────┬───────┤
CellApp1 CellApp2 (各负责左/右半区)
│ │
┌───┴───┐ ┌───┴───┐
│ Leaf │ │ Leaf │ (每个 Leaf 是一个 Cell)
└───────┘ └───────┘
关键特性:
- BSP 树动态划分空间,支持任意数量的 CellApp
- grow/shrink:Cell 边界可动态移动,实现负载均衡
- Offload:实体可跨 Cell 迁移
- CellAppGroup:分组管理,支持多个独立的 Space 共享 CellApp
KBEngine:简化空间管理
Space (单个 Space)
│
SpaceMemory
│
┌──────┴──────┐
Cell1 Cell2 (手动或简单分配)
KBEngine 没有实现 BigWorld 这套 BSP 树。按当前 SpaceMemory 的实现,一个 space 运行时核心就是一个 Cell* pCell_ 加一个 CoordinateSystem;重点是把单 space 的运行态做简单,而不是做 BigWorld 那种多 cell 动态拓扑。
对比
| 维度 | BigWorld BSP | KBEngine 简化 |
|---|---|---|
| 拓扑结构 | BSP 树(二叉空间分割) | 平铺 SpaceMemory |
| 动态扩容 | Cell 边界自动调整 | 需手动干预 |
| 负载均衡 | 自动(基于 EntityProfiler 数据) | 简化分配 |
| 实体迁移 | Offload 机制 | 简化迁移 |
| 复杂度 | 高(BSP 树维护 + 边界同步) | 低(平面管理) |
| 适用场景 | 单 Space 大世界(无缝地图) | 多 Space 中小场景 |
23.6 AOI 模型对照
共同基础:十字链表
两套项目都使用十字链表(Cross-List / CoordinateSystem)作为 AOI 底层数据结构:
- 两个维度的有序链表(X 轴 + Z 轴)
- RangeTrigger / ViewTrigger 做进入/离开检测
- Hysteresis 区域防抖
BigWorld 的扩展:aoi_update_schemes
// BigWorld: lib/cellapp/aoi_update_schemes/
// 可插拔的 AOI 更新策略抽象层
BigWorld 将 AOI 的"哪些实体需要同步给谁"和"怎么同步"分离为可插拔的策略:
- aoi_update_schemes:抽象层,定义更新策略接口
- KBEngine 没有 this 抽象——AOI 更新逻辑直接硬编码在 Witness/Entity 中
对比
| 维度 | BigWorld | KBEngine |
|---|---|---|
| 底层索引 | 十字链表 | 十字链表 |
| 触发器 | RangeTrigger / ViewTrigger | 相同 |
| 更新策略 | 可插拔 aoi_update_schemes | 固定策略 |
| 防抖 | Hysteresis | 类似 |
| 扩展性 | 高(策略可替换) | 低(需改引擎代码) |
23.7 持久化模型对照
BigWorld:更完善的存储抽象
EntityDef 属性定义
↓
PropertyMapping(属性级映射,15+ 种)
├── BlobMapping
├── SequenceMapping
├── StringMapping
├── ClassMapping
├── CompositeMapping
├── UserTypesMapping
└── PythonMapping
↓
EntityMapping → EntityTable
↓
PrimaryDatabase / SecondaryDatabase(主从分离)
↓
MySQL / XML 双后端
特点:
- 属性级映射策略:每个属性可以有不同的存储方式
- 主从分离:PrimaryDatabase 写,SecondaryDatabase 读
- 数据库迁移工具:consolidate_dbs / transfer_db / sync_db
- BillingSystem:完整的计费抽象层
KBEngine:更实用的存储方案
EntityDef 属性定义
↓
EntityTable(表级映射)
↓
DBInterface(统一接口)
├── MySQL 后端
└── Redis 后端
特点:
- MySQL + Redis 双后端:MySQL 做持久化,Redis 做缓存和共享数据
- 表级映射:属性到列的映射更简单
- 无主从分离:单库模式
- Redis 补位:用 Redis 实现了 BigWorld 用内存共享(SharedData)做的事
对比
| 维度 | BigWorld | KBEngine |
|---|---|---|
| 映射粒度 | 属性级(PropertyMapping) | 表级(EntityTable) |
| 主存储 | MySQL | MySQL |
| 缓存 | 无(内存共享替代) | Redis |
| 开发存储 | XML | 无 |
| 主从 | Primary/Secondary | 无原生支持 |
| 迁移工具 | 三个专用工具 | 无 |
| 计费系统 | 内置 | 脚本层实现 |
设计哲学差异:BigWorld 追求存储层的完备抽象,KBEngine 追求实用——MySQL 够用就 MySQL,需要高速读写就加 Redis。
23.8 负载均衡对照
BigWorld:自动化多层次
1. 实体级:EntityTypeProfiler → EntityProfiler → 每个实体的负载追踪
2. Cell 级:CellProfiler → Cell 负载汇总
3. Space 级:BSP 树动态调整 → grow/shrink Cell 边界
4. 组件级:CellAppGroup → CellApp 间负载均衡
5. 分配级:Rendezvous Hash → 新实体分配到负载最低的 CellApp
BigWorld 的负载均衡是数据驱动的:三层 Profiler(Entity → EntityType → Cell)收集精确的负载数据,BSP 树根据这些数据自动调整。
KBEngine:简化分配
1. 组件级:简单的负载查询和分配
2. 无 BSP 树动态调整
3. 无实体级负载追踪
对比
| 维度 | BigWorld | KBEngine |
|---|---|---|
| 负载采集 | 三级 Profiler(Entity/Type/Cell) | Watcher 中的基本指标 |
| 空间均衡 | BSP 树自动 grow/shrink | 无 |
| 实体分配 | Rendezvous Hash | 简化分配 |
| 迁移能力 | Offload 自动迁移 | 简化迁移 |
| 自动化程度 | 高 | 低 |
23.9 容错对照
BigWorld:三级保障
第一级:Reviver
→ 检测进程死亡 → 自动拉起新进程
→ 通过 bwmachined 间接启动(保证注册信息正确)
第二级:BackupSender
→ Base 实体跨 BaseApp 备份
→ BackupHash 做实体→备份 BaseApp 映射
→ BaseApp 死亡时从备份恢复
第三级:Archiver
→ 周期性将 Base 实体写入数据库
→ 支持 SecondaryDB 做本地归档
→ BaseApp 死亡时触发紧急归档
KBEngine:基础收束
第一层:EntityLog
→ DBMgr 维护在线实体检出记录
→ BaseApp 死亡后清理旧 componentID 的检出记录
→ 后续登录重新走分配与加载链路
第二层:rndUUID 重连
→ Proxy 用 rndUUID + entityID 识别重连会话
→ createClientProxies + onGetWitness 重建客户端控制权
第三层:Archiver / Backuper
→ Archiver 按周期触发 writeToDB
→ Backuper 按周期触发 writeBackupData
→ 但不等同于 BigWorld 的跨 BaseApp 灾备恢复
对比
| 维度 | BigWorld | KBEngine |
|---|---|---|
| 进程守护 | Reviver 自动拉起 | 无内建 Reviver,通常靠外部脚本 |
| 实体备份 | BackupSender 跨进程备份 | Backuper / writeBackupData,但不是灾备恢复链 |
| 实体归档 | Archiver 周期写入 | writeToDB + Archiver 周期触发 |
| 恢复粒度 | 从备份 BaseApp 恢复(快) | 从数据库恢复(慢) |
| 数据丢失风险 | 低(备份在内存中) | 中(未写库的数据会丢失) |
这是两套项目差距最大的领域。BigWorld 的强项是“进程守护 + 跨 BaseApp 备份恢复 + 数据库归档”形成完整闭环;KBEngine 虽然也有周期性收束机制,但缺少 BigWorld 那种成熟的跨进程热备恢复。
23.10 网络层对照
BigWorld:UDP 为主 + 自建可靠性(Mercury)
内部通信:UDP(Mercury)
→ 自建可靠传输层(序列号/ACK/发送窗口/重传/分片重组)
→ 四级可靠性(RELIABLE_NO / DRIVER / PASSENGER / CRITICAL)
→ isLocalRegular 发送节奏优化(避免不必要的重传定时器)
→ Piggyback 捎带 ACK
→ SendingStats 追踪 bps/pps/mps
外部通信:TCP + UDP
→ 客户端连接可以是 TCP 或 UDP
关于"共享内存"的澄清:对 BigWorld-Engine-14.4.1 全量源码的扫描证实,开源版没有使用共享内存进行进程间通信。同机和跨机通信走同一条 UDP 路径,区别只是目的 IP 是 LOCALHOST(127.0.0.1)还是远程地址。UDP 在 loopback 上不经网卡,内核直接在 socket 缓冲区间拷贝数据,性能已经很好。Wargaming 内部版本可能有额外优化,但不在 OSE 中。
Mercury 的发送节奏优化(isLocalRegular):
服务器间通道(如 CellAppChannel)默认 isLocalRegular(true)——本端会周期性 tick 驱动发送,ACK 自然捎带在下次发送中,无需额外重传定时器。不定期发送的通道(如匿名通道)设 isLocalRegular(false),加入 IrregularChannels 集合由全局定时器管理重传。
KBEngine:Channel 统一抽象,常见部署偏 TCP
内部通信:`Channel`
→ 统一封装消息收发、序列化和连接状态
→ 常见部署更多依赖 TCP
→ 也保留 UDP/KCP 扩展路径
外部通信:TCP / UDP / KCP
→ 支持 KCP 封装
→ 客户端/bots 侧可挂 KCP sender/receiver
KBEngine 无 isLocalRegular 机制——TCP 天然保证可靠交付,不需要应用层管理重传节奏。
对比
| 维度 | BigWorld | KBEngine |
|---|---|---|
| 内部协议 | UDP + 自建可靠性(Mercury) | Channel 抽象,常见实现偏 TCP |
| 可靠性实现 | 自研(序列号 + ACK + 窗口 + 重传 + Piggyback) | 操作系统 TCP |
| 可靠性分级 | 四级 ReliableType(同一通道内混用) | 无(TCP 全可靠) |
| 延迟 | 更低(无 TCP 拥塞控制/HOL blocking) | 较高(TCP 固有开销) |
| 实现复杂度 | 高(需实现整个可靠性层) | 低(复用 TCP) |
| 发送优化 | isLocalRegular 节奏感知,避免无效定时器 | 无(TCP 栈自行管理) |
| 同机优化 | 无(同机仍走 UDP loopback) | 无(同机仍走 TCP loopback) |
| 共享内存 | 未使用 | 未使用 |
| 外部协议 | TCP/UDP | TCP/UDP/KCP |
| 带宽效率 | Piggyback 优化,不重传不可靠消息 | 标准打包,TCP 重传所有数据 |
BigWorld 选 UDP 的原因:MMO 内部通信需要极致低延迟。TCP 的拥塞控制和 head-of-line blocking 在高并发游戏场景下会造成不必要的延迟。更重要的是,Mercury 允许在同一通道内混用可靠/不可靠消息——位置更新(RELIABLE_NO)丢了就丢了,下一帧覆盖;而实体创建(RELIABLE_CRITICAL)必须可靠送达。
KBEngine 的取向:把网络细节收进 Channel,优先保持实现和消息模型统一,再按客户端或 bots 场景挂接 KCP。TCP 的实现和调试便利性在千级 CCU 场景下是巨大的工程优势。
23.11 脚本层对照
BigWorld:完整的 Python 集成
ServerApp → EntityApp → ScriptApp
↑
Python 运行时初始化
PyImport_AppendInittab
脚本模块注册
脚本定时器系统
脚本频繁任务
绑层规模:
lib/pyscript/:50+ 文件lib/script/:40+ 文件- 高级抽象:pyobject_plus / script_events / script_data_sink/source
- 类型绑定:data_types/ 下 30+ 种 DataType 的 Python 映射
- PyDeferred:基于 Twisted Deferred 的异步编程
- TwoWay RPC:依赖 PyDeferred
KBEngine:精简的 Python 集成
ServerApp → EntityApp
↑
Python 运行时初始化(内联在 EntityApp 中)
绑层规模:
kbe/src/lib/pyscript/:精简的绑层- 回调机制:CallbackMgr(callbackID → 函数映射)
- 无 TwoWay、无 Deferred
对比
| 维度 | BigWorld | KBEngine |
|---|---|---|
| 继承层次 | 三层(ServerApp → EntityApp → ScriptApp) | 两层(ServerApp → EntityApp) |
| 绑层文件 | 90+ 文件 | ~20 文件 |
| 异步编程 | Twisted Deferred(链式) | CallbackMgr(扁平) |
| 类型映射 | 30+ 种 DataType | 基础类型 |
| 事件系统 | script_events(完整) | registerEvent(简化) |
| 学习曲线 | 较陡 | 平缓 |
23.12 可观测性对照
BigWorld:面向运维
ForwardingWatcher → 从 Mgr 组件一站式查询所有下属
EntityProfiler → 单个实体的负载追踪
EntityTypeProfiler → 按类型聚合负载
CellProfiler → Cell 级负载
SendingStats → bps/pps/mps + 重传 + Piggyback
message_logger → 双格式存储 + 组件隔离 + Python 查询
KBEngine:面向开发
Watcher → 单机路径树,guiconsole/telnet 查询
ProfileVal → 函数级耗时统计
NetworkStats → 消息级收发追踪
Logger → 集中收集 + LogWatcher 过滤
Telnet → 4 状态机,Python 解释器
guiconsole → Windows 桌面工具
对比
| 维度 | BigWorld | KBEngine |
|---|---|---|
| 分布式查询 | ForwardingWatcher(一站式) | 无(需逐台查询) |
| 负载精度 | Entity 级 | 函数级 |
| 日志存储 | 双格式 + 结构化 | 单格式 + 缓冲 |
| 日志查询 | Python 接口 + 多维度过滤 | LogWatcher 过滤 |
| GUI 工具 | cellappmgr_viewer_server / bwp | guiconsole(Windows) |
| 定位 | 运维级 | 开发级 |
23.13 安全机制对照
| 维度 | BigWorld | KBEngine |
|---|---|---|
| 登录挑战 | Cuckoo Cycle PoW | 无(脚本层自行实现) |
| 加密通道 | EncryptionFilter(可插拔 BlockCipher) | BlowfishFilter(固定 Blowfish) |
| 身份识别 | 类似机制 | rndUUID(64 位随机) |
| Exposed 方法 | 相同的信任边界 | 相同 |
| 抗暴力破解 | 内置 PoW | 无内置机制 |
BigWorld 在安全方面投入更多——Cuckoo Cycle PoW 有效防止自动化脚本暴力登录,可插拔的 BlockCipher 允许升级加密算法。KBEngine 的安全逻辑更多依赖脚本层自行实现。
23.14 源码入口对照表
| 子系统 | BigWorld 关键文件 | KBEngine 关键文件 |
|---|---|---|
| 进程守护 | server/reviver/reviver.hpp | 无 |
| 备份/归档 | server/baseapp/backup_sender.hpp / archiver.hpp | kbe/src/server/baseapp/backuper.cpp / archiver.cpp |
| EntityLog | 无 | kbe/src/server/dbmgr/dbtasks.h |
| 登录挑战 | lib/connection/cuckoo_cycle_login_challenge_factory.hpp | 无 |
| 加密 | lib/network/encryption_filter.hpp | kbe/src/lib/network/encryption_filter.h |
| 热重载 | lib/moo/reload.hpp | kbe/src/lib/server/entity_app.h |
| Bots | server/tools/bots/bot_entity.cpp | kbe/src/server/tools/bots/bots.h |
| 数据迁移 | server/tools/transfer_db/ | 无 |
| 注册中心 | server/bwmachined/ | kbe/src/server/machine/ |
| 分布式 Watcher | lib/server/watcher_forwarding.hpp | 无(单机 Watcher) |
| BSP 树 | server/cellapp/space/ | 无 |
| AOI 策略 | lib/cellapp/aoi_update_schemes/ | 固定策略 |
| Profiler 三级 | lib/server/entity_profiler.hpp / entity_type_profiler.hpp / server/cellapp/cell_profiler.hpp | kbe/src/lib/helper/profile.h |
| 网络统计 | lib/network/sending_stats.hpp | kbe/src/lib/network/network_stats.h |
23.15 选型建议
选 BigWorld 架构(或其思想)如果:
- 目标 10 万+ CCU,需要极致的性能和可扩展性
- 需要 无缝大世界(BSP 树动态拓扑)
- 需要 高可用(Reviver + Backup + Archive 完整保障链)
- 团队有 资深 C++ 工程师,能驾驭 UDP 自建可靠性
- 可以接受 闭源/商业授权
选 KBEngine 如果:
- 目标 千级 CCU,不需要极致扩展
- 需要 快速上手(开源、文档多、社区活跃)
- 场景以 多 Space 分场景 为主(不需要 BSP)
- 团队规模较小,追求 开发效率
- 需要利用 Redis 生态做缓存和共享数据
两者结合的最佳实践:
- 继承架构思想:Base/Cell 分离、EntityCall、Ghost、Witness 这些核心设计是经过验证的
- 补充现代基础设施:用 Prometheus + Grafana 替代 Watcher、用 OpenTelemetry 补充 Tracing
- 选择合适的网络层:内部用 TCP 简化开发(KBEngine 的选择),外部用 KCP 或 QUIC 降低延迟
- 实现 Reviver:即使不用 BigWorld,也应该有自动进程守护
- 实现 Backup 机制:BaseApp 级别的实体备份是防止数据丢失的关键
- 云环境治理组件身份:不要仅依赖硬件指纹,关键组件使用稳定身份映射,弹性组件保留自动分配兜底
23.16 小结
BigWorld 和 KBEngine 的关系,不是"A 优于 B",而是**"完整方案 vs 最小可行方案"**。
BigWorld 用更多代码、更细粒度的拆分、更完善的工具链,换来:
- 更高的扩展上限
- 更好的容错能力
- 更精细的负载控制
- 更完善的运维支持
KBEngine 用更简洁的设计、更少的进程、更直接的实现,换来:
- 更低的上手门槛
- 更快的开发迭代
- 更少的运维负担
- 开源社区的支持
两者共享的核心贡献——Base/Cell 分离的 MMO 服务器架构模型——才是最有价值的部分。理解了这个模型,无论是用 BigWorld、KBEngine 还是从零开始,都能做出正确的架构决策。
