实现一个ECS+Actor游戏服务器框架

设计目标

构建一个多进程多线程的分布式游戏服务器框架。

  • 使用Actor模型。
  • 采用ECS模式。
  • 支持热更新。
  • 使用Mongodb作为数据库。
  • 支持服务发现,可动态不停服平行扩展。

为了快速搭建ECS框架,先不考虑底层内存优化。


ActorId与EntityId

Actor有个ActorId,ECS有个EntityId。ActorId是Actor的唯一标识,包含Actor的位置信息。

在写的时候发现Entity在各个框架都有不同的实现。Entity其中的Version是版本号,为了防止悬空引用,每次复用时会递增。

玩家还会有PlayerId,这里我的想法是用PlayerId进行客户端与服务器的交互,对应关系是PlayerId => ActorId => EntityId。

ECS中Entity与Component用struct还是class?

先说我的想法

Entity选用struct。
当组件是纯数据(无方法或简单方法)且需高性能时(如 Position, Velocity)用 struct。
当组件需复杂行为、继承或动态性时,并且需要存库时用 class(如 AIBehavior, Inventory)。

关于用struct还是class,各个框架有不同的实现

Entity 的实现类型

框架 Entity 类型 设计理由
Entitas class 简化 API 设计,支持面向对象模式(如事件回调),适合快速原型开发。
Arch struct 数据导向设计,内存连续存储,减少缓存未命中,适合高性能场景。

Component 的实现类型

框架 Component 类型 设计理由
Entitas class 面向对象特性,支持继承和事件回调。
Arch struct 数据驱动设计,内存连续存储,减少缓存未命中,适合高性能场景。

关于多线程

在写创建实体的代码时,突然想到一般的ECS框架是否会多线程调用?如果多线程调用,创建,销毁都要保证线程安全,这样太累了。

后来经过思考,创建与销毁不需要多线程调用,update可以多线程调用。在update时创建实体销毁实体等操作可存到无锁队列,在update结束后统一由主线程执行。Arch的CommandBuffer印证了我的想法。

帧同步游戏不能用多线程,由于线程间顺序不好控制,容易造成不同步。

最后编辑于2025年03月15日 00:44
返回顶部