Written by GuillaumeTechProject Skyfall

Skyfall, part 9: a sprite editor for the blocks and props

November 12, 2026: the third tool. A sprite editor that paints the blocks and props the arenas are made of, shows them in the game's renderer while you paint, saves Aseprite files and brought animated terrain like magma.

The Open dialog of Skyfall's sprite editor on the Objects tab: 15 objects in a grid, among them a wall torch, a frost brazier, a banner, prayer flags and the bottle kiln, selected in gold.

Part 9 of the Skyfall story, and the last of the three tools I built from November 10 to 12. Part 7 covered the track editor and part 8 the map editor. The map editor paints arenas out of blocks and objects. This article covers the tool that paints the blocks and objects themselves: the sprite editor, which landed late on November 12, in one commit of 32 files.

Table of contents

Blocks and objects

The arenas from part 8 are made of two kinds of sprites.

A block is a terrain, like mossy ruin stone or basalt. It’s a single 96 by 64 PNG, an autotile template. Its first rows hold 16 shapes: a 3 by 3 block, a pillar 1 cell wide, a bar 1 cell high and a single block. They come in three variants, A, B and C, so a long wall doesn’t repeat the same tile. The last rows hold the inner corners, a calm filler for cells deep inside a wall, the spills on top (grass and snow, drawn in the empty cell above), and the spills below (drips and icicles). A blank variant falls back to A, and blank spill slots make the spills sparser.

An object is a strip of frames side by side, like a torch, a banner or Embergrove’s bottle kiln.

When the stages arrived, a script generated the block PNGs, and that script was throwaway. The PNGs are now the source of truth, and the sprite editor repaints them in place. Its Open dialog lists the 21 blocks by biome and the 15 objects. A new block starts from a blank template or from a copy of another block. A new object starts from a frame size, a number of frames, and a type: decor or light.

The sprite editor's Open dialog on the Blocks tab: 21 blocks in a grid, each with its name, its id and its biome, among them mossy ruin stone, oak bark, magma, iron grate and rune temple brick. At the bottom, a New block row with an id, a name, a biome and a Blank template menu.
The 21 blocks, in six biomes.

Painting a block

love tools/sprite/editor opens the editor. Like the two others, it’s a standalone LÖVE app with the same pixel-art widgets.

The tools are a pencil, an eraser, a fill, a line, a rectangle, a shade tool, a picker and a selection, with brush sizes 1 to 4. The right button erases. On a block, the fill stays inside its 8 by 8 tile. The shade tool makes a pixel one step lighter along the sprite’s own colours, and the right button makes it one step darker.

Mirror works through the template. Painting a left edge paints the right edge, flipped. Painting the top-left inner corner paints the top-right one. A pillar or a spill mirrors inside its own tile. On an object, Mirror simply flips across the middle.

The Guide labels the template’s rows. It also marks in rust the sides of each shape that face the air, where the rim of the block goes.

The sprite editor with the rune temple brick open at 8x zoom: the 96 by 64 template in blue bricks, with its rows labelled on the left (corners top, sides centre, corners bottom, bar single, inner corners, deep filler, top spills, bottom spills) and its three variants, A, B and C. On the left, the colour panel and the sprite's palette of 15 colours. Below, the timeline with two layers, Runes and Brick, over 4 frames, onion skin on. On the right, Cragspire in the In game preview, the speed at 6 fps, the play order 1 1 1 2 3 4 4 3 2, and the three files that Save writes.
The rune temple brick: 2 layers, 4 frames, and Cragspire in the preview.

The colour panel has a hex field, hue, saturation, value and alpha. With “Recolour the sprite” checked, changing the colour repaints every pixel of that colour, in every unlocked layer and frame, as one undo step. The palette lists the sprite’s colours by ramp, or the colours of another block or object, plus the dark ink every sprite shares, #0b0e1c.

The game in the corner

At the top right, the In game panel draws the unsaved sprite with the game’s stage renderer. It can show a sample patch with every shape of the template, a sample room on a chosen backdrop, or an arena that uses the sprite. The lights are on, and everything animates on the game’s clock. Each stroke shows up in the arena before I save.

Frames and layers

At the bottom, the timeline has a row per layer and a column per frame. The eye hides a layer, and a hidden layer stays out of the PNG. The lock protects a layer from the brush. ”+ Frame” adds a linked copy of the frame: the two frames share their pixels until I paint one of them. The onion skin tints the pixels that change from the frame before, in red, and to the frame after, in blue. Enter plays the animation at the game’s speed and in the game’s order.

An animation has a speed in frames per second and a play order. In an order like “1 2 1 3”, a repeated frame stays on screen longer.

The sprite editor with the bottle kiln open at 6x zoom: a brick kiln 96 by 72 pixels, frame 3 of 6, its glowing coals in the mouth, with the guide marking its map cell. On the right, Embergrove in the preview, the Decor group, the frame size, the anchor, a brazier light with a reach of 150, and the animation at 8 fps with its own play order.
Embergrove's bottle kiln: 6 frames of coals in a 24-step order.

The bottle kiln shows it well: 6 frames of coals, played at 8 fps in a 24-step order, so the flicker doesn’t look like a loop. Each kiln placed in a map also starts at its own point of the order.

Animated terrain

The same commit taught the game to animate terrain. An animated block puts its frames side by side, so its PNG is a multiple of 96 pixels wide, and its line in engine/map/stage/terrains.lua sets a speed and, if needed, a play order. Every cell of that terrain animates in step, on the same clock as the torches. The renderer swaps the texture of each batch of tiles on every frame.

Two blocks use it. Magma is a new lava terrain, with 8 frames at 6 fps, and Embergrove’s floor is made of it. The rune temple brick, from Cragspire’s ziggurat, got a Runes layer over its bricks and 4 frames at 6 fps. Its order, 1 1 1 2 3 4 4 3 2, holds the first frame, plays to frame 4 and back.

The sprite editor with Magma open: an 8-frame block of red lava with a bright orange crust on top, only variant A painted, and a few drops in the bottom spills. On the right, Embergrove in the preview, the Lava biome and the speed at 6 fps, with the frames played 1 to 8 in turn.
Magma, 8 frames at 6 fps, under Embergrove.

Saving: PNG, Aseprite and registry

Ctrl+S writes three things. First, the PNG strip the game reads. Then, <name>.aseprite next to it, when the sprite has several layers or when that file already exists. It keeps the hidden layers and opens in Aseprite and LibreSprite. Last, the sprite’s entry in the registry, terrains.lua for a block or objects.lua for an object, with its speed, play order, width, anchor and light. The other entries stay byte-identical.

The Aseprite part is ase.lua, about 200 lines. It reads RGBA, grayscale and indexed files, with linked cels and hidden groups, and writes RGBA files the way Aseprite does. When I open a sprite, the editor uses the .aseprite file only when it holds the same picture as the PNG, or when it’s the newer file.

Between the two editors

The map editor got an Edit art button. It opens the selected block or object in the sprite editor. The map editor also reloads the art and the registries each time its window gets the focus back. So I paint in one window, save, click on the other, and the arena shows the new art.

Like the two other editors, this one has a self-test, love tools/sprite/editor --selftest. It paints, adds layers and linked frames, recolours, then saves and reloads on a temporary copy of the art. It also reads every .aseprite file in the repository, checks that saving leaves the registries byte-identical, and plays an animated sheet in the renderer.

Where Skyfall stands

  • Still pre-alpha, at version 0.0.0.
  • About 540 commits since January 11, 34 of them from November 10 to 12.
  • About 41,500 lines of Lua in 214 files, up from 27,800 in 153 files on November 9.
  • About 10,300 of those lines are the three editors: about 3,900 for the tracks, 2,600 for the maps and 3,800 for the sprites.

The Skyfall story

  1. From a Defold cube to a fresh start in LÖVE
  2. Wall jumps, a real bow and a quiet network
  3. Rounds, rain, torches and a VHS replay
  4. The War Room and the armory
  5. A map editor, a ghost and the Champion Forge
  6. Pixel-art menus, six arenas and sound at last
  7. A track editor for the music
  8. A map editor that draws with the game
  9. A sprite editor for the blocks and props (this article)