willow

package module
v0.2.2 Latest Latest
Warning

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

Go to latest
Published: Mar 24, 2026 License: MIT Imports: 18 Imported by: 0

README

Willow

Go Reference Go Report Card

A display-tree 2D rendering layer for Ebitengine, including scene management, batching, cameras, culling, hit detection, and special effects. Inspired by Starling, Flash display lists, and PixiJS, adapted for Go's strengths.

Status: Functional and actively developed. Core systems are working and used across all included examples. API may change before v1.0.0.

Shapes Watermesh Particles

New here? Check out the Willow website for tutorials, examples, and everything you need to start building with Willow.


What is Willow?

Willow is a 2D rendering framework built on Ebitengine. Ebitengine is immediate-mode - every frame you must issue every draw command from scratch, and nothing persists between frames. Willow adds a retained-mode-inspired layer on top: you create a tree of nodes representing your game objects, and Willow traverses that tree each frame to produce draw commands for Ebitengine. You describe what exists in your scene, not how to render it each frame. This is the same pattern used by engines like Unity, Godot, and PixiJS: a persistent scene graph (display tree) driving an immediate-mode renderer.

A main focus of Willow is performance, designed to minimize heap allocations and maximize batching, with features like subtree command caching for static content, and a zero-allocation-per-frame contract on the hot path. While managing the display tree does have a slight runtime cost, in some instances Willow can be faster than raw Ebitengine due to better batching and caching strategies.

It sits between Ebitengine and your game:

Your Game             - gameplay, content, logic
Willow                - scene graph, rendering, interaction
Ebitengine            - GPU backend, window, audio, platform

Why does Willow exist?

Ebitengine is an excellent, minimal 2D engine for Go, but every project beyond a prototype ends up building the same infrastructure from scratch: transform hierarchies, batching, hit testing, camera viewports, text rendering, sprite atlases.

Willow exists so you don't have to rebuild that foundation every time.

Ebitengine is intentionally low-level, that's its strength. Willow is a higher-level framework on top of it, so you can focus on gameplay instead of rendering infrastructure.

Inspired by Starling, Flash display lists, and PixiJS, scene graph architectures that powered millions of 2D games, adapted for Go's strengths: simplicity and performance.


What Willow Is Not

  • Not a full game engine. No built-in physics, networking, or asset pipelines
  • Not a UI layout framework (a companion willowui library is planned)
  • Not a replacement for Ebitengine. It builds on top of it

Willow focuses on structured rendering and scene composition. You bring the gameplay and domain logic.


Goals

  1. Structure without handcuffs. Willow provides hierarchy, transforms, and batching without imposing game/app architecture. Any genre, any pattern, any scale.
  2. Performance as a contract. Zero heap allocations per frame on the hot path. 10,000 moving sprites at 120+ FPS on desktop, 60+ FPS on mobile and web. Verified with compiler escape analysis and benchmark suites.
  3. Wrap Ebitengine, never fight it. Willow uses Ebitengine's lifecycle hooks, image types, and threading model directly.
  4. Cross Platform. Windows, macOS, Linux, iOS, Android, WebAssembly, and wherever Ebitengine runs.

Use Cases

Willow is well suited for:

  • 2D games requiring structured layering and scene composition
  • Games with worlds with large tile maps, cameras, and movement
  • Game tooling and level editors built on a display tree
  • Rapidly prototyping game ideas with minimal boilerplate on top of Ebitengine
  • A foundation for porting over Flash, Adobe AIR, Starling, Pixi.js, or other games to a new and exciting Go/Ebiten ecosystem!

Quick start

go get github.com/devthicket/willow@latest

For quick setup, call willow.Run(scene, config) and Willow handles the window and game loop. For full control, implement ebiten.Game yourself and call scene.Update() and scene.Draw(screen) directly - both paths are first-class.

package main

import (
	"log"

	"github.com/devthicket/willow"
)

func main() {
	scene := willow.NewScene()

	sprite := willow.NewSprite("hero", willow.TextureRegion{})
	sprite.SetSize(40, 40)
	sprite.SetColor(willow.RGBA(0.3, 0.7, 1, 1))
	sprite.SetPosition(300, 220)
	scene.Root().AddChild(sprite)

	if err := willow.Run(scene, willow.RunConfig{
		Title:  "My Game",
		Width:  640,
		Height: 480,
	}); err != nil {
		log.Fatal(err)
	}
}

Examples

20+ runnable examples are included in the willow-examples repository, covering everything from basic sprites to full scenes combining lighting, meshes, particles, and masks. Several are also available as live WASM demos to play directly in your browser.

git clone https://github.com/devthicket/willow-examples.git
cd willow-examples
go run ./examples/basic    # simplest possible Willow app
go run ./examples/shapes   # parent/child transforms
go run ./examples/lighting # dungeon scene with torches and wisps

Documentation


Features

  • Scene graph - (also known as a Display Tree) Parent/child transform inheritance (position, rotation, scale, skew, pivot) with alpha propagation and Pixi-style ZIndex sibling reordering. Tree search by name with FindChild/FindDescendant (supports % wildcards).
  • Sprite batching - TexturePacker JSON atlas loading with multi-page, trimmed, and rotated region support. Consecutive draws are grouped automatically into single DrawImage calls.
  • Camera system - Multiple independent viewports with smooth follow, scroll-to animation (45+ easings), bounds clamping, frustum culling, and world/screen coordinate conversion.
  • Input and interaction - Hierarchical hit testing with pluggable shapes (rect, circle, polygon). Pointer capture, drag dead zones, multi-touch, and two-finger pinch with rotation. Callbacks per-node or scene-wide.
  • Text rendering - Two font systems: DistanceFieldFont (SDF) for TTF/OTF with resolution-independent scaling, GPU-accelerated outlines, shadows, and glow; PixelFont (Bitmap) for pixel-perfect bitmap spritesheet fonts with integer-only scaling (1x, 2x, 3x) and cell trimming. Both support alignment, word wrapping, and line height overrides. Offline fontgen CLI to pre-bake SDF atlases, or generate at runtime.
  • Particle system - CPU-simulated with preallocated pools. Configurable emit rate, lifetime, speed, gravity, and scale/alpha/color interpolation. Optional world-space emission.
  • Mesh support - DrawTriangles with preallocated vertex and index buffers. High-level helpers for rope meshes, filled polygons, and deformable grids.
  • Subtree command caching - SetCacheAsTree caches all render commands for a container's subtree and replays them with delta transform remapping. Camera panning, parent movement, and alpha changes never invalidate the cache. Animated tiles (same-page UV swaps) are handled automatically via a two-tier source pointer - no invalidation, no API overhead. Manual and auto-invalidation modes. Includes sort-skip optimization when the entire scene is cache hits.
  • Filters and effects - Composable filter chains via Kage shaders. Built-in: color matrix, blur, outline, pixel-perfect outline, pixel-perfect inline, palette swap. Render-target masking and CacheAsTexture.
  • Lighting - Dedicated lighting layer using erase-blend render targets with automatic compositing.
  • Node index - Opt-in NodeIndex registry for tag-based grouping and O(1) lookups by name or tag. Supports % wildcards, multi-tag intersection queries, and zero-allocation iteration. No overhead for nodes that aren't indexed.
  • Animation - Tweening via gween with 45+ easing functions re-exported as willow.Ease* for autocomplete discoverability. Convenience wrappers for position, scale, rotation, alpha, and color. Auto-stops on node disposal.
  • Debug mode - Performance timers, batch counting, tree depth warnings, and disposed-node assertions via scene.SetDebugMode(true).

Performance

Willow is designed around a zero-allocation-per-frame contract on the hot path:

  • Preallocated command buffer reused each frame
  • Dirty flag propagation - static subtrees skip transform recomputation entirely
  • Custom merge sort with preallocated scratch buffer (no sort.SliceStable allocations)
  • Typed callback slices - no interface{} boxing in event dispatch
  • Render-texture pooling by power-of-two size buckets
  • Value-type DrawImageOptions declared once, reused per iteration

Subtree command caching (SetCacheAsTree) avoids re-traversing static subtrees entirely. Commands are stored at cache time and replayed with a single matrix multiply per command. Camera movement, parent transforms, and alpha changes are handled via delta remapping. Animated tiles (UV swaps within the same atlas page) are handled automatically via a two-tier source pointer indirection - no invalidation, no API overhead. This is designed to allow batch group of tilemaps with animated tiles (e.g. water) to be performance-optimized by avoiding full subtree invalidation on every frame.

Scenario (10K sprites) Time vs uncached
Manual cache, camera scrolling ~39 μs ~125x faster
Manual cache, 100 animated tile UV swaps ~1.97 ms ~2.5x faster
Auto cache, 1% of children moving ~4.0 ms ~1.2x faster
No cache (baseline) ~4.9 ms -

The cache is per-container, and will be invalidated if a child within the container moves. It is recommended to separate static content (tilemaps, UI panels) from dynamic content (players, projectiles) into different containers for best results.

Benchmark suite included: go test -bench . -benchmem


Roadmap

  • UI widget layer (buttons, text input, layout, focus traversal) as a separate companion library (willowui)
  • Example projects and starter templates
  • Comprehensive API documentation and guides
  • Tutorials and integration walkthroughs
  • Performance profiling across mobile and WebAssembly targets
  • Community feedback and API stabilization

Built with

  • Go 1.24+
  • Ebitengine v2.9+
  • Currently tested on: macOS and WebAssembly

Contributing

Contributions are welcome. Please a pull request and ensure tests pass. For major changes, open an issue first to discuss the design and implementation.


License

MIT - see LICENSE for details.

Documentation

Overview

Package willow is a display-tree 2D rendering layer for Ebitengine, including scene management, batching, cameras, culling, hit detection, and special effects. Inspired by Starling, Flash display lists, and PixiJS, adapted for Go's strengths.

Ebitengine is immediate-mode: every frame you issue draw commands from scratch, and nothing persists. Willow adds a retained-mode-inspired layer on top - you create a tree of nodes representing your game objects, and Willow traverses that tree each frame to produce draw commands for Ebitengine. You describe what exists in your scene, not how to render it each frame. This is the same pattern used by engines like Unity, Godot, and PixiJS: a persistent scene graph (display tree) driving an immediate-mode renderer.

It sits between Ebitengine and your game:

Your Game             - gameplay, content, logic
Willow                - scene graph, rendering, interaction
Ebitengine            - GPU backend, window, audio, platform

Full documentation, tutorials, and examples are available at:

https://www.devthicket.org/willow

Quick start

The simplest way to get started is Run, which creates a window and game loop for you:

scene := willow.NewScene()
// ... add nodes ...
willow.Run(scene, willow.RunConfig{
	Title: "My Game", Width: 640, Height: 480,
})

For full control, implement ebiten.Game yourself and call [Scene.Update] and [Scene.Draw] directly:

type Game struct{ scene *willow.Scene }

func (g *Game) Update() error         { g.Scene_.Update(); return nil }
func (g *Game) Draw(s *ebiten.Image)  { g.Scene_.Draw(s) }
func (g *Game) Layout(w, h int) (int, int) { return w, h }

Scene graph

Every visual element is a Node. Nodes form a tree rooted at [Scene.Root]. Children inherit their parent's transform and alpha.

Create nodes with typed constructors: NewContainer, NewSprite, NewText, NewParticleEmitter, NewMesh, NewPolygon, and others.

container := willow.NewContainer("ui")
scene.Root().AddChild(container)

sprite := willow.NewSprite("hero", atlas.Region("hero_idle"))
sprite.SetPosition(100, 50)
container.AddChild(sprite)

For solid-color rectangles, use NewSprite with a zero-value TextureRegion and set color and size:

box := willow.NewSprite("box", willow.TextureRegion{})
box.SetSize(80, 40)
box.SetColor(willow.RGBA(0.3, 0.7, 1, 1))

Finding nodes

For quick tree searches, use [Node.FindChild] (direct children) or [Node.FindDescendant] (recursive depth-first). Both support % wildcards:

bar := enemy.FindChild("health_bar")
boss := scene.Root().FindDescendant("boss%")  // starts with "boss"

For repeated lookups or tag-based grouping, use NodeIndex:

idx := willow.NewNodeIndex()
idx.Add(enemy, "enemy", "damageable")
enemies := idx.FindByTag("enemy")
boss := idx.FindByName("boss%")

Key features

Willow includes cameras with follow/scroll-to/zoom, two text systems (SDF-based [DistanceFieldFont] for smooth TTF/OTF scaling with outlines, glows, and shadows; pixel-perfect [PixelFont] for bitmap spritesheet fonts with integer-only scaling), CPU-simulated particles, mesh/polygon/rope geometry, Kage shader filters, texture caching, masking, blend modes, lighting layers, and tweens (via gween).

All 45 gween easing functions are re-exported as EaseLinear, EaseOutCubic, EaseOutBounce, etc. for autocomplete discoverability without an extra import.

See the full docs for guides on each feature: https://www.devthicket.org/willow

Index

Constants

View Source
const (
	TileFlipH    = tilemap.TileFlipH    // Horizontal flip (bit 31)
	TileFlipV    = tilemap.TileFlipV    // Vertical flip (bit 30)
	TileFlipD    = tilemap.TileFlipD    // Diagonal flip (bit 29)
	TileFlagMask = tilemap.TileFlagMask // All three flags combined
)

Tile GID flip flags (same convention as Tiled TMX format).

View Source
const (
	BlendNormal   = types.BlendNormal
	BlendAdd      = types.BlendAdd
	BlendMultiply = types.BlendMultiply
	BlendScreen   = types.BlendScreen
	BlendErase    = types.BlendErase
	BlendMask     = types.BlendMask
	BlendBelow    = types.BlendBelow
	BlendNone     = types.BlendNone
)

Blend modes.

View Source
const (
	NodeTypeContainer       = types.NodeTypeContainer
	NodeTypeSprite          = types.NodeTypeSprite
	NodeTypeMesh            = types.NodeTypeMesh
	NodeTypeParticleEmitter = types.NodeTypeParticleEmitter
	NodeTypeText            = types.NodeTypeText
)

Node types.

View Source
const (
	EventPointerDown  = types.EventPointerDown
	EventPointerUp    = types.EventPointerUp
	EventPointerMove  = types.EventPointerMove
	EventClick        = types.EventClick
	EventDragStart    = types.EventDragStart
	EventDrag         = types.EventDrag
	EventDragEnd      = types.EventDragEnd
	EventPinch        = types.EventPinch
	EventPointerEnter = types.EventPointerEnter
	EventPointerLeave = types.EventPointerLeave
)

Event types.

View Source
const (
	MouseButtonLeft   = types.MouseButtonLeft
	MouseButtonRight  = types.MouseButtonRight
	MouseButtonMiddle = types.MouseButtonMiddle
)

Mouse buttons.

View Source
const (
	ModShift = types.ModShift
	ModCtrl  = types.ModCtrl
	ModAlt   = types.ModAlt
	ModMeta  = types.ModMeta
)

Modifier keys.

View Source
const (
	TextAlignLeft   = types.TextAlignLeft
	TextAlignCenter = types.TextAlignCenter
	TextAlignRight  = types.TextAlignRight
)

Text alignment.

View Source
const (
	CacheTreeManual = types.CacheTreeManual
	CacheTreeAuto   = types.CacheTreeAuto
)

Cache tree modes.

View Source
const (
	BatchModeCoalesced = render.BatchModeCoalesced
	BatchModeImmediate = render.BatchModeImmediate
)

Batch modes.

View Source
const (
	CommandSprite     = render.CommandSprite
	CommandMesh       = render.CommandMesh
	CommandParticle   = render.CommandParticle
	CommandTilemap    = render.CommandTilemap
	CommandSDF        = render.CommandSDF
	CommandBitmapText = render.CommandBitmapText
)

Command types.

View Source
const (
	RopeJoinMiter = mesh.RopeJoinMiter
	RopeJoinBevel = mesh.RopeJoinBevel
)

Rope join modes.

View Source
const (
	RopeCurveLine        = mesh.RopeCurveLine
	RopeCurveCatenary    = mesh.RopeCurveCatenary
	RopeCurveQuadBezier  = mesh.RopeCurveQuadBezier
	RopeCurveCubicBezier = mesh.RopeCurveCubicBezier
	RopeCurveWave        = mesh.RopeCurveWave
	RopeCurveCustom      = mesh.RopeCurveCustom
)

Rope curve modes.

View Source
const (
	FontStyleRegular    = text.FontStyleRegular
	FontStyleBold       = text.FontStyleBold
	FontStyleItalic     = text.FontStyleItalic
	FontStyleBoldItalic = text.FontStyleBoldItalic
)

Font style constants.

Variables

View Source
var (
	RGB              = types.RGB
	ColorFromRGBA    = types.ColorFromRGBA
	ColorFromHSV     = types.ColorFromHSV
	ColorWhite       = types.ColorWhite
	ColorBlack       = types.ColorBlack
	ColorTransparent = types.ColorTransparent
)

Color constructors and constants.

View Source
var (
	NewAtlas      = atlas.New
	NewBatchAtlas = atlas.NewBatch
	LoadAtlas     = atlas.LoadAtlas
)

Atlas constructors.

View Source
var (
	NewColorMatrixFilter         = filter.NewColorMatrixFilter
	NewBlurFilter                = filter.NewBlurFilter
	NewOutlineFilter             = filter.NewOutlineFilter
	NewPixelPerfectOutlineFilter = filter.NewPixelPerfectOutlineFilter
	NewPixelPerfectInlineFilter  = filter.NewPixelPerfectInlineFilter
	NewPaletteFilter             = filter.NewPaletteFilter
	NewCustomShaderFilter        = filter.NewCustomShaderFilter
)

Filter constructors.

View Source
var (
	NewRope            = mesh.NewRope
	NewDistortionGrid  = mesh.NewDistortionGrid
	NewPolygon         = mesh.NewPolygon
	NewRegularPolygon  = mesh.NewRegularPolygon
	NewStar            = mesh.NewStar
	NewPolygonTextured = mesh.NewPolygonTextured
	SetPolygonPoints   = mesh.SetPolygonPoints
)

Mesh constructors.

View Source
var (
	DistanceBetween  = node.DistanceBetween
	DirectionBetween = node.DirectionBetween
)

Spatial queries.

View Source
var (
	TweenPosition = core.TweenPosition
	TweenScale    = core.TweenScale
	TweenColor    = core.TweenColor
	TweenAlpha    = core.TweenAlpha
	TweenRotation = core.TweenRotation
)

Tweens.

View Source
var (
	NewSceneManager   = core.NewSceneManager
	NewFadeTransition = core.NewFadeTransition
)

Scene manager.

View Source
var DefaultFXAAConfig = render.DefaultFXAAConfig

DefaultFXAAConfig returns an FXAAConfig with FXAA 3.11 quality-15 defaults.

View Source
var EncodeGID = tilemap.EncodeGID

EncodeGID combines a tile ID with flip flags into a single uint32 GID.

View Source
var GenerateSDFFromBitmaps = text.GenerateSDFFromBitmaps

GenerateSDFFromBitmaps creates an SDF atlas from pre-rasterized glyph bitmaps (used by fontgen CLI).

View Source
var GofontBundle []byte

GofontBundle is the pre-baked .fontbundle for the Go Regular font family. Pass it to NewFontFamilyFromFontBundle to get a ready-to-use FontFamily.

font, err := willow.NewFontFamilyFromFontBundle(willow.GofontBundle)
View Source
var LoadTestScript = core.LoadTestScript

Test runner.

View Source
var NewAnimationPlayer = node.NewAnimationPlayer

Animation player.

View Source
var NewLightLayer = lighting.NewLightLayer

Lighting.

View Source
var NewNodeIndex = node.NewNodeIndex

Node index.

View Source
var NewRenderTexture = render.NewRenderTexture

Render.

View Source
var RegionsFromGrid = tilemap.RegionsFromGrid

RegionsFromGrid builds a TextureRegion slice from a regular grid tileset. Index 0 is a zero region (empty tile); indices 1..count map to tiles in row-major order. Margin is the outer border; spacing is the gap between tiles.

View Source
var ToTexture = core.ToTexture

Render to texture.

View Source
var WhitePixel *ebiten.Image

WhitePixel is a 1x1 white image used by default for solid color sprites.

Functions

func Run

func Run(scene *Scene, cfg RunConfig) error

Run is a convenience entry point that creates an Ebitengine game loop around the given Scene.

func RunWithManager

func RunWithManager(sm *SceneManager, cfg RunConfig) error

RunWithManager is a convenience entry point that runs a SceneManager.

Types

type AnimFrame

type AnimFrame = tilemap.AnimFrame

AnimFrame describes a single frame in a tile animation sequence.

type AnimationPlayer

type AnimationPlayer = node.AnimationPlayer

AnimationPlayer manages multiple named animation sequences on a node.

type AnimationSequence

type AnimationSequence = node.AnimationSequence

AnimationSequence defines a single named animation.

type Atlas

type Atlas = atlas.Atlas

Atlas holds one or more atlas page images and a map of named regions.

func LoadSceneAtlas

func LoadSceneAtlas(s *Scene, jsonData []byte, pages []*ebiten.Image) (*Atlas, error)

LoadSceneAtlas parses TexturePacker JSON, registers atlas pages with the scene, and returns the Atlas for region lookups.

type AtlasEntry

type AtlasEntry = text.AtlasEntry

AtlasEntry holds the raw PNG and JSON bytes for one baked font atlas.

type BatchMode

type BatchMode = render.BatchMode

BatchMode controls how the render pipeline submits draw calls.

type BlendMode

type BlendMode = types.BlendMode

BlendMode selects a compositing operation.

type BlurFilter

type BlurFilter = filter.BlurFilter

BlurFilter applies a Kawase iterative blur.

type CacheTreeMode

type CacheTreeMode = types.CacheTreeMode

CacheTreeMode controls how a cached subtree invalidates.

type CallbackHandle

type CallbackHandle = input.CallbackHandle

CallbackHandle allows removing a registered scene-level callback.

type Camera

type Camera = camera.Camera

Camera controls the view into the scene: position, zoom, rotation, viewport.

func Cameras

func Cameras(s *Scene) []*Camera

Cameras returns the scene's camera list.

func NewCamera

func NewCamera(viewport Rect) *Camera

NewCamera creates a standalone camera with the given viewport.

type ClickContext

type ClickContext = node.ClickContext

ClickContext carries click event data.

type Color

type Color = types.Color

Color represents an RGBA color with components in [0, 1].

func RGBA

func RGBA(r, g, b, a float64) Color

RGBA creates a Color from red, green, blue, alpha components in [0, 1].

type ColorMatrixFilter

type ColorMatrixFilter = filter.ColorMatrixFilter

ColorMatrixFilter applies a 4x5 color matrix transformation.

type CommandType

type CommandType = render.CommandType

CommandType identifies the kind of render command.

type CustomShaderFilter

type CustomShaderFilter = filter.CustomShaderFilter

CustomShaderFilter wraps a user-provided Kage shader.

type DistortionGrid

type DistortionGrid = mesh.DistortionGrid

DistortionGrid provides a grid mesh that can be deformed per-vertex.

type DragContext

type DragContext = node.DragContext

DragContext carries drag event data.

type EaseFunc

type EaseFunc = ease.TweenFunc

EaseFunc is the signature for easing functions used by TweenConfig.

var (
	EaseLinear       EaseFunc = ease.Linear
	EaseInQuad       EaseFunc = ease.InQuad
	EaseOutQuad      EaseFunc = ease.OutQuad
	EaseInOutQuad    EaseFunc = ease.InOutQuad
	EaseOutInQuad    EaseFunc = ease.OutInQuad
	EaseInCubic      EaseFunc = ease.InCubic
	EaseOutCubic     EaseFunc = ease.OutCubic
	EaseInOutCubic   EaseFunc = ease.InOutCubic
	EaseOutInCubic   EaseFunc = ease.OutInCubic
	EaseInQuart      EaseFunc = ease.InQuart
	EaseOutQuart     EaseFunc = ease.OutQuart
	EaseInOutQuart   EaseFunc = ease.InOutQuart
	EaseOutInQuart   EaseFunc = ease.OutInQuart
	EaseInQuint      EaseFunc = ease.InQuint
	EaseOutQuint     EaseFunc = ease.OutQuint
	EaseInOutQuint   EaseFunc = ease.InOutQuint
	EaseOutInQuint   EaseFunc = ease.OutInQuint
	EaseInSine       EaseFunc = ease.InSine
	EaseOutSine      EaseFunc = ease.OutSine
	EaseInOutSine    EaseFunc = ease.InOutSine
	EaseOutInSine    EaseFunc = ease.OutInSine
	EaseInExpo       EaseFunc = ease.InExpo
	EaseOutExpo      EaseFunc = ease.OutExpo
	EaseInOutExpo    EaseFunc = ease.InOutExpo
	EaseOutInExpo    EaseFunc = ease.OutInExpo
	EaseInCirc       EaseFunc = ease.InCirc
	EaseOutCirc      EaseFunc = ease.OutCirc
	EaseInOutCirc    EaseFunc = ease.InOutCirc
	EaseOutInCirc    EaseFunc = ease.OutInCirc
	EaseInElastic    EaseFunc = ease.InElastic
	EaseOutElastic   EaseFunc = ease.OutElastic
	EaseInOutElastic EaseFunc = ease.InOutElastic
	EaseOutInElastic EaseFunc = ease.OutInElastic
	EaseInBack       EaseFunc = ease.InBack
	EaseOutBack      EaseFunc = ease.OutBack
	EaseInOutBack    EaseFunc = ease.InOutBack
	EaseOutInBack    EaseFunc = ease.OutInBack
	EaseInBounce     EaseFunc = ease.InBounce
	EaseOutBounce    EaseFunc = ease.OutBounce
	EaseInOutBounce  EaseFunc = ease.InOutBounce
	EaseOutInBounce  EaseFunc = ease.OutInBounce
)

type EmitterConfig

type EmitterConfig = particle.EmitterConfig

EmitterConfig controls how particles are spawned and behave.

type EntityStore

type EntityStore = core.EntityStore

EntityStore is the interface for optional ECS integration.

type EventType

type EventType = types.EventType

EventType identifies a kind of interaction event.

type FXAAConfig

type FXAAConfig = render.FXAAConfig

FXAAConfig holds tunable parameters for the FXAA post-process pass. Use DefaultFXAAConfig for sensible defaults.

type FadeTransition

type FadeTransition = core.FadeTransition

FadeTransition fades through a solid color between scene changes.

type Filter

type Filter = filter.Filter

Filter is the interface for visual effects applied to a node.

type FontFamily

type FontFamily = text.FontFamily

FontFamily holds SDF atlases for multiple styles and bake sizes, or wraps a pixel font. It is the only public font type in willow.

func NewFontFamilyFromFontBundle

func NewFontFamilyFromFontBundle(data []byte) (*FontFamily, error)

NewFontFamilyFromFontBundle loads a pre-baked .fontbundle archive and returns a FontFamily.

func NewFontFamilyFromPixelFont

func NewFontFamilyFromPixelFont(img *ebiten.Image, cellW, cellH int, chars string) *FontFamily

NewFontFamilyFromPixelFont wraps a pixel spritesheet into a FontFamily.

func NewFontFamilyFromTTF

func NewFontFamilyFromTTF(cfg FontFamilyConfig) (*FontFamily, error)

NewFontFamilyFromTTF creates a FontFamily from TTF/OTF data. All style variants are provided in the config struct. BakeSizes defaults to [64, 256].

type FontFamilyConfig

type FontFamilyConfig = text.FontFamilyConfig

FontFamilyConfig configures a FontFamily created from TTF/OTF data.

type FontStyle

type FontStyle = text.FontStyle

FontStyle identifies a typographic style variant.

type GifConfig added in v0.2.2

type GifConfig = core.GifConfig

GifConfig controls GIF recording behaviour.

type Glyph

type Glyph = text.Glyph

Glyph holds glyph metrics and atlas position.

type GlyphBitmap

type GlyphBitmap = text.GlyphBitmap

GlyphBitmap holds a rasterized glyph and its metrics for atlas packing (used by fontgen CLI).

type HitCircle

type HitCircle = input.HitCircle

HitCircle is a circular hit area in local coordinates.

type HitPolygon

type HitPolygon = input.HitPolygon

HitPolygon is a convex polygon hit area in local coordinates.

type HitRect

type HitRect = input.HitRect

HitRect is an axis-aligned rectangular hit area in local coordinates.

type HitShape

type HitShape = types.HitShape

HitShape is implemented by custom hit-test shapes attached to a Node.

type InteractionEvent

type InteractionEvent = core.InteractionEvent

InteractionEvent carries interaction data for the ECS bridge.

type KeyModifiers

type KeyModifiers = types.KeyModifiers

KeyModifiers is a bitmask of keyboard modifier keys.

type Light

type Light = lighting.Light

Light represents a light source in a LightLayer.

type LightLayer

type LightLayer = lighting.LightLayer

LightLayer provides a convenient 2D lighting effect using erase blending.

type MouseButton

type MouseButton = types.MouseButton

MouseButton identifies a mouse button.

type Node

type Node = node.Node

Node is the fundamental scene graph element.

func NewCircle

func NewCircle(name string, radius float64, c Color) *Node

NewCircle creates a solid-color circle node with the given radius. The circle is approximated with 32 segments.

func NewContainer

func NewContainer(name string) *Node

NewContainer creates a container node with no visual representation.

func NewLine

func NewLine(name string, x1, y1, x2, y2, thickness float64, c Color) *Node

NewLine creates a solid-color line node between two points with a given thickness. The line is built as a thin rotated rectangle sprite for efficient batching.

func NewMesh

func NewMesh(name string, img *ebiten.Image, vertices []ebiten.Vertex, indices []uint16) *Node

NewMesh creates a mesh node that uses DrawTriangles for rendering.

func NewParticleEmitter

func NewParticleEmitter(name string, cfg EmitterConfig) *Node

NewParticleEmitter creates a particle emitter node with a preallocated pool.

func NewRect

func NewRect(name string, w, h float64, c Color) *Node

NewRect creates a solid-color rectangle node.

func NewSprite

func NewSprite(name string, region TextureRegion) *Node

NewSprite creates a sprite node that renders a texture region.

func NewText

func NewText(name string, content string, font *FontFamily) *Node

NewText creates a text node that renders the given string using font.

func NewTriangle

func NewTriangle(name string, p1, p2, p3 Vec2, c Color) *Node

NewTriangle creates a solid-color triangle node from three points.

func Root

func Root(s *Scene) *Node

Root returns the scene's root container node.

type NodeIndex

type NodeIndex = node.NodeIndex

NodeIndex is an opt-in registry for looking up nodes by name or tag.

type NodeType

type NodeType = types.NodeType

NodeType distinguishes rendering behavior for a Node.

type OutlineFilter

type OutlineFilter = filter.OutlineFilter

OutlineFilter draws a multi-pixel outline around the source.

type PackerConfig

type PackerConfig = atlas.PackerConfig

PackerConfig controls the dynamic atlas packer.

type PaletteFilter

type PaletteFilter = filter.PaletteFilter

PaletteFilter remaps pixel colors through a palette based on luminance.

type ParticleEmitter

type ParticleEmitter = particle.Emitter

ParticleEmitter manages a pool of particles with CPU-based simulation.

type PinchContext

type PinchContext = node.PinchContext

PinchContext carries two-finger pinch/rotate gesture data.

type PixelPerfectInlineFilter

type PixelPerfectInlineFilter = filter.PixelPerfectInlineFilter

PixelPerfectInlineFilter recolors edge pixels via Kage shader.

type PixelPerfectOutlineFilter

type PixelPerfectOutlineFilter = filter.PixelPerfectOutlineFilter

PixelPerfectOutlineFilter draws a 1-pixel outline via Kage shader.

type PointerContext

type PointerContext = node.PointerContext

PointerContext carries pointer event data.

type Range

type Range = types.Range

Range is a general-purpose min/max range.

type Rect

type Rect = types.Rect

Rect is an axis-aligned rectangle (origin top-left, Y down).

type RenderCommand

type RenderCommand = render.RenderCommand

RenderCommand is a single draw instruction emitted during scene traversal.

type RenderTexture

type RenderTexture = render.RenderTexture

RenderTexture is a persistent offscreen canvas.

type RenderTextureDrawOpts

type RenderTextureDrawOpts = render.RenderTextureDrawOpts

RenderTextureDrawOpts controls how an image or sprite is drawn onto a RenderTexture.

type Rope

type Rope = mesh.Rope

Rope generates a ribbon/rope mesh that follows a polyline path.

type RopeConfig

type RopeConfig = mesh.RopeConfig

RopeConfig configures a Rope mesh.

type RopeCurveMode

type RopeCurveMode = mesh.RopeCurveMode

RopeCurveMode selects the curve algorithm used by Rope.Update().

type RopeJoinMode

type RopeJoinMode = mesh.RopeJoinMode

RopeJoinMode controls how segments join in a Rope mesh.

type RunConfig

type RunConfig struct {
	Title         string
	Width, Height int
	Background    Color
	ShowFPS       bool
	// FXAA enables full-screen fast approximate anti-aliasing as a post-process
	// pass. Nil disables FXAA. Use DefaultFXAAConfig() for sensible defaults.
	FXAA *FXAAConfig
}

RunConfig holds optional configuration for Run.

type SDFGenOptions

type SDFGenOptions = text.SDFGenOptions

SDFGenOptions configures SDF atlas generation (used by fontgen CLI).

type Scene

type Scene = core.Scene

Scene is the top-level object that owns the node tree, cameras, input state, and render buffers.

func NewScene

func NewScene() *Scene

NewScene creates a new scene with a pre-created root container.

type SceneManager

type SceneManager = core.SceneManager

SceneManager manages a stack of scenes with optional transitions.

type TestRunner

type TestRunner = core.TestRunner

TestRunner sequences injected input events and screenshots across frames.

type TextAlign

type TextAlign = types.TextAlign

TextAlign controls horizontal text alignment within a TextBlock.

type TextBlock

type TextBlock = text.TextBlock

TextBlock holds text content, formatting, and cached layout state.

type TextEffects

type TextEffects = text.TextEffects

TextEffects configures text effects (outline, glow, shadow).

type TextureRegion

type TextureRegion = types.TextureRegion

TextureRegion describes a sub-rectangle within an atlas page.

type TileLayerConfig

type TileLayerConfig = tilemap.LayerConfig

TileLayerConfig holds the parameters for creating a tile layer.

type TileMapLayer

type TileMapLayer = tilemap.Layer

TileMapLayer is a single layer of tile data.

type TileMapViewport

type TileMapViewport = tilemap.Viewport

TileMapViewport is a scene graph node that manages a viewport into a tilemap.

func NewTileMapViewport

func NewTileMapViewport(name string, tileWidth, tileHeight int) *TileMapViewport

NewTileMapViewport creates a new tilemap viewport node.

type TileQuery

type TileQuery = tilemap.TileQuery

TileQuery provides a read-only view of tilemap data for external systems.

type Transition

type Transition = core.Transition

Transition controls the visual effect between scene changes.

type TweenConfig

type TweenConfig = types.TweenConfig

TweenConfig holds the duration and easing function for a tween.

type TweenGroup

type TweenGroup = core.TweenGroup

TweenGroup animates up to 4 float64 fields on a Node simultaneously.

type Vec2

type Vec2 = types.Vec2

Vec2 is a 2D vector.

Directories

Path Synopsis
examples
demos/3d-raycaster command
Wolfenstein-style dungeon crawler testbed for the Willow engine.
Wolfenstein-style dungeon crawler testbed for the Willow engine.
demos/3d-village command
Village — a low-poly software 3D village rendered in the PS1/N64 aesthetic.
Village — a low-poly software 3D village rendered in the PS1/N64 aesthetic.
demos/atlas command
Atlas demonstrates the TexturePacker atlas system and dynamic page registration.
Atlas demonstrates the TexturePacker atlas system and dynamic page registration.
demos/basic command
Basic demonstrates a minimal willow scene with a colored sprite bouncing around the window.
Basic demonstrates a minimal willow scene with a colored sprite bouncing around the window.
demos/cable-puzzle command
Rope Garden - a cable-untangling puzzle.
Rope Garden - a cable-untangling puzzle.
demos/filter-gallery command
Filter Gallery showcases every built-in Willow filter applied to a whelp sprite.
Filter Gallery showcases every built-in Willow filter applied to a whelp sprite.
demos/filter-showcase command
Filter Showcase demonstrates Willow's filter and shader system with a single sprite cycling through dramatic visual effects.
Filter Showcase demonstrates Willow's filter and shader system with a single sprite cycling through dramatic visual effects.
demos/fireflies command
Fireflies demonstrates a nighttime meadow scene with glowing fireflies drifting on tweened paths, each casting a warm light.
Fireflies demonstrates a nighttime meadow scene with glowing fireflies drifting on tweened paths, each casting a warm light.
demos/geometry-showcase command
Geometry Showcase demonstrates the breadth of Willow's polygon and custom geometry primitives: regular polygons, stars, custom polygons, circles, triangles, lines, and runtime vertex updates — all animated with tweens and per-frame rotation.
Geometry Showcase demonstrates the breadth of Willow's polygon and custom geometry primitives: regular polygons, stars, custom polygons, circles, triangles, lines, and runtime vertex updates — all animated with tweens and per-frame rotation.
demos/interaction command
Interaction demonstrates draggable colored rectangles with click callbacks using willow.Run for a minimal game loop.
Interaction demonstrates draggable colored rectangles with click callbacks using willow.Run for a minimal game loop.
demos/lighting command
Lighting Demo showcases the LightLayer system in a dark dungeon scene.
Lighting Demo showcases the LightLayer system in a dark dungeon scene.
demos/lighting-showcase command
Lighting Showcase demonstrates Willow's circle light system with multiple colored lights orbiting and overlapping to create blended illumination.
Lighting Showcase demonstrates Willow's circle light system with multiple colored lights orbiting and overlapping to create blended illumination.
demos/lightning-showcase command
Lightning Showcase demonstrates a dramatic lightning strike effect combining the lighting system, particle sparks, and screen flash.
Lightning Showcase demonstrates a dramatic lightning strike effect combining the lighting system, particle sparks, and screen flash.
demos/mace command
Mace demonstrates a medieval flail — a spiked mace head on a chain — swinging around the screen using the Rope mesh for the chain and a Star polygon for the head.
Mace demonstrates a medieval flail — a spiked mace head on a chain — swinging around the screen using the Rope mesh for the chain and a Star polygon for the head.
demos/mask-showcase command
Mask Showcase demonstrates Willow's clipping and masking system with a single sprite cycling through five dramatic mask effects, one per second.
Mask Showcase demonstrates Willow's clipping and masking system with a single sprite cycling through five dramatic mask effects, one per second.
demos/masks command
Masks demonstrates three node-masking techniques in Willow across three equal full-height panels:
Masks demonstrates three node-masking techniques in Willow across three equal full-height panels:
demos/outline command
Outline demonstrates outline and inline filters applied to a sprite with alpha transparency (whelp.png).
Outline demonstrates outline and inline filters applied to a sprite with alpha transparency (whelp.png).
demos/particles command
Particles demonstrates the ParticleEmitter system with three distinct effects and two blend modes.
Particles demonstrates the ParticleEmitter system with three distinct effects and two blend modes.
demos/physics command
physics spawns random shapes with gravity, collisions, and click-to-explode.
physics spawns random shapes with gravity, collisions, and click-to-explode.
demos/pixel-font command
Text-pixelfont demonstrates pixel-perfect bitmap font rendering using willow.NewFontFamilyFromPixelFont.
Text-pixelfont demonstrates pixel-perfect bitmap font rendering using willow.NewFontFamilyFromPixelFont.
demos/rope command
Rope demonstrates the Rope mesh helper by connecting two draggable nodes with a textured rope that sags under gravity.
Rope demonstrates the Rope mesh helper by connecting two draggable nodes with a textured rope that sags under gravity.
demos/sdf-blizzard command
SDF Blizzard demonstrates SDF font effects with an icy theme: per-letter bouncing, intense glow/outline/shadow effects, and falling ice particles.
SDF Blizzard demonstrates SDF font effects with an icy theme: per-letter bouncing, intense glow/outline/shadow effects, and falling ice particles.
demos/shaders command
Shaders showcases Willow's built-in filter system by displaying all shader effects simultaneously in a 3x3 grid, each applied to a pre-rendered tilemap panel with animated parameters.
Shaders showcases Willow's built-in filter system by displaying all shader effects simultaneously in a 3x3 grid, each applied to a pre-rendered tilemap panel with animated parameters.
demos/shapes command
Shapes demonstrates scene graph hierarchy with polygons and containers.
Shapes demonstrates scene graph hierarchy with polygons and containers.
demos/sprite-stress command
sprites10k spawns 10,000 whelp sprites that rotate, scale, fade, and bounce around the screen simultaneously.
sprites10k spawns 10,000 whelp sprites that rotate, scale, fade, and bounce around the screen simultaneously.
demos/text command
Text demonstrates font rendering with willow.NewText and willow.NewFontFamilyFromFontBundle.
Text demonstrates font rendering with willow.NewText and willow.NewFontFamilyFromFontBundle.
demos/tiled-loader command
Demo: loading a Tiled (.tmx) map into Willow's tilemap system via go-tiled.
Demo: loading a Tiled (.tmx) map into Willow's tilemap system via go-tiled.
demos/tilemap-basic command
Tilemap demonstrates a grid-based tilemap with camera panning.
Tilemap demonstrates a grid-based tilemap with camera panning.
demos/tilemap-viewport command
TileMapViewport demonstrates the geometry-buffer tilemap renderer with camera panning, multiple tile layers, and a sandwich entity layer.
TileMapViewport demonstrates the geometry-buffer tilemap renderer with camera panning, multiple tile layers, and a sandwich entity layer.
demos/tween-gallery command
Tween Gallery showcases every easing function available in Willow's tween system.
Tween Gallery showcases every easing function available in Willow's tween system.
demos/tween-recipe command
Tween Recipe demonstrates a coordinated tween combo where twelve circles bloom outward from center, rotate and shift color, then converge back in a continuous loop.
Tween Recipe demonstrates a coordinated tween combo where twelve circles bloom outward from center, rotate and shift color, then converge back in a continuous loop.
demos/tweens command
Tweens demonstrates the tween animation system using tiles from the shared tileset.
Tweens demonstrates the tween animation system using tiles from the shared tileset.
demos/underwater command
Underwater demonstrates a layered underwater scene revealed through a circular porthole mask that follows the cursor.
Underwater demonstrates a layered underwater scene revealed through a circular porthole mask that follows the cursor.
demos/watermesh command
Watermesh demonstrates per-vertex wave animation using a DistortionGrid textured with tile 13 (the water tile) from the bundled tileset.
Watermesh demonstrates per-vertex wave animation using a DistortionGrid textured with tile 13 (the water tile) from the bundled tileset.
internal
integration
Package integration contains integration tests for the willow engine.
Package integration contains integration tests for the willow engine.

Jump to

Keyboard shortcuts

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