Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Pixel art w/ era palettes (NES, Game Boy, PICO-8).
.claude/skills/nousresearch-pixel-art/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 24% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 173% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 81% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 23% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 16% | 0% |
Convert any image into retro pixel art, then optionally animate it into a short MP4 or GIF with era-appropriate effects (rain, fireflies, snow, embers).
Two scripts ship with this skill:
scripts/pixel_art.py — photo → pixel-art PNG (Floyd-Steinberg dithering)scripts/pixel_art_video.py — pixel-art PNG → animated MP4 (+ optional GIF)Each is importable or runnable directly. Presets snap to hardware palettes when you want era-accurate colors (NES, Game Boy, PICO-8, etc.), or use adaptive N-color quantization for arcade/SNES-style looks.
Before generating, confirm the style with the user. Different presets produce very different outputs and regenerating is costly.
Call clarify with 4 representative presets. Pick the set based on what the user asked for — don't just dump all 14.
Default menu when the user's intent is unclear:
pythonclarify( question="Which pixel-art style do you want?", choices=[ "arcade — bold, chunky 80s cabinet feel (16 colors, 8px)", "nes — Nintendo 8-bit hardware palette (54 colors, 8px)", "gameboy — 4-shade green Game Boy DMG", "snes — cleaner 16-bit look (32 colors, 4px)", ], )
When the user already named an era (e.g. "80s arcade", "Gameboy"), skip clarify and use the matching preset directly.
If the user asked for a video/GIF, or the output might benefit from motion, ask which scene:
pythonclarify( question="Want to animate it? Pick a scene or skip.", choices=[ "night — stars + fireflies + leaves", "urban — rain + neon pulse", "snow — falling snowflakes", "skip — just the image", ], )
Do NOT call clarify more than twice in a row. One for style, one for scene if animation is on the table. If the user explicitly asked for a specific style and scene in their message, skip clarify entirely.
Run pixel_art() first; if animation was requested, chain into pixel_art_video() on the result.
| Preset | Era | Palette | Block | Best for | |--------|-----|---------|-------|----------| | arcade | 80s arcade | adaptive 16 | 8px | Bold posters, hero art | | snes | 16-bit | adaptive 32 | 4px | Characters, detailed scenes | | nes | 8-bit | NES (54) | 8px | True NES look | | gameboy | DMG handheld | 4 green shades | 8px | Monochrome Game Boy | | gameboy_pocket | Pocket handheld | 4 grey shades | 8px | Mono GB Pocket | | pico8 | PICO-8 | 16 fixed | 6px | Fantasy-console look | | c64 | Commodore 64 | 16 fixed | 8px | 8-bit home computer | | apple2 | Apple II hi-res | 6 fixed | 10px | Extreme retro, 6 colors | | teletext | BBC Teletext | 8 pure | 10px | Chunky primary colors | | mspaint | Windows MS Paint | 24 fixed | 8px | Nostalgic desktop | | mono_green | CRT phosphor | 2 green | 6px | Terminal/CRT aesthetic | | mono_amber | CRT amber | 2 amber | 6px | Amber monitor look | | neon | Cyberpunk | 10 neons | 6px | Vaporwave/cyber | | pastel | Soft pastel | 10 pastels | 6px | Kawaii / gentle |
Named palettes live in scripts/palettes.py (see references/palettes.md for the complete list — 28 named palettes total). Any preset can be overridden:
pythonpixel_art("in.png", "out.png", preset="snes", palette="PICO_8", block=6)
| Scene | Effects | |-------|---------| | night | Twinkling stars + fireflies + drifting leaves | | dusk | Fireflies + sparkles | | tavern | Dust motes + warm sparkles | | indoor | Dust motes | | urban | Rain + neon pulse | | nature | Leaves + fireflies | | magic | Sparkles + fireflies | | storm | Rain + lightning | | underwater | Bubbles + light sparkles | | fire | Embers + sparkles | | snow | Snowflakes + sparkles | | desert | Heat shimmer + dust |
pythonimport sys import os sys.path.insert(0, os.path.expanduser("~/.hermes/skills/creative/pixel-art/scripts")) from pixel_art import pixel_art from pixel_art_video import pixel_art_video # 1. Convert to pixel art pixel_art("/path/to/photo.jpg", "/tmp/pixel.png", preset="nes") # 2. Animate (optional) pixel_art_video( "/tmp/pixel.png", "/tmp/pixel.mp4", scene="night", duration=6, fps=15, seed=42, export_gif=True, )
bashcd ~/.hermes/skills/creative/pixel-art/scripts python pixel_art.py in.jpg out.png --preset gameboy python pixel_art.py in.jpg out.png --preset snes --palette PICO_8 --block 6 python pixel_art_video.py out.png out.mp4 --scene night --duration 6 --gif
Pixel conversion:
block with Image.NEAREST (hard pixels, no interpolation)N-color palette OR a named hardware palette
Image.NEARESTQuantizing AFTER downscale keeps dithering aligned with the final pixel grid. Quantizing before would waste error-diffusion on detail that disappears.
Video overlay:
libx264 -pix_fmt yuv420p -crf 18palettegen + paletteusepip install Pillow)"NES", "PICO_8", "GAMEBOY_ORIGINAL").source first if it's tiny.
block or palette will break quantization — keep them positive ints.images you may want a second pass with a different seed for density.
mono_green / mono_amber force color=0.0 (desaturate). If you overrideand keep chroma, the 2-color palette can produce stripes on smooth regions.
clarify loop: call it at most twice per turn (style, then scene). Don'tpepper the user with more picks.
Image.open(p).getcolors())ffprobe can open it) with non-zero sizeNamed hardware palettes and the procedural animation loops in pixel_art_video.py are ported from pixel-art-studio (MIT). See ATTRIBUTION.md in this skill directory for details.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 16,392 | 8,153 | -50% | 1 | 1 | 0% | 740 | 3,177 | +329% | 0 | 0 | — |
case-12 | fail→fail | 16,834 | 6,563 | -61% | 1 | 1 | 0% | 4,196 | 2,600 | -38% | 0 | 0 | — |
case-02 | fail→fail | 21,145 | 5,500 | -74% | 1 | 1 | 0% | 4,185 | 2,779 | -34% | 0 | 0 | — |
case-03 | fail→fail | 15,417 | 7,939 | -49% | 1 | 1 | 0% | 3,204 | 2,578 | -20% | 0 | 0 | — |
case-04 | fail→pass | 10,686 | 2,974 | -72% | 1 | 1 | 0% | 2,206 | 2,731 | +24% | 0 | 0 | — |
case-05 | fail→pass | 7,881 | 6,321 | -20% | 1 | 1 | 0% | 1,243 | 3,389 | +173% | 0 | 0 | — |
case-06 | fail→pass | 9,988 | 3,653 | -63% | 1 | 1 | 0% | 1,492 | 2,704 | +81% | 0 | 0 | — |
case-07 | fail→pass | 12,588 | 2,946 | -77% | 1 | 1 | 0% | 2,181 | 2,679 | +23% | 0 | 0 | — |
case-08 | fail→pass | 10,467 | 5,998 | -43% | 1 | 1 | 0% | 2,331 | 2,709 | +16% | 0 | 0 | — |
case-09 | fail→pass | 7,378 | 2,041 | -72% | 1 | 1 | 0% | 1,450 | 2,638 | +82% | 0 | 0 | — |
case-10 | pass→pass | 5,877 | 4,313 | -27% | 1 | 1 | 0% | 1,135 | 3,132 | +176% | 0 | 0 | — |
case-11 | fail→pass | 6,568 | 1,743 | -73% | 1 | 1 | 0% | 1,249 | 2,548 | +104% | 0 | 0 | — |
case-13 | fail→pass | 7,806 | 3,175 | -59% | 1 | 1 | 0% | 1,360 | 2,730 | +101% | 0 | 0 | — |
case-14 | fail→fail | 8,007 | 7,695 | -4% | 1 | 1 | 0% | 1,631 | 2,560 | +57% | 0 | 0 | — |
case-15 | fail→pass | 11,157 | 2,427 | -78% | 1 | 1 | 0% | 2,228 | 2,662 | +19% | 0 | 0 | — |
case-16 | pass→pass | 12,311 | 2,134 | -83% | 1 | 1 | 0% | 1,975 | 2,512 | +27% | 0 | 0 | — |
case-17 | fail→pass | 9,427 | 2,076 | -78% | 1 | 1 | 0% | 1,642 | 2,577 | +57% | 0 | 0 | — |
case-18 | fail→pass | 11,387 | 7,878 | -31% | 1 | 1 | 0% | 1,912 | 3,596 | +88% | 0 | 0 | — |
case-19 | fail→fail | 20,273 | 6,869 | -66% | 1 | 1 | 0% | 2,109 | 2,700 | +28% | 0 | 0 | — |
case-20 | fail→pass | 3,406 | 22,697 | +566% | 1 | 1 | 0% | 432 | 6,703 | +1452% | 0 | 0 | — |
case-21 | pass→pass | 9,698 | 8,572 | -12% | 1 | 1 | 0% | 1,963 | 3,949 | +101% | 0 | 0 | — |
case-22 | pass→pass | 12,933 | 4,921 | -62% | 1 | 1 | 0% | 2,690 | 3,091 | +15% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 18 counted toward the lift figure. The other 4 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +55 percentage points is the difference between those two pass rates over the 18 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 8/8/2026 | +13% |
Other measured skills in the registry, with their headline benchmark lift.