Braid 一个轻量级的 Actor 游戏开发框架
Braid 是一个以 Actor 模型为核心驱动的创新型无服务器游戏框架。它通过统一的寻址系统实现自动负载管理,使开发者能够专注于设计和实现,而无需关心复杂的分布式系统组件。
特性
- 以 Actor 为中心:框架本质上是 Actor 的集合,简化了分布式逻辑。
- 自动负载均衡:通过寻址系统实现自动资源分配。
- 专注开发:无需考虑服务或集群等底层架构,专注于游戏逻辑。
每个 actor 都代表了一个独立的计算单元,可以是游戏中的 chat, room, rank, mail, user 等等,通过注册在这个 actor 上的处理函数 和 引用的 状态,向外部提供服务,一个集群可以由任意个 节点,和注册在这个节点上的 actor 构成;在集群中 actor 之间可以相互进行访问(同步 & 异步
braid 本质上是提供了一个分布式计算基座,他能更好的适应未来的各种游戏架构(包括云游戏)
1. 快速开始
使用 braid-cli 工具安装脚手架项目, 一个最小可工作游戏服务器,作为您使用 Braid 的起点
# 1. Install CLI Tool
$ go install github.com/pojol/braid-cli@latest
# 2. Using the CLI to Generate a New Empty Project
$ braid-cli new "you-project-name" v0.1.7
# 3. Creating .go Files from Actor Template Configurations
$ cd you-project-name/template
$ go generate
# 4. Navigate to the services directory, then try to build and run the demo
$ cd you-project-name/node
$ go run main.go
2. 创建新的 actor 并将其加载到集群中
编写 node.yaml 将 actor 模板注册到节点(容器)中
actors:
- name: "USER"
id : "user"
unique: false
weight: 100
limit: 10000
将 actor 的构建函数绑定到 actor 工厂中
type userActor struct {
*actor.Runtime
state *Entity
}
func NewUserActor(p core.IActorBuilder) core.IActor {
return &httpAcceptorActor{
Runtime: &actor.Runtime{Id: p.GetID(), Ty: p.GetType(), Sys: p.GetSystem()},
state: user.NewEntity(p.GetID())
}
}
func (a *userActor) Init(ctx context.Context) {
a.Runtime.Init(ctx)
a.state.Load(ctx) // Load data from cache to local storage
}
// factory.go with node.yaml
case template.USER:
factory.bind("USER", v.Unique, v.Weight, v.Limit, NewUserActor)
3. 实现 actor 的逻辑
注意:在 actor 中注册的所有处理函数(事件、定时器)都是同步处理的,用户无需关心集群内部的异步逻辑。
绑定事件函数具柄
user.RegisterEvent("use_item", func(ctx core.ActorContext) *actor.DefaultChain {
// use middleware
unpackcfg := &middleware.MsgUnpackCfg[proto.xxx]{}
return &actor.DefaultChain{
Before: []Base.MiddlewareHandler{
middleware.MsgUnpack(unpackcfg),
},
Handler: func(ctx context.Context, msg *router.MsgWrapper) error {
realmsg, ok := unpackcfg.Msg.(*proto.xxx)
// todo ...
return nil
}
}
})
绑定 timer handler
user.RegisterTimer(0, 1000, func(ctx core.ActorContext) error {
state := ctx.GetValue(xxxStateKey{}).(*xxxState)
if state.State == Init {
// todo & state transitions
state.State = Running
} else if state.State == Running {
}
return nil
})
订阅消息(mq
user.SubscriptionEvent("topic", "channel", callback, pubsub.WithTTL(time.Hour*24*30))
4. 默认支持 jaeger 链路追踪
开启链路追踪 NodeWithTracer ,将会记录每个 actor 的调用路径(集群内,您可以通过根 ID #requestid 来追踪每个请求的调用过程
测试机器人
5. 通过测试机器人验证 braid 提供的服务器接口
使用上面的脚手架工程
$ cd you-project-name/testbots
# 1. 运行机器人服务器
$ go run main.go
# 2. 下载 gobot 编辑器(最新版本
https://github.com/pojol/gobot/releases
# 3. 运行 gobot 编辑器
$ run gobot_editor_[ver].exe or .dmg
# 4. 进入到 bots 页签
# 5. 将 testbots 目录中的 testbot.bh 文件拖拽到 bots 页面中
# 6. 选中 testbot 机器人,点击 load 加载 testbot
# 7. 点击左下角按钮,构建机器人实例
# 8. 点击单步运行按钮,查看机器人和 braid 服务器交互情形