置顶
实现一个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印证了我的想法。
帧同步游戏不能用多线程,由于线程间顺序不好控制,容易造成不同步。