Pixel effects
232 code-drawn pixel art effects on one canvas: fire, explosions, magic, hits, weather, pickups and more, recoloured with any of 27 palettes and played at any speed and size.
It's pixelfx, Patch's own pixel effects library (MIT). Every effect is a small piece of code that draws into a low-resolution frame, so it stays sharp when scaled up and can be recoloured, mirrored and reseeded without touching its code. In the live demo, pick an effect on the page, by kind and from its picture, and click the stage to cast it there too, up to eight at once.
Use it in a game
In a browser game (canvas, Phaser, PixiJS, three.js), use the code. It has no dependencies:
import { createFrame, clearFrame, createFx, composite } from './pixelfx/core/index.js';
import * as frostNova from './pixelfx/fx/ice/frost-nova.js';
const frame = createFrame(320, 180); // your game's pixel resolution
const img = new ImageData(320, 180);
const fx = createFx(frostNova, { x: 160, y: 140 }); // also: flip, angle, seed, palette, light...
function tick(dt) {
fx.update(dt);
clearFrame(frame);
fx.draw(frame, 'back'); // behind characters
drawCharacters();
fx.draw(frame, 'front');
composite(frame, img.data, backgroundColor);
ctx.putImageData(img, 0, 0); // scale up with image-rendering: pixelated
}
- Recolour any effect with
palette, a dark-to-bright ramp of hex colours: a fire can burn blue and a heal can glow pink.PALinpixelfx/corehas the 27 ramps the demo's Palette control uses. - Every effect is a file in
pixelfx/fx/<kind>/<name>.js;pixelfx/fx/index.jslists them all. - Other engines (Godot, Unity, GameMaker): pixelfx's own repo renders any effect to a sprite sheet with an
Aseprite-style JSON (
tools/render.mjs). demo.jsshows the whole loop: the frame, a backdrop, the stand-in character, extra casts, and scaling up with sharp pixels.
Controls
The block page talks to the demo over the patch-block message channel (lib/patch-block.js). The frame shows
only the stage, the effect's name in a corner, and click to cast.
For people (the block page shows these):
| id | Control | Type | Range | What it does |
|---|---|---|---|---|
effect | Effect | choice | 232 options in 20 groups, each with a picture; default Campfire | Which of the 232 effects plays, by kind. |
palette | Palette | choice | 28 options; default Its own | Recolours the effect with one of the colour ramps, or keeps its own colours. |
speed | Speed | number | 0.1 to 3 ×, default 1 | How fast it plays: 1 is as made. |
backdrop | Backdrop | choice | Its own, Dark, Floor, Night sky, Light, Black; default Its own | What it plays over: the one it was made for, or another. |
The effect's value is its id in pixelfx (fire/campfire), its label the effect's name, and its group its kind, in
the library's order (Fire, Explosions, Water, Ice, Lightning, Sci-fi, Melee, Impacts, Projectiles, Spawn & death,
Arcane, Holy, Shadow, Status, Nature, Weather, UI, Pickups, Transitions, Critters). The page draws it as a row of
kinds, then the kind's effects as pictures (images: "pixel", so they stay sharp).
Each picture, thumbs/effects/<kind>-<name>.webp, is a short animated WebP drawn by pixelfx itself
(make-thumbs.mjs): the effect at its true pixel size on the dark backdrop (transitions on the light one, since
they wipe with dark ink), cropped to it, scaled up with sharp pixels to 112 x 112. It keeps only the stretch where
the effect shows at least 35% of its peak coverage, so a tile is never empty, at most 20 frames at the effect's own
speed, and its first frame is the peak (a transition's is halfway through the wipe), which is what a still preview
shows. Lossless when it fits in 48 KB, else lossy at high quality. All 232 come to about 7.0 MB, none over 48 KB,
and the page loads them only as they're shown.
Trigger: Replay (again): Plays it again from the start.
For agents (4 more, in recipe.json with every range and default):
| id | Control | Type | Range | What it does |
|---|---|---|---|---|
size | Size | choice | Small, Medium, Large; default Medium | How big the effect shows in the frame. |
mirror | Mirror | toggle | default off | Plays it facing the other way. |
character | Character | toggle | default on | Shows the stand-in character for effects that act on one (slashes, buffs, status). |
seed | Seed | number | 1 to 9999, default 1 | The same effect and seed always play the same way: a new seed plays it a little differently. |
Build it
npm install
npm run build # the pictures (once; needs ffmpeg), recipe.json from pixelfx itself, then dist/ (241 files, ~8.3 MB)
dist/ is the live demo exactly as released, with index.html at the top and nothing loaded from other hosts.
| Path | What |
|---|---|
demo.js, index.html | The demo page (Patch, MIT) |
recipe.json, make-recipe.mjs | The release recipe (mode browser with its block section), written from pixelfx's effects and palettes |
make-thumbs.mjs | Draws the Effect choice's pictures into thumbs/ (gitignored; npm run build -- --thumbs draws them again) |
pixelfx/ | pixelfx's src (core and the 232 effects), unedited, from commit fe7103c |
fonts/ | Funnel Sans and Red Hat Mono, latin 400 and 500 (the page uses Funnel Sans 500 for the effect's name and Red Hat Mono 400 for the tip) |
lib/patch-block.js | Patch's block demo helper, as served at patch.gg/patch-block.js: the block message protocol |
build.mjs, vite.config.mjs | The build |
Credits and licences
- pixelfx: Patch, MIT (
pixelfx/LICENSE).pixelfx/core/sim.jsand the effects that say so at the top of their file adapt Hugo Duprez's open-source pixel art VFX at Sprite Fusion, MIT, © 2026 Hugo Duprez (pixelfx/NOTICE.md; keep it with them). - Fonts: Funnel Sans (The Funnel Project Authors) and Red Hat Mono (The Red Hat Project Authors), SIL Open Font
License 1.1 (
fonts/OFL-*.txt). - The demo page and the pictures of the effects: Patch, MIT.
Code: MIT (LICENSE). Art: the effects are drawn by code, so they are MIT too; the two fonts, used only for the
effect's name and the tip, are OFL 1.1.