Draws game art from code specs: pixel sprites, SVG props and icons, rigged characters, FX, autotiles, layouts and parallax, with QA sheets.
- GitHub stars
- 5,557
- Files
- 42
- Last commit
- Nov 6, 2026
- License
- MIT
- Allowed tools
- —
What does the codeart2d skill do?
codeart2d draws game art from code specs: pixel sprites, SVG props and icons, rigged characters, FX, autotiles, layouts and parallax, with QA sheets.
Summary generated from the skill's SKILL.md.
About the codeart2d skill
Writing game art as text specs is what codeart2d handles: a developer supplies PixelSpec JSON, portable SVG, rig, FX, material, layout or parallax files, and the bundled Python scripts render, check and package the result without any image model. It is meant for teams that explicitly want code-drawn art, or for cases where route_media.py prints no-route (exit 3), meaning no API key or local image or video route exists. The skill states plainly that image generation tools come first for characters, props, maps and FX.
Each job has its own command: render_pixelspec.py for palette-exact sprites, svg_render.py with a palette file for vector props, UI and icons, rig_animate.py for characters with planted feet, fx_build.py for slash and impact effects, autotile_build.py for seam-proven terrain transitions, layout_build.py for top-down maps with collision, parallax_build.py and ambient_bake.py for backgrounds and plate motion. Tools write to a new output directory, refuse an existing one, and print a single JSON summary; --strict-qc publishes nothing on a failed check. Dependencies are numpy and Pillow, plus a rasterizer such as resvg-py for SVG work and node for fx_verify.mjs.
Every result must be labelled code-drawn, with codeart-meta.json recording art_source as code. The limitations are explicit: not for painterly, detailed or likeness art, HD-2D plates, or realistic fire, smoke and water.
What an agent can do with it
- 1Pixel sprite from a PixelSpec fileAsk an AI client to turn a gem PixelSpec into frames and preview images with palette variants and QA reported.
- 2Seam-proven autotile terrain setHave the client build road, path and wall transitions as an autotile set that passes the seam check.
- 3Walking character with planted feetRequest a small rigged character that idles and walks, producing clips and a review sheet.
- 4Top-down map with collisionAsk for a playable top-down layout with roads, props, exits, collision and a debug image to inspect.
- 5Slash and impact FX buildHave the client generate a slash or impact ring effect as baked frames plus a JS runtime module.
Written from the skill's SKILL.md. Every use case is checked against a quote from it.
How to install the codeart2d skill
Each command copies the skill folder into the client's skills directory. Restart the client or start a new session to load it.Install the codeart2d skill in Plugin
/plugin marketplace add 0x0funky/agent-sprite-forge /plugin install agent-sprite-forge@agent-sprite-forge
Install the codeart2d skill in Claude Code
~/.claude/skills/codeart2d/SKILL.md
$ npx degit 0x0funky/agent-sprite-forge/skills/codeart2d ~/.claude/skills/codeart2dInstall the codeart2d skill in Claude Code (project)
.claude/skills/codeart2d/SKILL.md
$ npx degit 0x0funky/agent-sprite-forge/skills/codeart2d .claude/skills/codeart2dInstall the codeart2d skill in Codex
~/.agents/skills/codeart2d/SKILL.md
$ npx degit 0x0funky/agent-sprite-forge/skills/codeart2d ~/.agents/skills/codeart2dInstall the codeart2d skill in Gemini CLI
~/.gemini/skills/codeart2d/SKILL.md
$ npx degit 0x0funky/agent-sprite-forge/skills/codeart2d ~/.gemini/skills/codeart2dInstall the codeart2d skill in Claude.ai
npx degit 0x0funky/agent-sprite-forge/skills/codeart2d codeart2d && zip -r codeart2d.zip codeart2d # claude.ai → Customize → Skills → + → Create skill → Upload a skill → codeart2d.zip
Automated checks
Ran Nov 15, 2026Full report →Passed our automated checks. That is not a security audit: read the scripts before you let an agent run them. How checks work · What to fix for more points
- Source repository linked and reachable0x0funky/agent-sprite-forge/skills/codeart2d is public and reachablegithub.com/0x0funky/agent-sprite-forge/tree/HEAD/skills/code ↗Pass
- Open source license (OSI)MITspdx.org/licenses/MIT.html ↗Pass
- Commit or release in the last yearLast commit 2026-11-06github.com/0x0funky/agent-sprite-forge/commits ↗Pass
- No download-and-run or credential theft in scripts5 of 15 scripts read; none of them downloads and runs code, the rest were not readFinding
- No hidden instructions in SKILL.mdNo override phrases, safeguard switches, credential requests or hidden charactersgithub.com/0x0funky/agent-sprite-forge/blob/HEAD/skills/code ↗Pass
- Pre-approved tools are scopedNo pre-approved tools; the agent asks before using onegithub.com/0x0funky/agent-sprite-forge/blob/HEAD/skills/code ↗Pass
- SKILL.md follows the Agent Skills formatValid name and description; says when to use it; 83 linesgithub.com/0x0funky/agent-sprite-forge/blob/HEAD/skills/code ↗Pass
SKILL.md
View on GitHubCode Art 2D
You write the art as text (PixelSpec JSON, portable SVG, rig, FX, material, layout or parallax
specs); the scripts render, check and package it. No image model is involved. It is a declared art
source (art_source: "code"), not a placeholder.
Use when
- The user explicitly asks for code-drawn art: a PixelSpec or SVG sprite, palette variants drawn in code, a code rig, code FX, a seam-proven autotile set, a code-made layout, stylized parallax or ambient loops.
route_media.pyprintsno-route(exit 3): no API key is configured and no local image or video route exists. Say so, and offer to add a key or a CLI as well.- Pose and layout guides that help an image model (support material, not final art).
Do not use when
- Any art request while an image or video route exists and the user did not ask for code art: generate2dsprite, generate2dmap or video2dsprite generate it.
- Painterly, organic or identity-rich art, likenesses, portraits, HD-2D plates or textured terrain; realistic fire, smoke or water.
- Never trace licensed characters into specs.
Capability check (once per session)
Run python "<skill-dir>/../generate2dmedia/scripts/route_media.py" resolve --kind image (or --kind video): when it names a route, the image or video skill takes the request unless the user asked for code art. forge_doctor.py in the same folder shows the full picture. If encoding.stdout fails, set PYTHONUTF8=1. For SVG work also run svg_render.py doctor --report <new.json> once per machine.
Art source
This skill is the explicit-only last resort of the route order: the API when a key is configured, then the local image tools, then code art, only when the user asks for it or no route exists. Never substitute it silently for generated art. Before you draw, check what code art can and cannot draw well in style-envelope.md (its table describes strengths, not the route order), and tell the user when a request needs an image model. Disclose every result: "code-drawn, no image model" (codeart-meta.json records "art_source": "code"); never present it as image-model output.
Host notes
- Codex: this skill is explicit-only;
image_genandroute_media.pymake the art unless the user asks for code art. Look at review sheets withview_image. - Claude Code: use it only on request or after
no-route. Look at everypreview-*.pngandreview/*.pngwith Read before you report; run tools with Bash;<skill-dir>is${CLAUDE_SKILL_DIR}. - Grok: runs the same Python tools; its native image tools make the art unless the user asks for code art.
Commands
Run each tool as one line from the user's project root: python "<skill-dir>/scripts/<tool>.py" .... <skill-dir> is this skill's folder; sibling skills sit beside it (--build-clips calls <skill-dir>/../generate2dsprite/scripts/build_animation_clips.py). Keep specs and outputs inside the project. Every tool writes a new --output-dir: it refuses an existing one and publishes only a complete result; with --strict-qc a failed check publishes nothing. Success prints one JSON line; errors print error: ... and exit 1; usage errors exit 2. Examples to copy: examples/.
Dependencies: numpy and Pillow for everything; PixelSpec rendering and pixel_qa.py need nothing else. SVG art also needs one rasterizer: resvg-py (python -m pip install "resvg-py>=0.5,<0.6", preferred), the resvg-js CLI on PATH, or Chrome/Edge (set CHROME_PATH) (rasterizers.md). Never PyMuPDF, skia-python or cairosvg: they silently ignore crispEdges, <style>, clipPath or gradients. fx_verify.mjs needs node.
Hello sprite
- Write
gem.pixelspec.json(the "Hello sprite" block in pixelspec.md). python "<skill-dir>/scripts/render_pixelspec.py" --spec gem.pixelspec.json --output-dir out/gem-v1 --preview-scale 8 --strict-qc- Open
out/gem-v1/preview-x8.png; the frames are inout/gem-v1/<variant>/frames/. - Tell the user it is code-drawn (no image model).
Pipeline
| Need | Route |
|---|---|
| Pixel character, prop or FX with palette variants | PixelSpec (pixelspec.md), then render_pixelspec.py --spec <spec> --output-dir <new> --build-clips --strict-qc; review with pixel_qa.py |
| Flat vector character, prop, UI or icon set | portable SVG with palette classes (svg-profile.md), then svg_render.py render --svg <svg> --palette <palette.json> --output-dir <new> --zoom N |
| Crisp pixel art drawn with SVG shapes | svg_render.py render --crisp --zoom N --strict-qc |
| Check an SVG before rendering | svg_render.py lint --svg <svg> --profile portable (add --compile --palette <p>) |
| Small character that walks, idles or attacks with planted feet | rig SVG plus a rig_anim.v1 file (rig-animation.md), then rig_animate.py --rig <svg> --anim <json> --output-dir <new> --build-clips --strict-qc; look at review/*.png |
| Slash, sparks, impact ring, hit flash, dust, projectile | fx.v1 spec (fx-language.md), then fx_build.py --spec <json> --output-dir <new> --build-clips --export-runtime; baked frames for pixel games, fx-runtime.mjs for gameplay-timed FX (fx-runtime-contract.md) |
| Check an fx.v1 runtime | node "<skill-dir>/scripts/fx_verify.mjs" <module.mjs> --report <file> |
| Terrain transitions, roads meeting water, paths over ground, walls and ledges | material spec, then autotile_build.py --material-spec <json> --output-dir <new> --strict-qc (Wang-16, three materials, blob-47, bevel; tiles-and-maps.md) |
| An image-tool texture inside exact tile masks | autotile_build.py --material-texture NAME=PATH --quantize-textures (one tile that wraps) |
| Playable top-down map: roads, props, exits, collision, reachability | layout_build.py --spec <layout.json> --output-dir <new> --preview --strict-qc (--tiles <tileset manifest> for real tiles); open debug.png (layouts-and-parallax.md) |
| Stylized parallax background | parallax_build.py --spec <parallax.json> --output-dir <new> --validate --sweep-frames 49; review sweep-sheet.png |
| Ambient motion on a static plate | ambient_bake.py --plate <png> --spec <effects.json> --output-dir <new> --preview --strict-qc; encode with generate2dmap scene_motion.py |
| QA any pixel frames | pixel_qa.py --input "<glob>" --palette <palette, spec or codeart-meta.json> --review <new.png> --onion --strict --report <new.json> |
Hand-offs: clips go to generate2dsprite export_engine.py (never generate2dsprite.py process); a layout's map_bundle.v2 goes to generate2dmap map_bundle.py validate, map_nav.py check and export_tiled.py / export_godot.py / export_ldtk.py.
Rules
- SVG (portable profile, enforced by lint): root width and height equal an integer viewBox (1 unit = 1 logical pixel); colours via
class="c-NAME"; bones rotate withtransform="rotate(a cx cy)"; no<text>,<image>, feTurbulence, feDisplacementMap or mix-blend-mode; pixel art addsshape-rendering="crispEdges"and no gradients, masks, filters or opacity. - Tilesets are seam-proven before they are published: tiles assembled from the atlas are compared pixel for pixel with an independent global render over every adjacency the set allows.
--strict-qcnever passes without that proof. - Fold empty FX tail frames before building clips; the builder refuses fully transparent frames.
- Side-view walk and run cycles: give the near and far legs a clear value contrast (the far leg two or more shades darker, never two darks that read alike) and keep the arms or forelegs visible (not hidden under a scarf, cape or bag).
render_pixelspec.pywarnshalf_cycle_duplicateswhen frame i and i+n/2 of a walk/run clip share a silhouette (IoU >= 0.95); fix the legs, or pass--allow-duplicate-half-cycleonly after the review sheet shows the stride reads. - generate2dsprite
sheet_qc.py frameson code-drawn frames (art_source=code):identity_residualandtorso_driftare advisory, since the head and root are fixed in code; judge them by eye, and treatnear_duplicatesandleg_alternationas real.
Acceptance
Look at the preview and review sheets at game size and 1x before reporting (style-envelope.md has the review loop). Quote the QA status and failed checks from the JSON summary.
Report every WARN or FAIL check verbatim (id, value, threshold, files) from each published QA envelope; never say "all checks passed" when any published envelope has a warn. Deliver specs, rendered frames or tiles, clips or bundles, codeart-meta.json and the disclosure line. Data contracts: references/schemas/codeart.schema.json.
Files in this skill
42codeart2d skill questions
How do I install the codeart2d skill in Claude Code?
Run npx degit 0x0funky/agent-sprite-forge/skills/codeart2d ~/.claude/skills/codeart2d. Claude Code loads skills from ~/.claude/skills (all projects) or .claude/skills (one project) and uses a skill when its description matches the task.
Which clients can use the codeart2d skill?
Any client that reads the Agent Skills format: Claude Code, Codex, Gemini CLI and claude.ai (upload as a ZIP). Scripts in the skill run only where the client allows code execution.
When should I use codeart2d instead of an image model?
Only when the user explicitly asks for code-drawn art, or when route_media.py reports no-route (exit 3) because no image or video route exists. It is never the default.
What kinds of game art can codeart2d make?
Pixel sprites from a PixelSpec, flat vector props, UI and icons in portable SVG, rigged characters, FX, seam-proven autotiles, top-down layouts and stylized parallax.
Do I have to tell users the art is code-drawn?
Yes. Every result must be disclosed as code-drawn with no image model, and never presented as image-model output.
What art styles does codeart2d not handle well?
Painterly, detailed or likeness art, HD-2D plates, textured terrain and realistic fire, smoke or water need an image model instead.