Skip to content

Recipe: Animated water with color cycling

Water ripples, fire glows, glints on metal — animations that look like they have many frames but use only one frame plus palette cycling. A classic technique from 90s adventure games and demoscene art.

![Screenshot: a 32×32 ocean tile with no animation frames, but the preview window shows three palette slots rotating to produce moving ripples — placeholder]

Goal

A single frame of pixel art whose visible colours rotate over time during preview playback. No drawing of in-betweens, no extra frames. Files stay small, the effect is GPU-cheap, and it loops forever.

When this works

  • Effects with localised colour bands: water, fire, glow halos, neon, blinking lights, lava.
  • Indexed palettes only. Cycling is a slot-rotation technique — the editor needs colour indices, not raw RGB. Convert the project to indexed mode first.
  • Tiles or backgrounds, not characters. A walking sprite needs real frames; rippling water doesn't.

Steps

1. Convert the project to indexed mode

Top bar → click the RGB badge → Convert to Indexed. Pick "Use current palette" and decide whether to force-quantize existing pixels.

2. Build the cycle palette

The cycle is a contiguous group of palette slots that will rotate. For water, that's typically 3–6 shades of a single hue arranged darkest → lightest.

Open the Palette panel. Pick three slots that you want in the cycle — say slots 4, 5, 6.

  • Slot 4: dark blue (#1a3a5c)
  • Slot 5: mid blue (#2a5a85)
  • Slot 6: light blue (#5a9bd4)

Paint your water ripples using only these three slots. The shape of the ripples doesn't change during animation — only the colour rotates through the cycle.

3. Create the cycle

Palette panel → Color Cycles section → + New cycle.

In the cycle row:

  • Slot grid: click slots 4, 5, 6 in order. Each gets a numeric badge (1, 2, 3) showing its position in the rotation.
  • Step ms: how fast to rotate. 200ms is a slow ripple; 80ms is a fast bubble. Try 150ms for water.
  • Enable: toggle on.

4. Open the preview window

Top bar → click the preview maximize icon, or press P.

The preview window is the only surface that applies cycling — it rotates the slots in real time using setInterval. Your underlying pixels never change.

5. Tune

  • Wrong direction? The cycle goes "slot 1 → slot 2 → slot 3 → slot 1". Reorder by clicking slots in the cycle in the order you want.
  • Multiple cycles? Add a second cycle for foam highlights (slots 12, 13 at 80ms). They run independently.
  • Indexed-mode safety: if you recolour slot 5 via the palette dialog, every existing water pixel updates AND the cycle still uses slot 5 (the new colour). The cycle is slot-indexed.

6. Export

Cycling is a preview-only effect — the underlying pixels are static. So:

  • PNG / sprite sheet → exports the static colours as they appear in slots.
  • GIF → also static. The exporter doesn't bake cycle rotation into frames.

To get an animated GIF of cycling water, you have two options:

  • Generate frames manually: duplicate the frame as many times as your cycle has steps, then in each duplicate edit the palette so slot 4 holds slot 5's colour, slot 5 holds slot 6's, etc. Tedious but works in any engine.
  • Engine-side cycling: most retro / pixel-art game engines (Phaser shaders, Godot's CanvasItem material) can rotate palette slots at runtime if you ship the static art + a cycle definition. The Aseprite-format JSON sprite sheet export already includes cycle metadata.

Tips

  • Build the ramp deliberately. Don't pick three random shades — pick three that step through luminance like a ramp. The cycle then reads as motion, not glitter.
  • Keep ripples simple. Three pixels of light blue interrupting a sea of dark blue produce a clear "sparkle" frame; complex shapes blur into noise.
  • Combine with onion skin off. Onion skin shows the previous frame ghosted; it doesn't help with cycling because there's only one frame.
  • Don't cycle the whole palette. Cycle 3–6 slots that share a hue. Cycling everything looks like a TV losing signal.

See also

Motestack is a personal hobby project. The editor and these docs ship under no warranty — back up your `.mstack` files.