Mizu is Entity Component System framework for Ebitengine.
Mizu is based on ento, which is made by wfranczyk.
The name is short for Mizutaki, a japenese dish, where chicken pieces and vegetables stewed in a simple stock, and eaten with dipping sauce such as ponzu.
- Very low boilerplate in exchange for a certain amount of reflection.
- Scene management.
- Compile defined components and entities.
To check all examples, visit this page.
Mizu uses Go 1.20 at the current moment.
Getting the latest version reflection API
:
go get -u github.com/sedyh/mizu
Getting the latest version generics API
:
go get -u github.com/sedyh/mizu@experimental
Import this package
import "github.com/sedyh/mizu/pkg/engine"
Define components, attributes of your game objects.
// Position for any entity, if it needs
type Pos struct {
X, Y float64 // Just a 2D point
}
// Velocity for any entity, if it needs
type Vel struct {
L, M float64 // Also, 2D point
}
// Radius for any entity, if it needs
type Rad struct {
Value float64 // Width value
}
Define entities, your game objects.
// Your game object
type Ball struct {
Pos // Ball position
Vel // Ball velocity
Rad // Ball radius
}
Define systems, your game mechanics that will work for a specific set of components.
// You can go through all entities that have a certain set of
// components specifying the requirements in the fields of the system
type Velocity struct {
*Pos // Current entity position
*Vel // Current entity velocity
}
// Apply velocity for each entity that has Pos and Vel
func (v *Velocity) Update(w engine.World) {
// If they are registered components, they will not be nil
v.Pos.X += v.Vel.L
v.Pos.Y += v.Vel.M
}
// When you need many sets of components
// in one system, you can use the views
type Render struct {}
// Render one frame
func (r *Render) Draw(w engine.World, screen *ebiten.Image) {
// But choose the right entities yourself
view := w.View(Pos{}, Rad{})
view.Each(func(entity engine.Entity) {
var pos *Pos
var rad *Rad
entity.Get(&pos, &rad)
ebitenutil.DrawRect(
screen,
pos.X-rad.Value/2, pos.Y-rad.Value/2,
rad.Value, rad.Value,
colornames.Aliceblue,
)
})
}
Define scenes, where will all this live.
type Game struct{}
// Main scene, you can use that for settings or main menu
func (g *Game) Setup(w engine.World) {
w.AddComponents(Pos{}, Vel{}, Rad{})
w.AddEntities(&Ball{Pos{0, 0}, Vel{4, 4}, Rad{10}})
w.AddSystems(&Velocity{}, &Render{})
}
Run the game.
// Provides its own ebiten.Game implementation
g := engine.NewGame(&Game{})
if err := ebiten.RunGame(g); err != nil {
log.Fatal(err)
}
Please visit our wiki for a helpful articles and best practices about Mizu.