On this page
tecs.gfx.animation
Sprite sheets, fixed-step playback, Aseprite slices, pivots, and reloads.
A Sheet divides one image into frames and names frame ranges with tags. An Animation selects a sheet tag and carries speed, loop, and playback state.
local hero <const> = tecs.gfx.animation.newGridSheet({
name = "hero",
imageWidth = 256,
imageHeight = 32,
frameWidth = 32,
frameHeight = 32,
tags = {
idle = {from = 1, to = 4},
run = {from = 5, to = 8},
},
})
hero:bind(app.renderer.sprites:sprite("hero.png"))
world:addPlugin(tecs.gfx.animation.plugin)
world:spawn(
tecs.Transform2D(64, 64, 0, 1, 0, 32, 32),
hero:sprite(),
tecs.gfx.animation.of(hero, "run"),
tecs.gfx.Renderable2D()
)Playback advances in fixed steps. Machines that replay the same simulation therefore select the same frames. frameOf and timeOf report playback on the same fixed-step clock.
Sheet sources
Use newGridSheet for uniform cells, newRectSheet for an explicit frame list, newSheetBuilder for a custom sheet, or newSheetFromAseprite for an Aseprite JSON export. Frames count from one. Tags name inclusive frame spans and may play forward, reverse, or ping-pong.
Bind a sheet to a renderer sprite before drawing it. Every entity playing that sheet shares its frame and timing data.
Slices and pivots
Aseprite slices may move between frames. A Pivot bound to a slice follows that movement, which keeps attachments such as hands, muzzles, and feet on the part of the drawing they name.
Reloads
Re-exporting a sheet under the same name can replace its frame, tag, slice, and timing data in place. Existing entities retain the sheet id and continue from their playback state. A replacement must preserve the bound image dimensions.
A sprite sheet divides one image into frames, tags, and slices.
Aseprite supplies the model: each frame carries its own duration, tags play inclusive spans in a direction, and slices carry rectangles, nine-slice centers, and pivots that may move between frames. fromAseprite reads its JSON export into the same interface that grid, rects, and build produce.
Frames count from one in sheet order. Tag zero represents the whole sheet playing forward.
Bind the finished sheet to a renderer sprite before drawing:
local hero <const> = tecs.gfx.animation.newSheetFromAseprite({
name = "game.hero",
json = asepriteExport,
})
hero:bind(app.renderer.sprites:sprite("sprites/hero.png"))sprite(frame) creates a Sprite for one frame. pivot(name, frame) creates a Pivot from a slice. Animation keeps that pivot on the named slice as the slice moves.
A sheet name forms a snapshot compatibility surface. Every entity that plays the sheet shares its registered frame, tag, slice, and timing data.
Module contents
Constructors
| Constructor | Description |
|---|---|
newGridSheet |
Creates a sheet whose frames form a uniform grid. |
newRectSheet |
Creates a sheet from explicitly listed frame rectangles. |
newSheetBuilder |
Creates a builder for a sheet that the other constructors cannot describe. |
newSheetFromAseprite |
Creates a sheet from an Aseprite JSON export. |
Types
| Type | Kind | Description |
|---|---|---|
Animation |
record | Stores playback state for one entity. |
AnimationEvents |
record | Requests Completed and Looped events for an entity. |
AsepriteOptions |
record | Configures newSheetFromAseprite. |
Builder |
record | Builds custom sheets one frame at a time. |
Completed |
record | Reports when a non-looping tag runs past its last frame. |
Direction |
enum | Selects how a tag walks its span. |
GridOptions |
record | Configures newGridSheet. |
Looped |
record | Reports when a looping tag passes its last frame and restarts. |
Pivot |
record | Read-only. Exposes the pivot component that controls where an entity's quad turns and scales. |
PlayOptions |
record | Configures of and play. |
Rect |
record | One frame, as newRectSheet and the builder take it. |
RectsOptions |
record | Configures newRectSheet. |
Sheet |
record | Read-only. Exposes an image divided into frames. |
Slice |
record | A named region that moves across the frames. |
SliceKey |
record | Defines where a slice sits from one frame onward. |
Tag |
record | A named span of frames, as the constructors take it. |
Functions
| Function | Kind | Description |
|---|---|---|
build |
Static | Creates a builder for a sheet that the other constructors cannot describe. |
byId |
Static | Returns the sheet represented by a registration index, or nil. |
byName |
Static | Returns the sheet registered under a name, or nil. |
findSheetById |
Static | Returns the sheet represented by a process-wide id. |
findSheetByName |
Static | Returns the sheet registered under a name. |
frameOf |
Static | Returns the sheet frame shown by an entity's animation. |
fromAseprite |
Static | Creates a sheet from an Aseprite JSON export. |
grid |
Static | Creates a sheet whose frames form a uniform grid. |
of |
Static | Creates an Animation that plays a named sheet tag and is ready to spawn. |
play |
Static | Points a live entity at a tag and restarts it there. |
plugin |
Static | Adds the systems that drive playback. |
rects |
Static | Creates a sheet from explicitly listed frame rectangles. |
replace |
Static | Folds a re-exported sheet into the one already registered under its name, in place, so an entity playing the old id... |
restart |
Static | Plays an entity's animation again from the start of its tag. |
revision |
Static | Returns how many times any sheet's frames have changed. |
sheetRevision |
Static | Returns how many times any sheet's frames have changed. |
timeOf |
Static | Returns an animation's position in its tag cycle, in seconds. |
Values
| Value | Type | Description |
|---|---|---|
DEFAULT_DURATION |
number |
Read-only. Reports how many milliseconds a frame remains visible when nothing overrides its duration. |
Constructors
tecs.gfx.animation.newGridSheet Static
Creates a sheet whose frames form a uniform grid.
function tecs.gfx.animation.newGridSheet(
options: sheet.GridOptions
): sheet.SheetArguments
| Name | Type | Description |
|---|---|---|
options |
sheet.GridOptions |
Raises on a missing name, a non-positive image or frame size, a grid that fits no cells, or a count past what the grid holds. Frames come out in row-major order. |
Returns
| Type | Description |
|---|---|
sheet.Sheet |
The finished sheet, already registered under its name and carrying an id. |
tecs.gfx.animation.newRectSheet Static
Creates a sheet from explicitly listed frame rectangles.
function tecs.gfx.animation.newRectSheet(
options: sheet.RectsOptions
): sheet.SheetArguments
| Name | Type | Description |
|---|---|---|
options |
sheet.RectsOptions |
Raises on a missing name, a non-positive image size, an empty frame list, or a frame with no positive size. |
Returns
| Type | Description |
|---|---|
sheet.Sheet |
The finished sheet, already registered under its name and carrying an id. |
tecs.gfx.animation.newSheetBuilder Static
Creates a builder for a sheet that the other constructors cannot describe.
function tecs.gfx.animation.newSheetBuilder(
name: string, imageWidth: number, imageHeight: number
): sheet.BuilderArguments
| Name | Type | Description |
|---|---|---|
name |
string |
Name to register the finished sheet under. |
imageWidth |
number |
Size of the image the frames are cut from, in pixels. |
imageHeight |
number |
The other size, in pixels. |
Returns
| Type | Description |
|---|---|
sheet.Builder |
Returns a builder that registers the sheet when finish runs. |
tecs.gfx.animation.newSheetFromAseprite Static
Creates a sheet from an Aseprite JSON export.
function tecs.gfx.animation.newSheetFromAseprite(
options: sheet.AsepriteOptions
): sheet.SheetArguments
| Name | Type | Description |
|---|---|---|
options |
sheet.AsepriteOptions |
Raises on a missing name or an export the reader cannot make a sheet out of. |
Returns
| Type | Description |
|---|---|
sheet.Sheet |
The finished sheet, already registered. |
Types
tecs.gfx.animation.Animation record
Stores playback state for one entity.
What an entity is playing lives here and where its cycle has got to lives in its Sprite, which carries the playback the shader resolves. So frame is not an index: the encoder writes ENCODED to say the Sprite carries a live playback, and zero says the entity is to start its cycle again. Which frame is showing is animation.frameOf.
time is the phase the cycle starts or resumes from, in seconds, and stays inside the cycle. Nothing advances it while playback runs, so it neither grows without bound nor loses precision to its own age. Read-only. Exposes the playback-state component for one entity.
record tecs.gfx.animation.Animation is Component
sheet: number
tag: number
speed: number
time: number
frame: number
loop: boolean
playing: boolean
endInterfaces
| Interface |
|---|
Component |
tecs.gfx.animation.Animation.sheet field
Caller-writable. Selects a sheet by its Sheet.id registration index. Zero plays nothing.
tecs.gfx.animation.Animation.tag field
Caller-writable. Selects a tag by its Sheet:tagId index. Zero plays the whole sheet in order.
tecs.gfx.animation.Animation.speed field
Caller-writable. Multiplies the timing the sheet carries. One is the timing as authored, two is twice as fast. Zero or less holds the current frame and stops time advancing, which is a pause that leaves playing alone.
How long each frame is held is the sheet's answer and not an entity's, because that is where an artist sets it: a hold frame is a frame with a long duration, which no single rate can express.
tecs.gfx.animation.Animation.time field
Engine-owned. Carries the phase the cycle starts or resumes from, in seconds. Ordinary game code should read timeOf, which reports where the cycle has got to; this field stays where playback was last started from. The cycle duration is the sum of the durations of the frames the tag visits. Changing speed leaves the phase where it is, so playback carries on from the frame it was showing rather than jumping.
tecs.gfx.animation.Animation.frame field
Engine-owned. Says whether the Sprite carries a live playback, and never which frame that playback is showing. Ordinary game code should use frameOf. Zero asks for the cycle to start again, which is what play, restart, of and a restored snapshot write.
tecs.gfx.animation.Animation.loop field
Caller-writable. Controls whether the tag restarts after its last frame.
tecs.gfx.animation.Animation.playing field
Caller-writable. Controls whether time advances.
tecs.gfx.animation.AnimationEvents record
Requests Completed and Looped events for an entity.
The event query visits only entities carrying this tag. A game can request events for a handful of entities without walking the rest of its animated crowd. Adding the tag costs one archetype move and nothing per step. Read-only. Exposes the tag that requests Completed and Looped events for an entity.
record tecs.gfx.animation.AnimationEvents is Component
endInterfaces
| Interface |
|---|
Component |
tecs.gfx.animation.AsepriteOptions record
Configures newSheetFromAseprite.
tecs.gfx.animation.AsepriteOptions.name field
Caller-writable. Sets the registration name. It defaults to the export's image name. An export without an image name requires this field.
tecs.gfx.animation.AsepriteOptions.name: stringtecs.gfx.animation.AsepriteOptions.json field
Caller-writable. Supplies the export as JSON text or a decoded table. it. A table is what an asset pipeline that decoded once should pass.
tecs.gfx.animation.AsepriteOptions.json: anytecs.gfx.animation.Builder record
Builds custom sheets one frame at a time.
record tecs.gfx.animation.Builder
finish: function(self): Sheet
frame: function(
self,
x: number,
y: number,
w: number,
h: number,
duration: number
): Builder
slice: function(
self,
name: string,
x: number,
y: number,
w: number,
h: number,
pivotX: number,
pivotY: number
): Builder
sliceKeys: function(
self, name: string, data: string, keys: {SliceKey}
): Builder
tag: function(
self,
name: string,
from: integer,
to: integer,
direction: Direction
): Builder
endtecs.gfx.animation.Builder:finish Instance
Registers and returns the finished sheet.
Raises on a sheet with no frames, and on a tag whose span falls outside them.
Arguments
| Name | Type | Description |
|---|---|---|
self |
Builder |
Returns
| Type | Description |
|---|---|
Sheet |
tecs.gfx.animation.Builder:frame Instance
Appends a frame to the sheet under construction.
function tecs.gfx.animation.Builder.frame(
self, x: number, y: number, w: number, h: number, duration: number
): BuilderArguments
| Name | Type | Description |
|---|---|---|
self |
Builder |
|
x |
number |
Left of the frame in the image, in pixels. |
y |
number |
Top of the frame. |
w |
number |
Width, which must be positive. |
h |
number |
Height, which must be positive. |
duration |
number |
Milliseconds it is held. Defaults to sheet.DEFAULT_DURATION. |
Returns
| Type | Description |
|---|---|
Builder |
The builder. |
tecs.gfx.animation.Builder:slice Instance
Adds a fixed slice with a pivot.
function tecs.gfx.animation.Builder.slice(
self,
name: string,
x: number,
y: number,
w: number,
h: number,
pivotX: number,
pivotY: number
): BuilderArguments
| Name | Type | Description |
|---|---|---|
self |
Builder |
|
name |
string |
What a sprite names to take its pivot from. |
x |
number |
Left of the slice within a frame, in pixels. |
y |
number |
Top of the slice. |
w |
number |
Width. |
h |
number |
Height. |
pivotX |
number |
Pivot within the slice, in the slice's own pixels. Omitted, the slice carries no pivot and its middle stands in. |
pivotY |
number |
Returns
| Type | Description |
|---|---|
Builder |
The builder. |
tecs.gfx.animation.Builder:sliceKeys Instance
Adds a slice from explicit keys for importers.
function tecs.gfx.animation.Builder.sliceKeys(
self, name: string, data: string, keys: {SliceKey}
): BuilderArguments
| Name | Type | Description |
|---|---|---|
self |
Builder |
|
name |
string |
The slice's name. |
data |
string |
Free text to carry alongside it, or nil for none. |
keys |
{SliceKey} |
Keys in frame order, at least one. |
Returns
| Type | Description |
|---|---|
Builder |
The builder. |
tecs.gfx.animation.Builder:tag Instance
Names an inclusive frame span and its playback direction.
function tecs.gfx.animation.Builder.tag(
self, name: string, from: integer, to: integer, direction: Direction
): BuilderArguments
| Name | Type | Description |
|---|---|---|
self |
Builder |
|
name |
string |
What an animation asks for. |
from |
integer |
First frame, counting from one. |
to |
integer |
Last frame, inclusive. |
direction |
Direction |
Defaults to "forward". |
Returns
| Type | Description |
|---|---|
Builder |
The builder. |
tecs.gfx.animation.Completed record
Reports when a non-looping tag runs past its last frame. The animation stops and holds that frame, so this fires once per playthrough and never again until something restarts it. Read-only. Exposes the event emitted when a non-looping tag finishes.
record tecs.gfx.animation.Completed is events.Event
entity: integer
sheet: Sheet
tag: string
__call: function(
self, entity: integer, sheet: Sheet, tag: string
): Completed
endInterfaces
| Interface |
|---|
events.Event |
tecs.gfx.animation.Completed.entity field
Read-only. Identifies the entity whose animation completed.
tecs.gfx.animation.Completed.sheet field
Read-only. Reports the sheet that completed.
tecs.gfx.animation.Completed.tag field
Read-only. Reports the tag that finished, or the empty string for a whole sheet.
tecs.gfx.animation.Completed:__call
Creates a completed event value.
tecs.gfx.animation.Completed.$meta.__call(
self, entity: integer, sheet: Sheet, tag: string
): CompletedArguments
| Name | Type | Description |
|---|---|---|
self |
Completed |
The completed event type. |
entity |
integer |
The entity whose animation completed. |
sheet |
Sheet |
The sheet that completed. |
tag |
string |
The tag that completed, or an empty string for the whole sheet. |
Returns
| Type | Description |
|---|---|
Completed |
The completed event value. |
tecs.gfx.animation.Direction enum
Selects how a tag walks its span.
enum tecs.gfx.animation.Direction
"forward"
"pingpong"
"reverse"
endtecs.gfx.animation.GridOptions record
Configures newGridSheet.
record tecs.gfx.animation.GridOptions
name: string
imageWidth: number
imageHeight: number
frameWidth: number
frameHeight: number
margin: number
spacing: number
columns: integer
rows: integer
count: integer
duration: number
tags: {string: Tag}
slices: {Slice}
endtecs.gfx.animation.GridOptions.name field
Caller-writable. Sets the required registration name.
tecs.gfx.animation.GridOptions.name: stringtecs.gfx.animation.GridOptions.imageWidth field
Caller-writable. Sets the required image width in pixels.
tecs.gfx.animation.GridOptions.imageWidth: numbertecs.gfx.animation.GridOptions.imageHeight field
Caller-writable. Sets the required image height in pixels.
tecs.gfx.animation.GridOptions.imageHeight: numbertecs.gfx.animation.GridOptions.frameWidth field
Caller-writable. Sets the required frame width in pixels.
tecs.gfx.animation.GridOptions.frameWidth: numbertecs.gfx.animation.GridOptions.frameHeight field
Caller-writable. Sets the required frame height in pixels.
tecs.gfx.animation.GridOptions.frameHeight: numbertecs.gfx.animation.GridOptions.margin field
Caller-writable. Sets the border between the image edge and first cell. Defaults to zero.
tecs.gfx.animation.GridOptions.margin: numbertecs.gfx.animation.GridOptions.spacing field
Caller-writable. Sets the gap between neighboring cells and defaults to zero.
tecs.gfx.animation.GridOptions.spacing: numbertecs.gfx.animation.GridOptions.columns field
Caller-writable. Sets how many cells fit across. The constructor derives it from the image size when omitted.
tecs.gfx.animation.GridOptions.columns: integertecs.gfx.animation.GridOptions.rows field
Caller-writable. Sets how many cells fit down. The constructor derives it from the image size when omitted.
tecs.gfx.animation.GridOptions.rows: integertecs.gfx.animation.GridOptions.count field
Caller-writable. Sets how many frames to take across rows. It defaults to every cell, which is wrong only for a sheet whose last row is short.
tecs.gfx.animation.GridOptions.count: integertecs.gfx.animation.GridOptions.duration field
Caller-writable. Sets how many milliseconds every cell remains visible. It defaults to DEFAULT_DURATION. A grid uses one duration for every frame; retime individual frames with sheet.build.
tecs.gfx.animation.GridOptions.duration: numbertecs.gfx.animation.GridOptions.tags field
Caller-writable. Defines optional named tags over the frames.
tecs.gfx.animation.GridOptions.tags: {string: Tag}tecs.gfx.animation.GridOptions.slices field
Caller-writable. Defines optional named slices.
tecs.gfx.animation.GridOptions.slices: {Slice}tecs.gfx.animation.Looped record
Reports when a looping tag passes its last frame and restarts.
Once per step at most, not once per cycle: a step long enough to cover several cycles wraps the time once and reports one loop, so counting these is not a way to count playthroughs. Read-only. Exposes the event emitted when a looping tag restarts.
record tecs.gfx.animation.Looped is events.Event
entity: integer
sheet: Sheet
tag: string
__call: function(
self, entity: integer, sheet: Sheet, tag: string
): Looped
endInterfaces
| Interface |
|---|
events.Event |
tecs.gfx.animation.Looped.entity field
Read-only. Identifies the entity whose animation looped.
tecs.gfx.animation.Looped.sheet field
Read-only. Reports the sheet that looped.
tecs.gfx.animation.Looped.tag field
Read-only. Reports the tag that wrapped, or the empty string for a whole sheet.
tecs.gfx.animation.Looped:__call
Creates a looped event value.
Arguments
| Name | Type | Description |
|---|---|---|
self |
Looped |
The looped event type. |
entity |
integer |
The entity whose animation looped. |
sheet |
Sheet |
The sheet that looped. |
tag |
string |
The tag that looped, or an empty string for the whole sheet. |
Returns
| Type | Description |
|---|---|
Looped |
The looped event value. |
tecs.gfx.animation.Pivot record
Read-only. Exposes the pivot component that controls where an entity's quad turns and scales.
record tecs.gfx.animation.Pivot is Component
x: number
y: number
sheet: number
slice: number
halfX: number
halfY: number
endInterfaces
| Interface |
|---|
Component |
tecs.gfx.animation.Pivot.x field
Caller-writable. Sets the pivot as a fraction across the frame from its left edge. One half selects the middle.
tecs.gfx.animation.Pivot.y field
Caller-writable. Sets the pivot as a fraction down the frame from its top edge. One half selects the middle.
tecs.gfx.animation.Pivot.sheet field
Caller-writable. Selects the sheet that owns the slice by registration index, or zero for a direct pivot.
tecs.gfx.animation.Pivot.slice field
Caller-writable. Selects the slice within that sheet by its Sheet:sliceId index, or zero for a pivot written directly.
tecs.gfx.animation.Pivot.halfX field
Engine-owned. Stores half the horizontal range that the point may travel over the current cycle, as a fraction of the frame.
A direct pivot or single-key slice uses zero, keeping the quad's exact cull bound. A moving slice uses x and y for the travel midpoint and this field for its reach on either side.
tecs.gfx.animation.Pivot.halfY field
Engine-owned. Stores the pivot's vertical travel for culling. Ordinary game code should ignore this field.
tecs.gfx.animation.PlayOptions record
Configures of and play.
tecs.gfx.animation.PlayOptions.speed field
Caller-writable. Multiplies the sheet's own timing and defaults to one.
tecs.gfx.animation.PlayOptions.speed: numbertecs.gfx.animation.PlayOptions.loop field
Caller-writable. Controls whether the tag restarts after its last frame. Defaults to true.
tecs.gfx.animation.PlayOptions.loop: booleantecs.gfx.animation.PlayOptions.playing field
Caller-writable. Controls whether playback starts immediately. Defaults to true.
tecs.gfx.animation.PlayOptions.playing: booleantecs.gfx.animation.Rect record
One frame, as newRectSheet and the builder take it.
tecs.gfx.animation.Rect.x field
Caller-writable. Sets the frame's left edge in image pixels.
tecs.gfx.animation.Rect.y field
Caller-writable. Sets the frame's top edge in image pixels.
tecs.gfx.animation.Rect.w field
Caller-writable. Sets the frame width in pixels.
tecs.gfx.animation.Rect.h field
Caller-writable. Sets the frame height in pixels.
tecs.gfx.animation.Rect.duration field
Caller-writable. Sets the frame duration in milliseconds and defaults to sheet.DEFAULT_DURATION.
tecs.gfx.animation.RectsOptions record
Configures newRectSheet.
record tecs.gfx.animation.RectsOptions
name: string
imageWidth: number
imageHeight: number
frames: {Rect}
tags: {string: Tag}
slices: {Slice}
endtecs.gfx.animation.RectsOptions.name field
Caller-writable. Sets the required registration name.
tecs.gfx.animation.RectsOptions.name: stringtecs.gfx.animation.RectsOptions.imageWidth field
Caller-writable. Sets the required image width in pixels.
tecs.gfx.animation.RectsOptions.imageWidth: numbertecs.gfx.animation.RectsOptions.imageHeight field
Caller-writable. Sets the required image height in pixels.
tecs.gfx.animation.RectsOptions.imageHeight: numbertecs.gfx.animation.RectsOptions.frames field
Caller-writable. Sets the required frame rects in address order.
tecs.gfx.animation.RectsOptions.frames: {Rect}tecs.gfx.animation.RectsOptions.tags field
Caller-writable. Defines optional named tags over the frames.
tecs.gfx.animation.RectsOptions.tags: {string: Tag}tecs.gfx.animation.RectsOptions.slices field
Caller-writable. Defines optional named slices.
tecs.gfx.animation.RectsOptions.slices: {Slice}tecs.gfx.animation.Sheet record
Read-only. Exposes an image divided into frames.
record tecs.gfx.animation.Sheet
name: string
id: integer
count: integer
imageWidth: number
imageHeight: number
bind: function(self, sprite: Sprite): Sheet
cycle: function(self, id: integer): number
duration: function(self, frame: integer): number
frameAt: function(self, id: integer, time: number): integer
hasTag: function(self, name: string): boolean
pivot: function(self, name: string, frame: integer): Pivot
pivotOf: function(self, id: integer, frame: integer): number, number
rect: function(self, frame: integer): number, number, number, number
slice: function(self, name: string): Slice
sliceId: function(self, name: string): integer
sliceKeyAt: function(self, id: integer, frame: integer): SliceKey
sliceName: function(self, id: integer): string
sprite: function(self, frame: integer): Sprite
tag: function(self, name: string): integer, integer, Direction
tagId: function(self, name: string): integer
tagName: function(self, id: integer): string
uv: function(self, frame: integer): number, number, number, number
endtecs.gfx.animation.Sheet.name field
Read-only. Reports the registered name that snapshots store.
tecs.gfx.animation.Sheet.id field
Read-only. Reports the registration index carried by an Animation. Construction assigns an id once and never reuses it.
tecs.gfx.animation.Sheet.count field
Read-only. Reports the number of frames and the largest index rect, uv and sprite accept.
tecs.gfx.animation.Sheet.imageWidth field
Read-only. Reports the source image width in pixels. Frame rectangles use this width, so binding the sheet to an image of a different size places frames incorrectly.
tecs.gfx.animation.Sheet.imageWidth: numbertecs.gfx.animation.Sheet.imageHeight field
Read-only. Reports the height in pixels of the image from which frames are cut.
tecs.gfx.animation.Sheet.imageHeight: numbertecs.gfx.animation.Sheet:bind Instance
Resolves the sheet's frames against a registered image.
sprite is what renderer.sprites:sprite(name) returns for a whole image: its u1 and v1 are the fractions of the texture-array layer that image occupies. The function scales the frame's image fraction by them before it names a region of the layer. Pass a sub-rect and the frames land inside that sub-rect, which is not what the sheet describes.
Binding again rescales from the pixel rectangles instead of the previous result, so re-registering an image does not accumulate scaling error. Entities already carrying regions from an earlier bind keep them: a rebind does not update any existing Sprite.
Arguments
| Name | Type | Description |
|---|---|---|
self |
Sheet |
|
sprite |
Sprite |
A whole image, from renderer.sprites:sprite. |
Returns
| Type | Description |
|---|---|
Sheet |
Returns the sheet so callers can chain bind. |
tecs.gfx.animation.Sheet:cycle Instance
Returns the duration of one tag cycle in seconds.
function tecs.gfx.animation.Sheet.cycle(self, id: integer): numberArguments
| Name | Type | Description |
|---|---|---|
self |
Sheet |
|
id |
integer |
A tag index, or zero for the whole sheet. |
Returns
| Type | Description |
|---|---|
number |
The sum of the durations of the frames the cycle visits, which for a pingpong tag counts the frames it passes twice twice. |
tecs.gfx.animation.Sheet:duration Instance
Returns how long a frame remains visible, in seconds.
function tecs.gfx.animation.Sheet.duration(self, frame: integer): numberArguments
| Name | Type | Description |
|---|---|---|
self |
Sheet |
|
frame |
integer |
One to count. Anything else raises. |
Returns
| Type | Description |
|---|---|
number |
Returns the authored frame duration in seconds. |
tecs.gfx.animation.Sheet:frameAt Instance
Returns the frame shown by a tag at a point in its cycle.
function tecs.gfx.animation.Sheet.frameAt(
self, id: integer, time: number
): integerArguments
| Name | Type | Description |
|---|---|---|
self |
Sheet |
|
id |
integer |
A tag index, or zero for the whole sheet. |
time |
number |
Seconds into the cycle. Outside it clamps rather than wrapping, since wrapping is the caller's decision about looping. |
Returns
| Type | Description |
|---|---|
integer |
A frame index into the whole sheet, counting from one. |
tecs.gfx.animation.Sheet:hasTag Instance
Returns whether the sheet contains the given tag.
function tecs.gfx.animation.Sheet.hasTag(self, name: string): booleanArguments
| Name | Type | Description |
|---|---|---|
self |
Sheet |
|
name |
string |
Any string, and nil answers false rather than raising, so this is what to ask before tag. |
Returns
| Type | Description |
|---|---|
boolean |
Whether tag would answer for that name. |
tecs.gfx.animation.Sheet:pivot Instance
Creates a Pivot from a named slice, ready to spawn.
Bound to the slice as well as resolved from it, so playback moves the pivot as the frame changes rather than leaving it where the frame it was built from put it.
Fails on a name the sheet does not carry, for the reason tag does: the alternative is a typo that silently pivots on the middle.
Arguments
| Name | Type | Description |
|---|---|---|
self |
Sheet |
|
name |
string |
A slice this sheet carries. |
frame |
integer |
The frame to resolve it at, defaulting to the first. What an entity shows before its first step, and what a sheet with no Animation keeps. |
Returns
| Type | Description |
|---|---|
Pivot |
A component value, not an entity. |
tecs.gfx.animation.Sheet:pivotOf Instance
Returns a slice pivot as a fraction of its frame.
Aseprite writes a pivot in the slice's own pixels, so this adds the slice's origin and divides by the frame, which is the number a quad wants: nothing downstream has to know the sheet's pixel sizes.
A slice with a center but no pivot answers the center's middle, and a slice with neither answers the middle of its own rectangle. Zero, a slice the sheet does not carry, or a frame it has no key for all answer the middle of the frame, which is where a quad sits with no pivot at all.
function tecs.gfx.animation.Sheet.pivotOf(
self, id: integer, frame: integer
): number, numberArguments
| Name | Type | Description |
|---|---|---|
self |
Sheet |
|
id |
integer |
A slice index from sliceId. |
frame |
integer |
A frame index. |
Returns
| Type | Description |
|---|---|
number |
The pivot's x and y as fractions of the frame, from its top left. |
number |
tecs.gfx.animation.Sheet:rect Instance
Returns a frame's pixel rectangle as x, y, width, and height.
function tecs.gfx.animation.Sheet.rect(
self, frame: integer
): number, number, number, numberArguments
| Name | Type | Description |
|---|---|---|
self |
Sheet |
|
frame |
integer |
One to count. Anything else raises, since a frame index out of range is a sheet and an animation disagreeing rather than something to paper over. |
Returns
| Type | Description |
|---|---|
number |
The rect's left, top, width and height, in the pixels of the image the sheet was cut from. |
number |
|
number |
|
number |
tecs.gfx.animation.Sheet:slice Instance
Returns a slice by name, or nil when the sheet does not contain one.
Arguments
| Name | Type | Description |
|---|---|---|
self |
Sheet |
|
name |
string |
A slice name. |
Returns
| Type | Description |
|---|---|
Slice |
The slice, whose keys the caller must not mutate. |
tecs.gfx.animation.Sheet:sliceId Instance
Returns the index represented by a slice name, or zero when absent.
function tecs.gfx.animation.Sheet.sliceId(self, name: string): integerArguments
| Name | Type | Description |
|---|---|---|
self |
Sheet |
|
name |
string |
A slice name, or nil. |
Returns
| Type | Description |
|---|---|
integer |
The index, which is what a component carries in place of the name for the reason a tag id is. |
tecs.gfx.animation.Sheet:sliceKeyAt Instance
Returns the slice key active on a frame, or nil.
A slice holds a key until the next one, so this answers the last key at or before the frame rather than only an exact match.
Arguments
| Name | Type | Description |
|---|---|---|
self |
Sheet |
|
id |
integer |
A slice index from sliceId. Zero answers nil. |
frame |
integer |
A frame index. |
Returns
| Type | Description |
|---|---|
SliceKey |
tecs.gfx.animation.Sheet:sliceName Instance
Returns the name represented by a slice index, or the empty string.
function tecs.gfx.animation.Sheet.sliceName(self, id: integer): stringArguments
| Name | Type | Description |
|---|---|---|
self |
Sheet |
|
id |
integer |
A slice index from sliceId. Zero or an absent index returns the empty string. |
Returns
| Type | Description |
|---|---|
string |
The slice name, or the empty string when the index is absent. |
tecs.gfx.animation.Sheet:sprite Instance
Creates a Sprite showing one frame, ready to spawn.
Defaults to the first frame. Meaningful after bind, since before it the sheet names no image and the quad has no layer to sample.
Arguments
| Name | Type | Description |
|---|---|---|
self |
Sheet |
|
frame |
integer |
One to count, defaulting to one. Anything else raises. |
Returns
| Type | Description |
|---|---|
Sprite |
Returns a fresh Sprite that the caller owns, not a view onto the sheet. |
tecs.gfx.animation.Sheet:tag Instance
Returns the first frame, last frame, and direction of a named tag.
Fails on a name the sheet does not carry, because the alternative is an animation silently playing the whole sheet on a typo.
Arguments
| Name | Type | Description |
|---|---|---|
self |
Sheet |
|
name |
string |
A tag this sheet was built with. |
Returns
| Type | Description |
|---|---|
integer |
The tag's first frame index, its last, and its direction. |
integer |
|
Direction |
tecs.gfx.animation.Sheet:tagId Instance
Returns the index represented by a tag name, or zero when absent.
Zero reads as the whole sheet rather than as nothing, so an animation that names no tag plays every frame in order.
A name the sheet does not carry is reported at error level under the tecs.gfx logger and then treated as the whole sheet. Zero is a plausible wrong answer rather than a visible failure, so a misspelled tag would otherwise animate every frame with nothing said. The report names the sheet, the name asked for, and the tags the sheet does carry, once per sheet and name however often the name is asked. Ask hasTag instead when a name's absence is expected and ordinary.
function tecs.gfx.animation.Sheet.tagId(self, name: string): integerArguments
| Name | Type | Description |
|---|---|---|
self |
Sheet |
|
name |
string |
A tag name, or nil or the empty string for the whole sheet. The empty string is what a snapshot stores for tag zero, so neither it nor nil is reported. |
Returns
| Type | Description |
|---|---|
integer |
Returns the index an Animation carries. The index belongs to this sheet alone: ids follow tag names in sorted order, so the same name in another sheet has another number. |
tecs.gfx.animation.Sheet:tagName Instance
Returns the name represented by a tag index, or the empty string for the whole sheet.
function tecs.gfx.animation.Sheet.tagName(self, id: integer): stringArguments
| Name | Type | Description |
|---|---|---|
self |
Sheet |
|
id |
integer |
An index from tagId. Nil, zero and anything the sheet does not carry all answer the empty string. |
Returns
| Type | Description |
|---|---|
string |
The tag's name, which is what a snapshot writes instead of the index. |
tecs.gfx.animation.Sheet:uv Instance
Returns a frame's region as u0, v0, u1, and v1.
Fractions of the image before bind and of the texture-array layer after it, which is the region a Sprite needs.
function tecs.gfx.animation.Sheet.uv(
self, frame: integer
): number, number, number, numberArguments
| Name | Type | Description |
|---|---|---|
self |
Sheet |
|
frame |
integer |
One to count. Anything else raises. |
Returns
| Type | Description |
|---|---|
number |
The region's left, top, right and bottom edges. |
number |
|
number |
|
number |
tecs.gfx.animation.Slice record
A named region that moves across the frames.
tecs.gfx.animation.Slice.name field
Caller-writable. Sets the name used to find the slice.
tecs.gfx.animation.Slice.data field
Caller-writable. Stores free text carried by Aseprite.
tecs.gfx.animation.Slice.keys field
Caller-writable. Sets at least one key in frame order.
tecs.gfx.animation.SliceKey record
Defines where a slice sits from one frame onward.
record tecs.gfx.animation.SliceKey
frame: integer
x: number
y: number
w: number
h: number
centerX: number
centerY: number
centerW: number
centerH: number
pivotX: number
pivotY: number
endtecs.gfx.animation.SliceKey.frame field
Caller-writable. Sets the first frame on which this key takes effect, counting from one.
tecs.gfx.animation.SliceKey.x field
Caller-writable. Sets the slice rectangle's left edge in frame pixels.
tecs.gfx.animation.SliceKey.y field
Caller-writable. Sets the slice rectangle's top edge in frame pixels.
tecs.gfx.animation.SliceKey.w field
Caller-writable. Sets the slice rectangle's width in pixels.
tecs.gfx.animation.SliceKey.h field
Caller-writable. Sets the slice rectangle's height in pixels.
tecs.gfx.animation.SliceKey.centerX field
Caller-writable. Sets the nine-slice center's left edge in slice pixels. Nil means the slice has no center.
tecs.gfx.animation.SliceKey.centerY field
Caller-writable. Sets the nine-slice center's top edge in slice pixels.
tecs.gfx.animation.SliceKey.centerW field
Caller-writable. Sets the nine-slice center's width in pixels.
tecs.gfx.animation.SliceKey.centerH field
Caller-writable. Sets the nine-slice center's height in pixels.
tecs.gfx.animation.SliceKey.pivotX field
Caller-writable. Sets the horizontal pivot in slice pixels. Nil means the slice has no pivot.
tecs.gfx.animation.SliceKey.pivotY field
Caller-writable. Sets the vertical pivot in slice pixels. Nil means the slice has no pivot.
tecs.gfx.animation.Tag record
A named span of frames, as the constructors take it.
tecs.gfx.animation.Tag.from field
Caller-writable. Sets the first frame index in the inclusive span.
tecs.gfx.animation.Tag.to field
Caller-writable. Sets the last frame index in the inclusive span.
tecs.gfx.animation.Tag.direction field
Caller-writable. Sets the playback direction and defaults to "forward".
Functions
tecs.gfx.animation.build Static
Creates a builder for a sheet that the other constructors cannot describe.
The model is what the builder writes, so an atlas from any tool reaches the same sheet an Aseprite export does. Frames, tags and slices are added in any order. build registers the finished sheet.
function tecs.gfx.animation.build(
name: string, imageWidth: number, imageHeight: number
): BuilderArguments
| Name | Type | Description |
|---|---|---|
name |
string |
Name to register the finished sheet under. |
imageWidth |
number |
Size of the image the frames are cut from, in pixels. |
imageHeight |
number |
Returns
| Type | Description |
|---|---|
Builder |
A builder whose methods chain. |
tecs.gfx.animation.byId Static
Returns the sheet represented by a registration index, or nil.
function tecs.gfx.animation.byId(id: integer): SheetArguments
| Name | Type | Description |
|---|---|---|
id |
integer |
An id from a sheet this process built. Construction assigns ids in order, so each id is meaningful only within one run. |
Returns
| Type | Description |
|---|---|
Sheet |
The sheet, or nil for an id nothing was built under. |
tecs.gfx.animation.byName Static
Returns the sheet registered under a name, or nil.
Building a second sheet under a name already taken replaces what this returns, so a reload points new entities at the new sheet. Entities already carrying the old id keep drawing the old one, which is what stops a reload from pulling a frame out from under them.
function tecs.gfx.animation.byName(name: string): SheetArguments
| Name | Type | Description |
|---|---|---|
name |
string |
The name a sheet was built under. |
Returns
| Type | Description |
|---|---|
Sheet |
The sheet most recently registered under that name, or nil. |
tecs.gfx.animation.findSheetById Static
Returns the sheet represented by a process-wide id.
function tecs.gfx.animation.findSheetById(id: integer): sheet.SheetArguments
| Name | Type | Description |
|---|---|---|
id |
integer |
An id a constructor handed out. |
Returns
| Type | Description |
|---|---|
sheet.Sheet |
The sheet, or nil when the id names none. |
tecs.gfx.animation.findSheetByName Static
Returns the sheet registered under a name.
function tecs.gfx.animation.findSheetByName(name: string): sheet.SheetArguments
| Name | Type | Description |
|---|---|---|
name |
string |
The name a constructor registered. |
Returns
| Type | Description |
|---|---|
sheet.Sheet |
The sheet, or nil when the name names none. |
tecs.gfx.animation.frameOf Static
Returns the sheet frame shown by an entity's animation.
The same answer the vertex shader draws, because both are frameAt over the same tag: the shader reads a table built from it and this calls it. What a hitbox on frame five, a footstep on frame three or a muzzle on an animated hand asks for.
function tecs.gfx.animation.frameOf(
world: World, entity: integer
): integerArguments
| Name | Type | Description |
|---|---|---|
world |
World |
The world the entity lives in. |
entity |
integer |
A live entity. |
Returns
| Type | Description |
|---|---|
integer |
A frame index into the whole sheet, counting from one, or zero for an entity with nothing to play. |
tecs.gfx.animation.fromAseprite Static
Creates a sheet from an Aseprite JSON export.
One reader in front of the model rather than a second model: frames, their durations, frame tags with their directions, and slices with their keys all land in the sheet the builder writes.
The reader accepts Aseprite's array layout and its object layout, sorting the latter by frame name. It ignores spriteSourceSize, so export with trimming off.
function tecs.gfx.animation.fromAseprite(
options: AsepriteOptions
): SheetArguments
| Name | Type | Description |
|---|---|---|
options |
AsepriteOptions |
The export and the name to register it under. |
Returns
| Type | Description |
|---|---|
Sheet |
The finished sheet. |
tecs.gfx.animation.grid Static
Creates a sheet whose frames form a uniform grid.
Margin surrounds the grid and spacing separates the cells, so a cell's left edge is margin + column * (frameWidth + spacing). Both default to zero, which is an image cut with nothing between its cells.
function tecs.gfx.animation.grid(options: GridOptions): SheetArguments
| Name | Type | Description |
|---|---|---|
options |
GridOptions |
Raises on a missing name, a non-positive image or frame size, a grid that fits no cells, or a count past what the grid holds. Frames come out in row-major order. |
Returns
| Type | Description |
|---|---|
Sheet |
The finished sheet, already registered under its name and carrying an id. |
tecs.gfx.animation.of Static
Creates an Animation that plays a named sheet tag and is ready to spawn.
Omit the tag to play the whole sheet in order. Fails on a tag the sheet does not carry, since the alternative is a typo that plays every frame.
The entity also needs a Sprite, which the query matches and playback writes what is playing into. An Animation on its own draws nothing.
function tecs.gfx.animation.of(
source: Sheet, tag: string, options: PlayOptions
): AnimationArguments
| Name | Type | Description |
|---|---|---|
source |
Sheet |
The sheet to play. Nil raises. |
tag |
string |
A tag the sheet names, or nil for the whole sheet. A name the sheet does not carry raises here rather than reporting and playing the whole sheet, because an author naming a tag at this call has one in mind and the sheet is already in hand to check against. |
options |
PlayOptions |
Defaults are the sheet's own timing, looping, and playing. |
Returns
| Type | Description |
|---|---|
Animation |
A component value, not an entity: pass it to world:spawn or world:set yourself. |
tecs.gfx.animation.play Static
Points a live entity at a tag and restarts it there.
Restarting is the point: time and frame both reset, so the next step writes the tag's first frame whatever the entity was showing. An entity carrying no Animation gets one.
function tecs.gfx.animation.play(
world: World,
entity: integer,
source: Sheet,
tag: string,
options: PlayOptions
)Arguments
| Name | Type | Description |
|---|---|---|
world |
World |
The world the entity lives in. |
entity |
integer |
A live entity with a Sprite. |
source |
Sheet |
The sheet to play. Nil raises. |
tag |
string |
A tag the sheet names, or nil for the whole sheet. A name the sheet does not carry raises, as it does in of. |
options |
PlayOptions |
Defaults are the sheet's own timing, looping, and playing. |
Returns
None.
tecs.gfx.animation.plugin Static
Adds the systems that drive playback.
Call this once for each world that plays sprite sheets. A second call on the same world does nothing.
It installs three systems, all in PostUpdate so they land before extraction whatever order a game added its plugins in. tecs.EncodeAnimation writes what each entity is playing into its Sprite and writes nothing on a step where nothing changed what is playing. tecs.ReportAnimation derives Completed and Looped for entities carrying AnimationEvents. tecs.RebaseAnimation moves the playback clock's origin every few hours of uptime and re-anchors every animated row on it, which is the one update in a hundred thousand that writes every playing animation.
function tecs.gfx.animation.plugin(world: World)Arguments
| Name | Type | Description |
|---|---|---|
world |
World |
The world to add the systems to. |
Returns
None.
tecs.gfx.animation.rects Static
Creates a sheet from explicitly listed frame rectangles.
For an image no grid describes: frames of differing sizes, or an atlas whose cells a packing tool placed.
function tecs.gfx.animation.rects(options: RectsOptions): SheetArguments
| Name | Type | Description |
|---|---|---|
options |
RectsOptions |
Raises on a missing name, a non-positive image size, an empty frame list, or a frame with no positive size. Rects are not checked against the image, so one that runs off the edge samples whatever the layer holds there. |
Returns
| Type | Description |
|---|---|
Sheet |
The finished sheet, already registered under its name and carrying an id. |
tecs.gfx.animation.replace Static
Folds a re-exported sheet into the one already registered under its name, in place, so an entity playing the old id shows the new frames.
Arguments
| Name | Type | Description |
|---|---|---|
built |
sheet.Sheet |
A sheet from any constructor here, registered moments ago under a name something else already holds. |
Returns
| Type | Description |
|---|---|
sheet.Sheet |
Returns the live sheet and nil, or nil and the refusal reason. |
string |
tecs.gfx.animation.restart Static
Plays an entity's animation again from the start of its tag.
The sheet, tag, speed and loop flag are left as they are; what resets is where in the cycle playback has got to and whether it is running. For replaying a one-shot that has finished, and for rewinding one that has not.
function tecs.gfx.animation.restart(
world: World, entity: integer
): booleanArguments
| Name | Type | Description |
|---|---|---|
world |
World |
The world the entity lives in. |
entity |
integer |
A live entity. |
Returns
| Type | Description |
|---|---|
boolean |
Whether there was an Animation to restart. False leaves the entity untouched, since there is nothing to say what it would play. |
tecs.gfx.animation.revision Static
Returns how many times any sheet's frames have changed.
Bumped by registration and by bind, both of which move where a frame's region points. Anything holding a copy of those regions compares this against what it copied from rather than being told, which keeps the dependency running one way: a sheet knows nothing about who read it.
function tecs.gfx.animation.revision(): integerArguments
None.
Returns
| Type | Description |
|---|---|
integer |
A number that only ever increases. |
tecs.gfx.animation.sheetRevision Static
Returns how many times any sheet's frames have changed.
What a cache of anything derived from a sheet compares against, so a sheet replaced or rebound under a running game invalidates it.
function tecs.gfx.animation.sheetRevision(): integerArguments
None.
Returns
| Type | Description |
|---|---|
integer |
A number that only ever increases. |
tecs.gfx.animation.timeOf Static
Returns an animation's position in its tag cycle, in seconds.
Recomputed on the call rather than kept in a column, because keeping it means writing every animating entity on every step and that is the cost resolving the frame in the shader exists to remove. A few hundred calls a step is free; it stops being free somewhere in the tens of thousands, which is a game asking a question this is the wrong shape for.
function tecs.gfx.animation.timeOf(
world: World, entity: integer
): numberArguments
| Name | Type | Description |
|---|---|---|
world |
World |
The world the entity lives in. |
entity |
integer |
A live entity. |
Returns
| Type | Description |
|---|---|
number |
Seconds into the cycle, wrapped for a looping tag and clamped at the end for a one-shot. Zero for an entity carrying no Animation and for one whose sheet this run does not have. |
Values
tecs.gfx.animation.DEFAULT_DURATION variable
Read-only. Reports how many milliseconds a frame remains visible when nothing overrides its duration.
tecs.gfx.animation.DEFAULT_DURATION: number