kongbong / ecsgo

Cache friendly, Multi threading Entity Component System in Go (with Generic)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ECSGo

ECSGo is an Entity Component System(ECS) in Go. This is made with Generic Go, so it needs Go 1.18 version

  • Cache friendly data storage
  • Run systems in concurrently with analyzing dependency tree.

Example

package main

import (
	"context"
	"log"
	"time"

	"github.com/kongbong/ecsgo"
)

type Position struct {
	X float32
	Y float32
}

type Velocity struct {
	X float32
	Y float32
}

type HP struct {
	Hp    float32
	MaxHp float32
}

type EnemyTag struct{}

func main() {
	registry := ecsgo.NewRegistry()

	sys1 := registry.AddSystem("VelocitySystem", 0, func(ctx *ecsgo.ExecutionContext) error {
		qr := ctx.GetQueryResult(0)
		log.Println("This system should have not any archtype", qr.GetArcheTypeCount())
		return nil
	})
	q1 := sys1.NewQuery()
	ecsgo.AddReadWriteComponent[Velocity](q1)
	ecsgo.AddExcludeComponent[EnemyTag](q1)

	o := registry.AddObserver("AddVelocityObserver", func(ctx *ecsgo.ObserverContext) error {
		vel := ecsgo.GetComponentObserver[Velocity](ctx)
		log.Println("This is one time called system", ctx.GetEntityId(), vel)
		return nil
	})
	ecsgo.AddComponentToObserver[Velocity](o)

	sys2 := registry.AddSystem("VelocitySystem2", 0, func(ctx *ecsgo.ExecutionContext) error {
		qr := ctx.GetQueryResult(0)
		qr.ForeachEntities(func(accessor *ecsgo.ArcheTypeAccessor) error {
			vel := ecsgo.GetComponentByAccessor[Velocity](accessor)
			log.Println("VelocitySystem2", accessor.GetEntityId(), vel)
			return nil
		})
		return nil
	})
	q2 := sys2.NewQuery()
	ecsgo.AddExcludeComponent[HP](q2)
	ecsgo.AddReadonlyComponent[Velocity](q2)

	sys3 := registry.AddSystem("PositionAndVelocity", 0, func(ctx *ecsgo.ExecutionContext) error {
		qr := ctx.GetQueryResult(0)
		qr.ForeachEntities(func(accessor *ecsgo.ArcheTypeAccessor) error {
			pos := ecsgo.GetComponentByAccessor[Position](accessor)
			vel := ecsgo.GetComponentByAccessor[Velocity](accessor)
			log.Println("Position, Velocity system", accessor.GetEntityId(), pos, vel, ctx.GetDeltaTime())
			pos.X++
			pos.Y++
			vel.X++
			vel.Y++
			return nil
		})
		return nil
	})
	q3 := sys3.NewQuery()
	ecsgo.AddReadWriteComponent[Position](q3)
	ecsgo.AddReadWriteComponent[Velocity](q3)
	ecsgo.AddReadonlyComponent[EnemyTag](q3)

	entity := registry.CreateEntity()
	ecsgo.AddComponent(registry, entity, Position{10, 10})
	ecsgo.AddComponent(registry, entity, Velocity{20, 20})
	ecsgo.AddComponent(registry, entity, EnemyTag{})

	ctx := context.Background()
	for i := 0; i < 10; i++ {
		registry.Tick(time.Second, ctx)
		time.Sleep(time.Second)
	}
}

About

Cache friendly, Multi threading Entity Component System in Go (with Generic)

License:MIT License


Languages

Language:Go 100.0%