finch-core

module
v0.0.10 Latest Latest
Warning

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

Go to latest
Published: Oct 9, 2025 License: Apache-2.0

README

Finch Core

The Finch Core module is the base for all other Finch modules. It provides a wrapper to configure and launch an Ebitengine application, along with other utilities used across the Finch ecosystem.

This core module is agnostic of all other Finch modules and should be considered the minimum entry point into a Finch application.

Usage

Quick Startup
package main

import (
	"github.com/adm87/finch-core/finch"
	"github.com/hajimehoshi/ebiten/v2"
	"github.com/hajimehoshi/ebiten/v2/ebitenutil"
)

func main() {
	f := finch.NewApp().
		WithWindow(&finch.Window{
			Title:        "Finch Test",
			ResizingMode: ebiten.WindowResizingModeDisabled,
			Width:        800,
			Height:       600,
			Fullscreen:   false,
			RenderScale:  1.0,
		}).
		WithStartup(startup).
		WithDraw(draw)

	if err := finch.Run(f); err != nil {
		panic(err)
	}
}

func startup(ctx finch.Context) {
	ctx.Logger().Info("Hello, Finch!")
}

func draw(ctx finch.Context, screen *ebiten.Image) {
	ebitenutil.DebugPrint(screen, "Hello, Finch!")
}
Assets
Loading

The goal is to make loading and accessing game assets simple and straight forward. A finch.AssetFile provides a handle for loading, unload, and accessing asset data.

package main

import (
	...

	"github.com/adm87/finch-core/finch"
	"github.com/adm87/finch-core/images"
)

var myAwesomePng = finch.AssetFile("absolute/path/to/assets/image.png")

func main() {
	images.RegisterAssetManager()

	...

	if err := myAwesomePng.Load(); err != nil {
		panic(err)
	}

	// OR

	myAwesomePng.MustLoad()

	// OR

	if err := finch.LoadAssets(myAwesomePng); err != nil {
		panic(err)
	}

	// OR

	finch.MustLoadAssets(myAwesomePng)
}

Finch's asset management also provides a mechanism for registering fs.FS filesystem implementations. This provides a custom solution for reading asset data from user defined locations.

package main

import (
	"os"

	...

	"github.com/adm87/finch-core/finch"
)
var assets = AssetRoot("assets")

func main() {
	finch.RegisterAssetFilesystem(assets, os.DirFS("absolute/path/to/assets"))

	...
}

Here, AssetRoot("assets") defines the root directory for a custom filesystem. Since this example is creating a filesystem for a local disk location, absolute/path/to/assets is the absolute path where that filesystem starts. This allows the AssetFile() paths to be relative to the filesystem they belong to.

var myAwesomePng = finch.AssetFile("assets/image.png")

When Finch attempts to load the AssetFile, is will check the top level directory to see if a filesystem has been registered for it. If so, it will use that filesystem with the relative path of the AssetFile to load the asset. This can be useful if assets are located on a remote server. Implement a custom fs.FS that knows how to connect to and read from the server, and register it to the root of that filesystem.

Note: If Finch doesn't find a registered filesystem, it will attempt to use the path of the AssetFile to load from disk.

Accessing

After an AssetFile has been loaded, you can use it to get the untyped data associated with it. The data will need to be type casted to the expected type.

func draw(ctx finch.Context, screen *ebiten.Image) {
	img, err := myAwesomePng.Get()
	if err != nil {
		panic(err)
	}
	screen.DrawImage(img.(*ebiten.Image), nil
	
	// OR

	screen.DrawImage(myAwesomePng.MustGet().(*ebiten.Image), nil)

	// OR

	img, err := images.Get(myAwesomePng)
	if err != nil {
		panic(err)
	}
	screen.DrawImage(img, nil)

	// OR

	screen.DrawImage(images.MustGet(myAwesomePng), nil)
}
Custom Asset Types

Finch comes with built-in asset managers for loading asset types common to the Ebitengine. To use them simply call their RegisterAssetManager() methods. Or, you can build your own asset manager and have Finch use that instead.

A custom asset manager provides users a way to manage how loaded data is allocated and deallocated within Finch's asset framework.

package images

import (
	"bytes"
	"errors"

	"github.com/adm87/finch-core/finch"
	"github.com/hajimehoshi/ebiten/v2"
	"github.com/hajimehoshi/ebiten/v2/ebitenutil"
)

func RegisterAssetManager() {
	finch.RegisterAssetManager(&finch.AssetManager{
		Types:       []finch.AssetType{"png", "jpg", "jpeg", "bmp"},
		Allocator:   allocator,
		Deallocator: deallocator,
	})
}

func Get(file finch.AssetFile) (*ebiten.Image, error) {
	img, err := finch.GetAsset[*ebiten.Image](file)
	if err != nil {
		return nil, err
	}
	return img, nil
}

func MustGet(file finch.AssetFile) *ebiten.Image {
	return finch.MustGetAsset[*ebiten.Image](file)
}

func allocator(data []byte) (any, error) {
	img, _, err := ebitenutil.NewImageFromReader(bytes.NewReader(data))
	if err != nil {
		return nil, err
	}
	return img, nil
}

func deallocator(asset any) error {
	img, ok := asset.(*ebiten.Image)
	if !ok {
		return errors.New("asset is not an *ebiten.Image")
	}
	img.Deallocate()
	return nil
}

This is Finch's built-in image asset manager. It tells Finch how to allocate and deallocate files with the extension png, jpg, jpeg, and bmp. This package also provides some convenient accessor methods for returning typed data.

Note: Only one asset manager per file extension is supported. If you would rather manage images yourself, create a custom asset manager and don't bother calling Finch's images' RegisterAssetManager() method.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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