workshop

← all creations

Mech Strider

sprites · created 2026-08-21

32×32 bipedal mech sprite — 2-frame idle, 4-frame walk cycle, two team palettes, drawn from editable character maps.

pixel-artcanvas

A front-facing bipedal walker: visor cockpit with an antenna, slab pauldrons over tapered forearms, a pulsing reactor core in the chest, and heavy piston legs. Six frames — a 2-frame idle bob and a 4-frame walk cycle — in two team palettes (steel and crimson).

Reuse

Pull PNGs straight from export/, or import the module and paint frames directly.

Render at integer scales with nearest-neighbor filtering or the edges smear. Walk plays at 8 fps, idle at 2 fps (ANIMATIONS in the module carries both).

The mech is symmetric enough to flip horizontally for facing — the antenna and the teal muzzle on one forearm are the only asymmetries, and they read fine mirrored. paintFrame(ctx, name, { flip: true }) does it.

Source

No .aseprite — the canonical source is source/mech-sprite.mjs: a framework-free ES module holding the pixel grids as character maps (one char per pixel, palette at the top). Edit a grid and regenerate everything with:

node source/render.mjs

(needs site/node_modules installed — the script resolves Playwright from there.) That one command rewrites export/, media/, thumb.png, and the demo’s bundled copy of the module, so nothing drifts.

How the frames are built

A frame is two layers composited on the 32×32 canvas: a leg pose drawn first (anchored at a fixed LEG_Y — the legs are the ground contact), then the torso drawn over it at the frame’s bob offset. The torso’s waist is transparent, so the hips show through and a bobbing torso overlaps the hips instead of tearing a gap. That’s why the walk cycle needs only three leg grids (stand, stepL, stepR) rather than six full-body ones, and why a new pose is cheap to add.

The reactor core (E cells) picks its color from the frame’s core: 'hot' | 'dim' rather than living in a second copy of the grid — that’s the pulse in the idle loop. Team palettes work the same way: one grid, a swapped color table.

Gotchas

Port notes

paintFrame is ~20 lines of grid walking with no DOM dependency beyond a 2D context, so DragonRuby ports translate directly: keep the grids as strings, map cells to args.outputs.solids, or just consume mech-sheet.png as a spritesheet with source_x = frame * 32.