Motion
How pixel sprites are animated by code without looking like vector art: a fixed-step tick and frames held unevenly, walk phase from distance snapped to a few poses, code for the soft parts (spines, tails, hair, knees, landings), rotation and squash baked rather than done per frame, and palette cycling, the most on-model animation an indexed engine has. Animation that reads as pixel art changes pose rarely and holds unevenly, and nearly all of it is math per tick over a few drawn or baked poses, rounded to whole pixels only when drawn.
Proposed: none of this is in Tycho yet. The demos run here in the page, written in plain JS with the study’s own kit (demos/kit.js), not Tycho; each says how it would run in Tycho: per frame (the GPU stand-in’s calls), pre-bake (painted once offscreen), or shader (per-pixel work every frame). What would move into Tycho, and when, is in the roadmap.
- Timing
- Gaits
- The soft parts in code
- Rotation and squash are baked
- Palette cycling and sway
- Where it runs
- Sources
Timing
Glenn Fiedler’s fixed-step accumulator steps the simulation by a constant dt, carries the remainder, and clamps long frames to avoid a “spiral of death” (Fix Your Timestep!). On top of that, an animation should be a list of {frame, ticks} driven by the tick count, not the clock (inference). A frame index that is a function of the ticks since the clip began makes animation reproducible and saveable as two integers (inference, from the notes).
Gaits
Walk phase should follow distance traveled, not time, so feet don’t skate, and phase should snap to 4, 6 or 8 poses, since a continuously sliding limb reads as vector art rather than pixels (inference). The games already solve gaits five ways:
| Game | Its walk |
|---|---|
| Under the White Dragon | sin/cos walkN and runN, six poses each (js/people.js) |
| Lodestar | Distance-driven eight-frame kdWalk, with kdIK (js/diver.js) |
| Merryfolk | walk1 and walk2 |
| Neo | A four-frame walk |
| Elsewhere | A two-frame traveler (js/ink.js) |
The soft parts in code
Rain World shows how far code can carry the soft parts: its creator moved the slugcat’s limbs in code “since code is how you make things move in a computer game”, mixing code with traditional animation (Unity blog). For a small engine the core tools are few (inference):
| Tool | For |
|---|---|
| A follow-the-leader point chain with an angle limit | Spines and tails |
| A verlet chain pinned to an anchor | Hair, scarves and capes |
| Two-bone analytic IK | Knees |
| Springs | The pop on a landing |
All of these run in the fixed step and round to whole pixels only when drawn (inference). Lodestar’s Kindler already pairs a skeleton with two-bone IK (see sprites).
Rotation and squash are baked
Rotating or scaling pixel sprites each frame destroys them, so rotations must be baked.
| Method | What it does |
|---|---|
| Scale2x, Scale4x | Scale2x’s four rules preserve edges; Scale4x is Scale2x applied twice (scale2x.it) |
| RotSprite | Upscales that way, rotates with nearest sampling, then downsamples (rotsprite crate) |
| cleanEdge | torcado’s, MIT-licensed: treats pixel art “as if it were a vector drawing” and lets the outline color win ties, but it is a shader (cleanEdge) |
| MMPX | Magnifies 2× “while preserving the exact palette, transparency, and single-pixel features”; processes 64k pixels in under 0.5 ms and ships JavaScript reference code (McGuire and Gagiu 2021) |
All of these pick only existing colors, so baked rotations stay inside an ink limit. Squash and stretch should be baked the same way, by duplicating or dropping rows and columns, because a per-frame scale(1.2, 0.8) creates mixels, pixels of mismatched size (inference). Tycho already ships the Scale2x and Scale3x row scalers that Lodestar uses (sprites).
Palette cycling and sway
Palette cycling is the most on-model animation for an indexed engine. Mark Ferrari animated rain, waves, waterfalls and fog in single 256-color images by rotating palette entries. Joseph Huckaby’s Canvas Cycle made that fast in a browser by recording only the pixels that use cycling entries and redrawing just those, which ran on an iPhone 3GS (Effect Games). Ferrari’s BlendShift mode fades between entries, which adds colors outside the palette (80.lv).
In Tycho, a cycle of K steps over a region becomes K small canvases printed once, plus a per-frame blit of the current phase (inference). The frogs’ pond glints, the lighthouse lamp and a moor bog in Elsewhere are the first uses. None of Tycho’s five games cycles palettes today (the local survey).
Foliage sway works per frame with row strips, where drawImage source rectangles shear a sprite row by row, as Merryfolk’s blitSway does (js/nature.js). It also works as three or four baked lean frames picked by one shared wind function. Either way the offset grows with height and is floored to whole pixels (plants).
Where it runs
Under Tycho’s rules (the renderer), placed by inference from its documented limits:
| Technique family | Where it runs | How |
|---|---|---|
| Frame timing, gait, springs, chains, IK | Stand-in | Math per tick; baked poses; chain nodes as fillRects |
| Rotation of pixel sprites | Pre-bake (shader for live cleanEdge) | Angle caches by RotSprite or MMPX |
| Squash and stretch | Pre-bake | Row and column variants |
| Palette cycling | Pre-bake (CPU buffer for large areas) | K phase canvases, or changed rows via drawPixels |
| Wind sway | Stand-in or pre-bake | Row strips, or lean frames |
Sources
- Glenn Fiedler, Fix Your Timestep!
- Unity blog, the procedural design of Rain World
- Scale2x, the algorithm
- The rotsprite crate
- torcado, cleanEdge
- McGuire and Gagiu 2021, MMPX style-preserving pixel art magnification
- Joseph Huckaby, old-school color cycling with HTML5
- 80.lv, color cycling from the 90s returns
The full research is in the notes on animation; the palette tricks are also in the notes on effects.