Godot SpriteFrames from pixel art

Updated · Adib Khan

From tags to animations

In Godot 4 an AnimatedSprite2D plays animations that live in a SpriteFrames resource. Each animation has a name, a speed in frames per second, a loop setting and a list of frames, and every frame points at a region of a texture. Building that by hand is not hard, but it is repetitive, and it has to be redone whenever you change the art.

The PixelFlipbook Godot bundle does it for you. You mark ranges of frames with tags in the timeline, such as idle frames 1 to 2 and run frames 3 to 6, and the export turns every tag into an animation of the same name. If you used no tags, one animation called default covers all frames.

The zip holds one folder with three files: the sheet PNG, the .tres resource and a README that says where to put things. Nothing in the folder depends on where you put it, because the resource refers to the PNG by a relative path.

The spritesheet PNG inside the Godot bundle: four walking frames in a two by two grid
The bundle's sheet is a plain grid PNG: this is the four-frame walk, two frames across and two down, shown at 8x. The region lines in the .tres below point at these four cells.
Draw an animation and tag it, then export for Godot.Open the editor

Using the bundle step by step

  1. Tag your animations. Select a range of frames in the timeline and add a tag. Give it a direction: forward, reverse or ping-pong.
  2. Export for Godot. Open Export and choose the Godot tab, then Export Godot bundle.
  3. Drop the folder into your project. Anywhere inside res:// works. The summary screen after export names the files and the resource to open.
  4. Open the .tres file or assign it to the Sprite Frames property of an AnimatedSprite2D. Your tags appear in the animation list.
  5. Keep pixels sharp. In Project Settings, under rendering and textures, set the default texture filter to Nearest. Otherwise Godot smooths the sprite when it scales.

A bundle is deterministic: exporting the same project twice gives identical files, so it plays well with version control.

The desktop timeline with four frame thumbnails and their durations, where frame ranges are selected
The timeline along the bottom of the desktop editor is where frame ranges are selected and tagged.
The phone editor on frame 2 of 4 with the timeline open and onion-skin ghosts of the neighbouring frames on the canvas
On a phone the timeline opens above the tool bar. Frame ranges are picked here too.

How speed, durations and loops are decided

PixelFlipbook lets every frame have its own duration, while Godot stores one speed per animation and a relative multiplier per frame. The exporter converts between the two like this:

Godot enforces a minimum frame time. If your shortest frame would drop below it, the exporter raises the speed to compensate and says so in the export report, instead of writing a resource that plays wrong.

Here is the start of a real resource, generated from the four-frame walk with a ping-pong tag:

[gd_resource type="SpriteFrames" format=3]

[ext_resource type="Texture2D" path="walk.png" id="1_sheet"]

[sub_resource type="AtlasTexture" id="AtlasTexture_00000"]
atlas = ExtResource("1_sheet")
region = Rect2(0, 0, 16, 16)

[sub_resource type="AtlasTexture" id="AtlasTexture_00001"]
atlas = ExtResource("1_sheet")
region = Rect2(16, 0, 16, 16)

[sub_resource type="AtlasTexture" id="AtlasTexture_00002"]
atlas = ExtResource("1_sheet")
region = Rect2(0, 16, 16, 16)

[sub_resource type="AtlasTexture" id="AtlasTexture_00003"]
atlas = ExtResource("1_sheet")
region = Rect2(16, 16, 16, 16)

[resource]
animations = [{

The free route: sheet and JSON

You do not need the bundle to get animation into Godot. The spritesheet export is free and gives you a PNG with evenly sized frames. In Godot's SpriteFrames editor, use the option to add frames from a sprite sheet, tell it how many frames run horizontally and vertically, select the frames you want and add them to an animation. Then set the speed yourself.

That takes a minute or two per animation. The bundle is for the case where you have many animations, change them often and would rather not click through that dialog each time.

If you use another engine, the same sheet works with anything that can read a PNG and a list of rectangles. The JSON guide covers the fields.

Try it

Open the walk starter for a four-frame animation, add a tag called walk across all four frames, and look at the Export sheet. Or the bounce starter, whose squash frame makes a good test of per-frame durations.