core

package
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: 21 Imported by: 0

Documentation

Index

Constants

View Source
const DefaultCommandCap = 4096

Variables

View Source
var (
	// RegisterPageFn registers an atlas page image at the given index.
	RegisterPageFn func(index int, img *ebiten.Image)

	// LoadAtlasFn parses TexturePacker JSON and registers atlas pages.
	LoadAtlasFn func(jsonData []byte, pages []*ebiten.Image, startIndex int)
)

Function pointers wired by the root package for operations that core cannot perform directly (atlas management, etc.).

Functions

func CountBatches

func CountBatches(commands []render.RenderCommand) int

CountBatches counts contiguous groups of commands sharing the same BatchKey.

func CountDrawCalls

func CountDrawCalls(commands []render.RenderCommand) int

CountDrawCalls counts individual draw calls from the command list.

func CountDrawCallsCoalesced

func CountDrawCallsCoalesced(commands []render.RenderCommand) int

CountDrawCallsCoalesced estimates actual draw calls in coalesced mode.

func DebugLog

func DebugLog(stats DebugStats)

DebugLog prints timing and draw-call stats to stderr.

func FlushScreenshots

func FlushScreenshots(screen *ebiten.Image, queue []string, dir string)

FlushScreenshots captures the rendered frame for every queued label and writes each as a PNG file.

func KeyFromName

func KeyFromName(name string) ebiten.Key

KeyFromName returns the ebiten.Key for a JSON key name. Lookup is case-insensitive. Returns -1 if the name is not recognized.

func NewFPSWidget

func NewFPSWidget() *node.Node

NewFPSWidget creates a Node that displays FPS and TPS as a screen overlay.

func PropagateScene

func PropagateScene(n *node.Node, s any)

PropagateScene recursively sets the scene back-pointer on n and all descendants.

func SanitizeLabel

func SanitizeLabel(label string) string

SanitizeLabel replaces characters that are unsafe in file names with underscores and falls back to "unlabeled" for empty strings.

func ToTexture

func ToTexture(n *node.Node, s *Scene) *ebiten.Image

ToTexture renders a node's subtree to a new offscreen image and returns it.

func TweenEase

func TweenEase(cfg TweenConfig) ease.TweenFunc

TweenEase returns cfg.Ease if non-nil, otherwise ease.Linear.

func UpdateNodesAndParticles

func UpdateNodesAndParticles(n *node.Node, dt float64)

UpdateNodesAndParticles walks the tree depth-first, calling OnUpdate callbacks and ticking particle emitters.

Types

type DebugStats

type DebugStats struct {
	TraverseTime  time.Duration
	SortTime      time.Duration
	BatchTime     time.Duration
	SubmitTime    time.Duration
	CommandCount  int
	BatchCount    int
	DrawCallCount int
}

DebugStats holds per-frame timing and draw-call metrics.

type EntityStore

type EntityStore interface {
	// EmitEvent delivers an interaction event to the ECS.
	EmitEvent(event InteractionEvent)
}

EntityStore is the interface for optional ECS integration. When set on a Scene via SetEntityStore, interaction events on nodes with a non-zero EntityID are forwarded to the ECS.

type FadeTransition

type FadeTransition struct {
	// contains filtered or unexported fields
}

FadeTransition fades through a solid color (typically black).

func NewFadeTransition

func NewFadeTransition(duration float32, c color.Color) *FadeTransition

NewFadeTransition creates a fade transition with the given duration and color.

func (*FadeTransition) Done

func (f *FadeTransition) Done() bool

func (*FadeTransition) Draw

func (f *FadeTransition) Draw(screen *ebiten.Image, progress float32)

func (*FadeTransition) Duration

func (f *FadeTransition) Duration() float32

func (*FadeTransition) Update

func (f *FadeTransition) Update(dt float32)

type GifConfig added in v0.2.2

type GifConfig struct {
	// Recording region.  Zero values capture the full window.
	X, Y          int // top-left of capture region (pixels)
	Width, Height int // size of capture region; 0 = full axis

	// Inset shrinks the capture region inward from all four edges.
	// Applied after X/Y/Width/Height (which default to full window).
	Inset int

	// Output resolution.  The captured region is downscaled to fit within
	// MaxWidth × MaxHeight while preserving aspect ratio.
	// 0 defaults to 480 and 360 respectively.
	MaxWidth  int
	MaxHeight int

	// FPS sets the recording frame rate.  0 defaults to 30.
	// The recorder skips engine ticks to match this rate.
	FPS int

	// MaxColors limits the palette size (2–256).  0 defaults to 256.
	// Fewer colors = smaller file but lower quality.
	MaxColors int

	// DropEvery removes every Nth captured frame from the output, merging
	// its delay into the previous frame.  0 defaults to 4 (drop every 4th).
	// Set to 1 to disable.
	DropEvery int

	// Optimisation toggles (all on by default).
	NoDedup     bool // disable similar-frame deduplication
	NoDiff      bool // disable transparent diff frames
	NoDownscale bool // disable resolution downscaling
}

GifConfig controls GIF recording behaviour. All optimisations are enabled by default; set the corresponding No* flag to disable one.

type GifRecorder added in v0.2.2

type GifRecorder struct {
	// contains filtered or unexported fields
}

GifRecorder accumulates frames from the ebiten screen and writes an optimised animated GIF on Finish.

func NewGifRecorder added in v0.2.2

func NewGifRecorder(label, dir string, cfg GifConfig) *GifRecorder

NewGifRecorder creates a recorder.

func (*GifRecorder) CaptureFrame added in v0.2.2

func (g *GifRecorder) CaptureFrame(screen *ebiten.Image)

CaptureFrame is called every Draw(). It decides whether to sample this frame based on the recording FPS, reads pixels, crops, downscales, and stores the result.

func (*GifRecorder) Finish added in v0.2.2

func (g *GifRecorder) Finish() error

Finish encodes the accumulated frames as an optimised GIF and writes it.

type InteractionEvent

type InteractionEvent struct {
	Type      types.EventType    // which kind of interaction occurred
	EntityID  uint32             // the ECS entity associated with the hit node
	GlobalX   float64            // pointer X in world coordinates
	GlobalY   float64            // pointer Y in world coordinates
	LocalX    float64            // pointer X in the hit node's local coordinates
	LocalY    float64            // pointer Y in the hit node's local coordinates
	Button    types.MouseButton  // which mouse button is involved
	Modifiers types.KeyModifiers // keyboard modifier keys held during the event
	// Drag fields (valid for EventDragStart, EventDrag, EventDragEnd)
	StartX       float64 // world X where the drag began
	StartY       float64 // world Y where the drag began
	DeltaX       float64 // X movement since the previous drag event
	DeltaY       float64 // Y movement since the previous drag event
	ScreenDeltaX float64 // X movement in screen pixels since the previous drag event
	ScreenDeltaY float64 // Y movement in screen pixels since the previous drag event
	// Pinch fields (valid for EventPinch)
	Scale      float64 // cumulative scale factor since pinch start
	ScaleDelta float64 // frame-to-frame scale change
	Rotation   float64 // cumulative rotation in radians since pinch start
	RotDelta   float64 // frame-to-frame rotation change in radians
}

InteractionEvent carries interaction data for the ECS bridge.

type Scene

type Scene struct {
	Root  *node.Node
	Debug bool

	TransformsReady bool

	// ClearColor is the background color used to fill the screen each frame
	// when the scene is run via Run. If left at the zero value (transparent
	// black), the screen is not filled, resulting in a black background.
	ClearColor types.Color

	// Cameras
	Cameras []*camera.Camera

	// Render pipeline — owns command buffer, sort/batch buffers, RT pool,
	// culling state, and batch submission.
	Pipeline render.Pipeline

	// Input state
	Input *input.Manager

	// Managed tweens (auto-ticked during Update)
	Tweens []*TweenGroup

	// Screenshot capture
	ScreenshotQueue []string
	ScreenshotDir   string

	// GIF recording
	GifRecorder *GifRecorder

	// Test runner
	TestRunnerRef *TestRunner

	// Injected keyboard input for test automation.
	InjectedChars []rune       // synthetic characters consumed by AppendInjectedChars
	InjectedKeys  []ebiten.Key // synthetic key presses consumed by IsInjectedKeyPressed

	// Held keys for data-driven autotest (key_down / key_up actions).
	HeldKeys map[ebiten.Key]struct{}

	// User callbacks set via SetUpdateFunc / SetPostDrawFunc / SetOnResize.
	UpdateFunc   func() error
	PostDrawFunc func(screen *ebiten.Image)
	OnResize     func(w, h int)

	// Scene lifecycle hooks for SceneManager.
	OnEnterFn func()
	OnExitFn  func()
	// contains filtered or unexported fields
}

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

func NewScene

func NewScene(root *node.Node) *Scene

NewScene creates a new Scene with default settings. The root node must be provided by the caller (root package creates it).

func (*Scene) AppendInjectedChars

func (s *Scene) AppendInjectedChars(buf []rune) []rune

AppendInjectedChars appends all injected characters to buf, then clears the queue. Mirrors ebiten.AppendInputChars for synthetic input.

func (*Scene) CapturePointer

func (s *Scene) CapturePointer(pointerID int, n *node.Node)

CapturePointer routes all events for pointerID to the given node.

func (*Scene) Draw

func (s *Scene) Draw(screen *ebiten.Image)

Draw traverses the scene tree, emits render commands, sorts them, and submits batches to the given screen image.

func (*Scene) GetBatchMode

func (s *Scene) GetBatchMode() render.BatchMode

GetBatchMode returns the current draw-call batching strategy.

func (*Scene) GetCameras

func (s *Scene) GetCameras() []*camera.Camera

GetCameras returns the scene's camera list. The returned slice MUST NOT be mutated.

func (*Scene) HasInjectedInput

func (s *Scene) HasInjectedInput() bool

HasInjectedInput returns true if there are any pending injected chars or keys.

func (*Scene) InjectClick

func (s *Scene) InjectClick(x, y float64)

InjectClick queues a press followed by a release at the given coordinates.

func (*Scene) InjectDrag

func (s *Scene) InjectDrag(fromX, fromY, toX, toY float64, frames int)

InjectDrag queues a full drag sequence over the given number of frames.

func (*Scene) InjectHover

func (s *Scene) InjectHover(x, y float64)

InjectHover queues a free pointer move (no button held) to trigger OnPointerEnter / OnPointerLeave without pressing a button.

func (*Scene) InjectKey

func (s *Scene) InjectKey(key ebiten.Key)

InjectKey queues a synthetic key press consumed by IsInjectedKeyPressed.

func (*Scene) InjectMove

func (s *Scene) InjectMove(x, y float64)

InjectMove queues a pointer move event at the given screen coordinates.

func (*Scene) InjectPress

func (s *Scene) InjectPress(x, y float64)

InjectPress queues a pointer press event at the given screen coordinates.

func (*Scene) InjectRelease

func (s *Scene) InjectRelease(x, y float64)

InjectRelease queues a pointer release event at the given screen coordinates.

func (*Scene) InjectText

func (s *Scene) InjectText(text string)

InjectText queues synthetic character input. Each rune is appended to InjectedChars, consumed one batch per frame by AppendInjectedChars.

func (*Scene) IsInjectedKeyPressed

func (s *Scene) IsInjectedKeyPressed(key ebiten.Key) bool

IsInjectedKeyPressed checks if key is in the injected keys queue and removes it. Returns true if found.

func (*Scene) IsKeyPressed added in v0.2.2

func (s *Scene) IsKeyPressed(key ebiten.Key) bool

IsKeyPressed returns true if a key is pressed on the real keyboard or held via the test runner (key_down/key_up). Demos should use this instead of ebiten.IsKeyPressed to support data-driven autotests.

func (*Scene) IsPointerDown

func (s *Scene) IsPointerDown(button types.MouseButton) bool

IsPointerDown reports whether the given mouse button is currently pressed.

func (*Scene) KeyDown added in v0.2.2

func (s *Scene) KeyDown(key ebiten.Key)

KeyDown marks a key as held. Used by test runner key_down actions.

func (*Scene) KeyUp added in v0.2.2

func (s *Scene) KeyUp(key ebiten.Key)

KeyUp releases a held key. Used by test runner key_up actions.

func (*Scene) NewCamera

func (s *Scene) NewCamera(viewport types.Rect) *camera.Camera

NewCamera creates a camera with the given viewport and adds it to the scene.

func (*Scene) OnBackgroundClick

func (s *Scene) OnBackgroundClick(fn func(node.ClickContext)) input.CallbackHandle

OnBackgroundClick registers a scene-level callback that fires when a click lands on empty space.

func (*Scene) OnClick

func (s *Scene) OnClick(fn func(node.ClickContext)) input.CallbackHandle

OnClick registers a scene-level callback for click events.

func (*Scene) OnDrag

func (s *Scene) OnDrag(fn func(node.DragContext)) input.CallbackHandle

OnDrag registers a scene-level callback for drag events.

func (*Scene) OnDragEnd

func (s *Scene) OnDragEnd(fn func(node.DragContext)) input.CallbackHandle

OnDragEnd registers a scene-level callback for drag end events.

func (*Scene) OnDragStart

func (s *Scene) OnDragStart(fn func(node.DragContext)) input.CallbackHandle

OnDragStart registers a scene-level callback for drag start events.

func (*Scene) OnPinch

func (s *Scene) OnPinch(fn func(node.PinchContext)) input.CallbackHandle

OnPinch registers a scene-level callback for pinch events.

func (*Scene) OnPointerDown

func (s *Scene) OnPointerDown(fn func(node.PointerContext)) input.CallbackHandle

OnPointerDown registers a scene-level callback for pointer down events.

func (*Scene) OnPointerEnter

func (s *Scene) OnPointerEnter(fn func(node.PointerContext)) input.CallbackHandle

OnPointerEnter registers a scene-level callback for pointer enter events.

func (*Scene) OnPointerLeave

func (s *Scene) OnPointerLeave(fn func(node.PointerContext)) input.CallbackHandle

OnPointerLeave registers a scene-level callback for pointer leave events.

func (*Scene) OnPointerMove

func (s *Scene) OnPointerMove(fn func(node.PointerContext)) input.CallbackHandle

OnPointerMove registers a scene-level callback for pointer move events.

func (*Scene) OnPointerUp

func (s *Scene) OnPointerUp(fn func(node.PointerContext)) input.CallbackHandle

OnPointerUp registers a scene-level callback for pointer up events.

func (*Scene) PointerPosition

func (s *Scene) PointerPosition() (x, y float64)

PointerPosition returns the current pointer position in screen space.

func (*Scene) PrimaryCamera

func (s *Scene) PrimaryCamera() *camera.Camera

PrimaryCamera returns the first camera, or nil if there are no cameras.

func (*Scene) RegisterPage

func (s *Scene) RegisterPage(index int, img *ebiten.Image)

RegisterPage stores an atlas page image at the given index.

func (*Scene) RegisterTween

func (s *Scene) RegisterTween(g *TweenGroup)

RegisterTween adds a tween group to the scene's managed list.

func (*Scene) ReleasePointer

func (s *Scene) ReleasePointer(pointerID int)

ReleasePointer stops routing events for pointerID to a captured node.

func (*Scene) RemoveCamera

func (s *Scene) RemoveCamera(cam *camera.Camera)

RemoveCamera removes a camera from the scene.

func (*Scene) RootNode

func (s *Scene) RootNode() *node.Node

RootNode returns the scene's root container node.

func (*Scene) Screenshot

func (s *Scene) Screenshot(label string)

Screenshot queues a labeled screenshot to be captured at the end of Draw.

func (*Scene) SetBatchMode

func (s *Scene) SetBatchMode(mode render.BatchMode)

SetBatchMode sets the draw-call batching strategy.

func (*Scene) SetDebugMode

func (s *Scene) SetDebugMode(enabled bool)

SetDebugMode enables or disables debug mode. When enabled, disposed-node access panics, tree depth and child count warnings are printed, and per-frame timing stats are logged to stderr.

func (*Scene) SetDragDeadZone

func (s *Scene) SetDragDeadZone(pixels float64)

SetDragDeadZone sets the minimum movement in pixels before a drag starts.

func (*Scene) SetEntityStore

func (s *Scene) SetEntityStore(store EntityStore)

SetEntityStore sets the optional ECS bridge.

func (*Scene) SetOnEnter

func (s *Scene) SetOnEnter(fn func())

SetOnEnter registers a callback called when this scene becomes active.

func (*Scene) SetOnExit

func (s *Scene) SetOnExit(fn func())

SetOnExit registers a callback called when this scene is being left.

func (*Scene) SetOnResize

func (s *Scene) SetOnResize(fn func(w, h int))

SetOnResize registers a callback that is called when the window is resized. The callback receives the new logical width and height in pixels.

func (*Scene) SetPostDrawFunc

func (s *Scene) SetPostDrawFunc(fn func(*ebiten.Image))

SetPostDrawFunc registers a callback that is called after Scene.Draw.

func (*Scene) SetTestRunner

func (s *Scene) SetTestRunner(runner *TestRunner)

SetTestRunner attaches a TestRunner to the scene.

func (*Scene) SetUpdateFunc

func (s *Scene) SetUpdateFunc(fn func() error)

SetUpdateFunc registers a callback that is called once per tick before Scene.Update when the scene is run via Run.

func (*Scene) StartGif added in v0.2.2

func (s *Scene) StartGif(label string)

StartGif begins recording frames as an animated GIF.

func (*Scene) StartGifWithConfig added in v0.2.2

func (s *Scene) StartGifWithConfig(label string, cfg GifConfig)

StartGifWithConfig begins recording with custom settings.

func (*Scene) StopGif added in v0.2.2

func (s *Scene) StopGif()

StopGif ends recording and writes the GIF file.

func (*Scene) TickTweens

func (s *Scene) TickTweens(dt float32)

TickTweens advances all managed tweens and compacts out completed ones.

func (*Scene) Update

func (s *Scene) Update()

Update processes input, advances animations, and simulates particles.

type SceneManager

type SceneManager struct {
	// contains filtered or unexported fields
}

SceneManager manages a stack of scenes with optional transitions.

func NewSceneManager

func NewSceneManager(initial *Scene) *SceneManager

NewSceneManager creates a SceneManager with the given initial scene.

func (*SceneManager) Current

func (sm *SceneManager) Current() *Scene

Current returns the active scene (top of stack).

func (*SceneManager) Draw

func (sm *SceneManager) Draw(screen *ebiten.Image)

Draw renders the active scene and any transition overlay.

func (*SceneManager) Pop

func (sm *SceneManager) Pop()

Pop removes the top scene and returns to the previous one. Panics if only one scene remains.

func (*SceneManager) Push

func (sm *SceneManager) Push(scene *Scene)

Push adds a scene on top of the stack with an optional transition.

func (*SceneManager) Replace

func (sm *SceneManager) Replace(scene *Scene)

Replace swaps the current scene for a new one (no stack growth).

func (*SceneManager) SetTransition

func (sm *SceneManager) SetTransition(t Transition)

SetTransition configures the transition for the next scene change. Pass nil to disable. Consumed after one use.

func (*SceneManager) Update

func (sm *SceneManager) Update()

Update advances the active scene and any in-progress transition.

type StepAction

type StepAction struct {
	Screenshot  func(label string)
	StartGif    func(label string, cfg GifConfig)
	StopGif     func()
	InjectClick func(x, y float64)
	InjectDrag  func(fromX, fromY, toX, toY float64, frames int)
	InjectMove  func(x, y float64)
	InjectText  func(text string)
	InjectKey   func(key string)
	KeyDown     func(key string)
	KeyUp       func(key string)
	QueueLen    func() int
}

StepAction is the interface that Scene uses to execute test steps. The Scene provides screenshot, inject, and queue access.

type TestRunner

type TestRunner struct {
	Steps     []TestStep
	Cursor    int
	WaitCount int
	IsDone    bool
	// contains filtered or unexported fields
}

TestRunner sequences injected input events and screenshots across frames.

func LoadTestScript

func LoadTestScript(jsonData []byte) (*TestRunner, error)

LoadTestScript parses a JSON test script and returns a TestRunner.

func (*TestRunner) Done

func (r *TestRunner) Done() bool

Done reports whether all steps have been executed.

func (*TestRunner) Step

func (r *TestRunner) Step(a StepAction)

Step advances the test runner by one frame.

type TestStep

type TestStep struct {
	Action string  `json:"action"`
	Label  string  `json:"label,omitempty"`
	Text   string  `json:"text,omitempty"`
	Key    string  `json:"key,omitempty"`
	X      float64 `json:"x,omitempty"`
	Y      float64 `json:"y,omitempty"`
	FromX  float64 `json:"fromX,omitempty"`
	FromY  float64 `json:"fromY,omitempty"`
	ToX    float64 `json:"toX,omitempty"`
	ToY    float64 `json:"toY,omitempty"`
	Frames int     `json:"frames,omitempty"`

	// GIF config fields (start_gif action only).
	Inset       int  `json:"inset,omitempty"`
	Width       int  `json:"width,omitempty"`
	Height      int  `json:"height,omitempty"`
	FPS         int  `json:"fps,omitempty"`
	MaxWidth    int  `json:"maxWidth,omitempty"`
	MaxHeight   int  `json:"maxHeight,omitempty"`
	MaxColors   int  `json:"maxColors,omitempty"`
	DropEvery   int  `json:"dropEvery,omitempty"`
	NoDedup     bool `json:"noDedup,omitempty"`
	NoDiff      bool `json:"noDiff,omitempty"`
	NoDownscale bool `json:"noDownscale,omitempty"`
}

TestStep represents a single action in a test script.

type Transition

type Transition interface {
	Duration() float32
	Update(dt float32)
	Draw(screen *ebiten.Image, progress float32)
	Done() bool
}

Transition controls the visual effect between scene changes.

type TweenConfig

type TweenConfig struct {
	Duration float32
	Ease     ease.TweenFunc
}

TweenConfig holds the duration and easing function for a tween.

type TweenGroup

type TweenGroup struct {
	Tweens [4]*gween.Tween
	Count  int
	Fields [4]*float64
	Target *node.Node
	Done   bool
	// Managed is true when auto-registered with a Scene.
	Managed   bool
	Cancelled bool
}

TweenGroup animates up to 4 float64 fields on a Node simultaneously. Create via root convenience constructors (TweenPosition, TweenScale, etc.).

func TweenAlpha

func TweenAlpha(n *node.Node, to float64, cfg types.TweenConfig) *TweenGroup

TweenAlpha animates node.Alpha_ to the target value.

func TweenColor

func TweenColor(n *node.Node, to types.Color, cfg types.TweenConfig) *TweenGroup

TweenColor animates all four components of node.Color_ to the target color.

func TweenPosition

func TweenPosition(n *node.Node, toX, toY float64, cfg types.TweenConfig) *TweenGroup

TweenPosition animates node.X_ and node.Y_ to the given target.

func TweenRotation

func TweenRotation(n *node.Node, to float64, cfg types.TweenConfig) *TweenGroup

TweenRotation animates node.Rotation_ to the target value.

func TweenScale

func TweenScale(n *node.Node, toSX, toSY float64, cfg types.TweenConfig) *TweenGroup

TweenScale animates node.ScaleX_ and node.ScaleY_ to the given target.

func (*TweenGroup) Cancel

func (g *TweenGroup) Cancel()

Cancel marks the tween for removal on the next tick.

func (*TweenGroup) Tick

func (g *TweenGroup) Tick(dt float32)

Tick is the internal method that does the actual tween work.

func (*TweenGroup) Update

func (g *TweenGroup) Update(dt float32)

Update advances all tweens by dt seconds. For managed tweens (auto-registered with a Scene), this is a no-op since Scene.Update() handles ticking.

Jump to

Keyboard shortcuts

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