/mizu

Entity Component System framework for Ebitengine

Primary LanguageGoOtherNOASSERTION

mizu Mizu

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.

Contents

Features

  • Very low boilerplate in exchange for a certain amount of reflection.
  • Scene management.
  • Compile defined components and entities.

Examples

To check all examples, visit this page.

Installation

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

Usage

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

Wiki

Please visit our wiki for a helpful articles and best practices about Mizu.