braid

module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 21, 2024 License: MIT

README

Braid A Lightweight Actor Framework Simplifying Game Development

Braid is an innovative serverless game framework driven by the Actor model at its core. It achieves intelligent load management through a unified addressing system, allowing developers to focus on designing and implementing Actors without the need to concern themselves with complex distributed system components.

Go Report Card Demo Documentation Discord

image.png

中文

Features
  • Actor-Centric: The framework is essentially a collection of Actors, simplifying distributed logic.
  • Automatic Load Balancing: Intelligent resource allocation through the addressing system.
  • Development Focus: No need to consider underlying architecture like services or clusters; concentrate on game logic.
1. Quick Start

Install the scaffold project using the braid-cli tool

# 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"

# 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/services/demo-1
$ go run main.go
2. Create a new actor and load it into the cluster

Write node.yaml to register actor templates to nodes (containers)

actors:
- name: "USER"
    id : "user"
    unique: false
    weight: 100
    limit: 10000

Create actor constructors and bind them to the factory

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. Implement logic for the actor

Note: All handling functions (events, timers) registered in the actor are processed synchronously. Users do not need to concern themselves with asynchronous logic within the actor.

Bind event handler

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
        }
    }
})

Bind 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
})

Subscribe to messages and bind event handler

user.SubscriptionEvent("offline_messages", a.Id, func() {

    // After successful subscription, bind a handler function for the message
    a.RegisterEvent(events.EvChatMessageStore, events.MakeChatStoreMessage)
    
}, pubsub.WithTTL(time.Hour*24*30))

benchmark

Directories

Path Synopsis
3rd
mgo
lib
log
mpsc
Package mpsc provides an efficient implementation of a multi-producer, single-consumer lock-free queue.
Package mpsc provides an efficient implementation of a multi-producer, single-consumer lock-free queue.
msg
test
utils

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL