Documentation
¶
Overview ¶
Package willow is a retained-mode 2D game framework for Ebitengine.
Ebitengine is immediate-mode: every frame you issue draw commands from scratch, and nothing persists. Willow adds a retained-mode layer on top - you build a persistent scene graph of nodes, and Willow traverses it each frame to produce draw commands for Ebitengine.
Willow provides the scene graph, transform hierarchy, sprite batching, input handling, camera viewports, text rendering, particle systems, and more that every non-trivial 2D game needs.
Full documentation, tutorials, and examples are available at:
https://devthicket.github.io/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://devthicket.github.io/willow/
Index ¶
- Constants
- Variables
- func LoadFontFromPathAsTtf(path string) ([]byte, error)
- func LoadFontFromSystemAsTtf(name string) ([]byte, error)
- func Run(scene *Scene, cfg RunConfig) error
- type AnimFrame
- type Atlas
- type BatchMode
- type BlendMode
- type BlurFilter
- type CacheTreeMode
- type CallbackHandle
- type Camera
- type ClickContext
- type Color
- type ColorMatrixFilter
- type CommandType
- type CustomShaderFilter
- type DistanceFieldFont
- type DistortionGrid
- type DragContext
- type EaseFunc
- type EmitterConfig
- type EntityStore
- type EventType
- type FXAAConfig
- type Filter
- type Font
- type Glyph
- type GlyphBitmap
- type HitCircle
- type HitPolygon
- type HitRect
- type HitShape
- type InteractionEvent
- type KeyModifiers
- type Light
- type LightLayer
- type MouseButton
- type Node
- func NewCircle(name string, radius float64, c Color) *Node
- func NewContainer(name string) *Node
- func NewLine(name string, x1, y1, x2, y2, thickness float64, c Color) *Node
- func NewMesh(name string, img *ebiten.Image, vertices []ebiten.Vertex, indices []uint16) *Node
- func NewParticleEmitter(name string, cfg EmitterConfig) *Node
- func NewRect(name string, w, h float64, c Color) *Node
- func NewSprite(name string, region TextureRegion) *Node
- func NewText(name string, content string, font Font) *Node
- func NewTriangle(name string, p1, p2, p3 Vec2, c Color) *Node
- func Root(s *Scene) *Node
- type NodeIndex
- type NodeType
- type OutlineFilter
- type PackerConfig
- type PaletteFilter
- type ParticleEmitter
- type PinchContext
- type PixelFont
- type PixelPerfectInlineFilter
- type PixelPerfectOutlineFilter
- type PointerContext
- type Range
- type Rect
- type RenderCommand
- type RenderTexture
- type RenderTextureDrawOpts
- type Rope
- type RopeConfig
- type RopeCurveMode
- type RopeJoinMode
- type RunConfig
- type SDFGenOptions
- type Scene
- type TestRunner
- type TextAlign
- type TextBlock
- type TextEffects
- type TextureRegion
- type TileLayerConfig
- type TileMapLayer
- type TileMapViewport
- type TweenConfig
- type TweenGroup
- type Vec2
Constants ¶
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.
const ( NodeTypeContainer = types.NodeTypeContainer NodeTypeSprite = types.NodeTypeSprite NodeTypeMesh = types.NodeTypeMesh NodeTypeParticleEmitter = types.NodeTypeParticleEmitter NodeTypeText = types.NodeTypeText )
Node types.
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.
const ( MouseButtonLeft = types.MouseButtonLeft MouseButtonRight = types.MouseButtonRight MouseButtonMiddle = types.MouseButtonMiddle )
Mouse buttons.
const ( ModShift = types.ModShift ModCtrl = types.ModCtrl ModAlt = types.ModAlt ModMeta = types.ModMeta )
Modifier keys.
const ( TextAlignLeft = types.TextAlignLeft TextAlignCenter = types.TextAlignCenter TextAlignRight = types.TextAlignRight )
Text alignment.
const ( CacheTreeManual = types.CacheTreeManual CacheTreeAuto = types.CacheTreeAuto )
Cache tree modes.
const ( BatchModeCoalesced = render.BatchModeCoalesced BatchModeImmediate = render.BatchModeImmediate )
Batch modes.
const ( CommandSprite = render.CommandSprite CommandMesh = render.CommandMesh CommandParticle = render.CommandParticle CommandTilemap = render.CommandTilemap CommandSDF = render.CommandSDF CommandBitmapText = render.CommandBitmapText )
Command types.
const ( RopeJoinMiter = mesh.RopeJoinMiter RopeJoinBevel = mesh.RopeJoinBevel )
Rope join modes.
const ( RopeCurveLine = mesh.RopeCurveLine RopeCurveCatenary = mesh.RopeCurveCatenary RopeCurveQuadBezier = mesh.RopeCurveQuadBezier RopeCurveCubicBezier = mesh.RopeCurveCubicBezier RopeCurveWave = mesh.RopeCurveWave RopeCurveCustom = mesh.RopeCurveCustom )
Rope curve modes.
Variables ¶
var ( RGB = types.RGB ColorFromRGBA = types.ColorFromRGBA ColorFromHSV = types.ColorFromHSV ColorWhite = types.ColorWhite ColorBlack = types.ColorBlack ColorTransparent = types.ColorTransparent )
Color constructors and constants.
Atlas constructors.
var ( LoadDistanceFieldFont = text.LoadDistanceFieldFont LoadDistanceFieldFontFromTTF = text.LoadDistanceFieldFontFromTTF GenerateSDFFromBitmaps = text.GenerateSDFFromBitmaps )
Text / Font constructors.
var ( NewColorMatrixFilter = filter.NewColorMatrixFilter NewBlurFilter = filter.NewBlurFilter NewOutlineFilter = filter.NewOutlineFilter NewPixelPerfectOutlineFilter = filter.NewPixelPerfectOutlineFilter NewPixelPerfectInlineFilter = filter.NewPixelPerfectInlineFilter NewPaletteFilter = filter.NewPaletteFilter NewCustomShaderFilter = filter.NewCustomShaderFilter )
Filter constructors.
var ( NewRope = mesh.NewRope NewDistortionGrid = mesh.NewDistortionGrid NewPolygon = mesh.NewPolygon NewRegularPolygon = mesh.NewRegularPolygon NewStar = mesh.NewStar NewPolygonTextured = mesh.NewPolygonTextured SetPolygonPoints = mesh.SetPolygonPoints )
Mesh constructors.
var ( TweenPosition = core.TweenPosition TweenScale = core.TweenScale TweenColor = core.TweenColor TweenAlpha = core.TweenAlpha TweenRotation = core.TweenRotation )
Tweens.
var DefaultFXAAConfig = render.DefaultFXAAConfig
DefaultFXAAConfig returns an FXAAConfig with FXAA 3.11 quality-15 defaults.
var LoadTestScript = core.LoadTestScript
Test runner.
var NewLightLayer = lighting.NewLightLayer
Lighting.
var NewNodeIndex = node.NewNodeIndex
Node index.
var NewRenderTexture = render.NewRenderTexture
Render.
var ToTexture = core.ToTexture
Render to texture.
var WhitePixel *ebiten.Image
WhitePixel is a 1x1 white image used by default for solid color sprites.
Functions ¶
func LoadFontFromPathAsTtf ¶
LoadFontFromPathAsTtf reads a TTF/OTF file from disk.
func LoadFontFromSystemAsTtf ¶
LoadFontFromSystemAsTtf searches OS system font directories for a font by name.
Types ¶
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 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 DistanceFieldFont ¶
type DistanceFieldFont = text.DistanceFieldFont
DistanceFieldFont renders text from a pre-generated SDF or MSDF atlas.
func NewFontFromTTF ¶
func NewFontFromTTF(ttfData []byte, size float64) (*DistanceFieldFont, error)
NewFontFromTTF generates an SDF font from TTF/OTF data, registers the atlas page, and returns the font ready to use.
func NewFontFromTTFOpts ¶
func NewFontFromTTFOpts(ttfData []byte, opts SDFGenOptions) (*DistanceFieldFont, error)
NewFontFromTTFOpts generates an SDF font using explicit SDFGenOptions.
type DistortionGrid ¶
type DistortionGrid = mesh.DistortionGrid
DistortionGrid provides a grid mesh that can be deformed per-vertex.
type EaseFunc ¶
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 FXAAConfig ¶
type FXAAConfig = render.FXAAConfig
FXAAConfig holds tunable parameters for the FXAA post-process pass. Use DefaultFXAAConfig for sensible defaults.
type GlyphBitmap ¶
type GlyphBitmap = text.GlyphBitmap
GlyphBitmap holds a rasterized glyph and its metrics for atlas packing.
type HitPolygon ¶
type HitPolygon = input.HitPolygon
HitPolygon is a convex polygon hit area in local coordinates.
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 LightLayer ¶
type LightLayer = lighting.LightLayer
LightLayer provides a convenient 2D lighting effect using erase blending.
type Node ¶
Node is the fundamental scene graph element.
func NewCircle ¶
NewCircle creates a solid-color circle node with the given radius. The circle is approximated with 32 segments.
func NewContainer ¶
NewContainer creates a container node with no visual representation.
func NewLine ¶
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 NewParticleEmitter ¶
func NewParticleEmitter(name string, cfg EmitterConfig) *Node
NewParticleEmitter creates a particle emitter node with a preallocated pool.
func NewSprite ¶
func NewSprite(name string, region TextureRegion) *Node
NewSprite creates a sprite node that renders a texture region.
func NewTriangle ¶
NewTriangle creates a solid-color triangle node from three points.
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 ¶
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 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 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.
type Scene ¶
Scene is the top-level object that owns the node tree, cameras, input state, and render buffers.
type TestRunner ¶
type TestRunner = core.TestRunner
TestRunner sequences injected input events and screenshots across frames.
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 TileMapViewport ¶
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 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.
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
hellodemo
command
|
|
|
examples
|
|
|
atlas
command
Atlas demonstrates the TexturePacker atlas system and dynamic page registration.
|
Atlas demonstrates the TexturePacker atlas system and dynamic page registration. |
|
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. |
|
filtergallery
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. |
|
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. |
|
lighting
command
Lighting Demo showcases the LightLayer system in a dark dungeon scene.
|
Lighting Demo showcases the LightLayer system in a dark dungeon scene. |
|
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: |
|
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). |
|
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. |
|
physics
command
physics spawns random shapes with gravity, collisions, and click-to-explode.
|
physics spawns random shapes with gravity, collisions, and click-to-explode. |
|
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. |
|
ropegarden
command
Rope Garden - a cable-untangling puzzle.
|
Rope Garden - a cable-untangling puzzle. |
|
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. |
|
shapes
command
Shapes demonstrates scene graph hierarchy with polygons and containers.
|
Shapes demonstrates scene graph hierarchy with polygons and containers. |
|
sprites10k
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. |
|
text
command
Text demonstrates font rendering with willow.NewText and willow.NewFontFromTTF.
|
Text demonstrates font rendering with willow.NewText and willow.NewFontFromTTF. |
|
text-pixelfont
command
Text-pixelfont demonstrates pixel-perfect bitmap font rendering using willow.NewPixelFont.
|
Text-pixelfont demonstrates pixel-perfect bitmap font rendering using willow.NewPixelFont. |
|
tilemap
command
Tilemap demonstrates a grid-based tilemap with camera panning.
|
Tilemap demonstrates a grid-based tilemap with camera panning. |
|
tilemapviewport
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. |
|
tweengallery
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. |
|
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. |
|
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. |
|
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. |