Skip to content

PixelSpriteTexture

Extends ImageTexture. Read from the plugin's source on every build.

A texture that is a document’s frame, kept in step with it.

The point of it is that nothing has to be exported. A Sprite2D, a TextureRect, a TileSet — anything that takes a Texture2D — can point at one of these and follow the artwork as it is drawn, where the PNG route needs an export, a reimport, and the artist to remember both.

A resource rather than a node on purpose. A PixelSprite2D would work for exactly one kind of node and leave every other kind wanting its own, which is the wrong axis to extend on.

The trade against exporting: the document ships with the game rather than a flat PNG, so the layer data is in the build, and there is no import pipeline to set filtering or compression from. For pixel art most of those settings were being turned off anyway. Export when the artwork is finished and this is what you draw against in the meantime.

Properties

document

@export var document: PixelDocument

The document this texture shows a frame of, rebuilt as the document changes.

frame

@export var frame: int = 0

Which frame of the document to show. Clamped rather than refused: a document that loses frames should leave its textures showing something.

Methods

path_changed

static func path_changed(document: PixelDocument) -> int

Puts document, just read off disk again, on every live texture showing the file it came from, and answers how many there were. The frame each was showing stays.

What the running game calls when the dock saves: kit/live_listener.gd reloads the path with CACHE_MODE_REPLACE, which refills the instance the game already holds, so a texture holding that instance holds the new pixels and nothing has told it. A texture holding another instance on the same path is given this one.

set_document

func set_document(value: PixelDocument) -> void

Sets document, follows its signals instead of the old one’s, and rebuilds.

set_frame

func set_frame(value: int) -> void

Sets frame and rebuilds, so the texture shows the new frame.

rebuild

func rebuild() -> void

Composites the frame and puts it on the texture. Public because a caller that has changed a document behind the signals can ask for it.

composited_image

func composited_image() -> Image

The pixels this texture is showing.

Not get_image(), which asks the rendering server and gets back whatever the server has. Replacing the image on a texture that already had one leaves get_image() returning the old one under the headless driver, so the suite could not see a rebuild at all and neither could anything else that only wanted the pixels.

Constants

PLACEHOLDER_SIZE

const PLACEHOLDER_SIZE := Vector2i(1, 1)

What the texture shows while there is no document, and what a document that cannot be composited falls back to. A texture with no image at all reports a size of zero, and a node given one draws nothing and says nothing about why.

UNSTORED_PROPERTIES

const UNSTORED_PROPERTIES: Array[StringName] = [&"image"]

What ImageTexture would save that this class builds instead. image is the composite of document’s frame, and the document already holds every pixel of it, so a scene or .tres holding this texture was carrying the artwork twice — the second copy the composite of the day, stale from the next stroke on. Loading sets document, which rebuilds it.

JamChip 0.1.0, by GlitterSnack. MIT licence. Built from the source on every merge, artwork and screenshots included, with JamChip.