sprite-artist
Skill4 starsChanged 7 months agoMITView on GitHub
Generates pixel-art sprite sheets for a game's entities using GPT Image 2 (gpt-image-2) and emits a manifest (row=entity, col=animation state). Always defaults to low quality; post-processes magenta to alpha via sharp. Falls back to procedural placeholder cells when no API key is available. Use after game-designer has produced entities.
- Reads credentials
In this repository22 other files it gives its agents.
- action-platformerSkill
- audio-composerSkill
- beat-em-upSkill
- bg-artistSkill
- codesmithSkill
- game-designerSkill
- gameforgeSkill
- gap-checkerSkill
- iso-city-builderSkill
- iso-living-worldSkill
- manifest-auditorSkill
- mobile-compat-checkerSkill
- multiplayerSkill
- palette-enforcerSkill
- parallel-qa-orchestraSkill
- physics-debug-validatorSkill
- pixel-action-adventureSkill
- playtesterSkill
- refinerSkill
- rpg-overworldSkill
- tile-artistSkill
- world-architectSkill
The file
We split this skill into the rules it gives an agent
7 rules. About 0 are common, 0 are distinctive, and 7 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 12
After game-designer produces a GDD.
- Very specific: line 49
Read GDD entities from game-state.json.
- Very specific: line 56
Write public/assets/manifest.json (will be merged with tile-artist output later).
- Very specific: line 62
Default provider: fal.ai (https://fal.run/openai/gpt-image-2).
- Very specific: line 66
After generation, post-process: every pixel where R>200 && G<80 && B>200 → alpha=0.
- Very specific: line 99
Call addOutline() once per cell, after all other pixels are drawn.
- Very specific: line 109
Call addOutline() once per cell, after all pixels are drawn, using the two-pass approach above.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Sprite Artist
Turns GDD entities into Phaser-ready sprite sheets and a manifest the codesmith consumes by name. Uses GPT Image 2 (gpt-image-2) — OpenAI's state-of-the-art image generation model — by default. Available via fal.ai (default provider, requires FAL_KEY) or directly through the OpenAI Images API (requires OPENAI_API_KEY).
When to use
After game-designer produces a GDD. The orchestrator passes the entities array; you produce sheets + manifest.
Two modes
| Mode | Trigger | Cost | Output |
| GPT Image 2 | FAL_KEY or OPENAI_API_KEY set, --placeholder not passed | ~$0.01-0.05 per sheet at low quality | Vivid pixel-art sprites |
| Procedural fallback | No key, or --placeholder flag | Free | Flat-color placeholder cells |
Both modes produce identical manifests, so downstream stages don't care which was used.
Manifest contract
Each sheet entry:
{
"sheet": "<absolute path>",
"relSheet": "assets/<filename>.png", // relative to project root, used in Phaser load
"rows": ["<ENTITY_ID>", ...], // top-to-bottom
"cols": ["idle","walk","attack","hurt"], // left-to-right
"cell": <pixel size of one cell>,
"bg": "magenta" | "transparent",
"textureKey": "entities-<N>" // Phaser texture key
}The complete manifest:
{
"sprites": [<entry>, ...],
"tiles": <set by tile-artist>
}Process
- Read GDD entities from
game-state.json. - Decide states-per-sheet: union of
entity.statesacross all entities, ordered as[idle, walk, attack, hurt, run, jump, cast, block, death, victory]then alphabetical for any extras. - Batch entities into sheets of ≤ 9 rows each.
- For each batch:
a. Image-gen mode: shell out to
~/.all-skills/sprite-sheet/scripts/generate.mjswith--bg magenta. Then run chroma-key (magenta → alpha) via sharp. b. Procedural mode: paint acellPx × cellPxcolored cell per (row, col) with state-specific tint/silhouette. - Append entries to
manifest.sprites. - Write
public/assets/manifest.json(will be merged with tile-artist output later). - Update
game-state.jsonassets.sprites.
GPT Image 2 mode details
- Uses GPT Image 2 (
gpt-image-2). Seereferences/gpt-image-2.mdfor endpoint, request shape, and provider options. - Default provider: fal.ai (
https://fal.run/openai/gpt-image-2). Drop-in alternative: OpenAI Images API (https://api.openai.com/v1/images/generations). - Default quality:
low— always start here for prototyping and framework iteration. Bump tomedium/highonly when explicitly asked. - Background MUST be magenta (
#FF00FF) — better chroma key fidelity than black against dark sprites. - Image dimensions must satisfy: multiples of 16; ratio ≤ 3:1; total px ∈ [655360, 8294400]. Auto-pick
cellPxto satisfy. - After generation, post-process: every pixel where
R>200 && G<80 && B>200→alpha=0. Done withsharp.
Visual quality target
The procedural generator targets NES / early GBA pixel art quality — the visual bar set by Double Dragon, Shovel Knight, and Link's Awakening:
- Characters: ellipse-based heads, distinct clothing layers (tunic, belt, boots), visible arms with hands, walk cycle with ±2 px leg offset between frames.
- Outlines: 1-pixel dark border around entire sprite silhouette using the two-pass rule below.
- Cell size: 48 px (gives enough pixels for readable faces, clothing detail, accessories).
- Palette discipline: 4-8 colors per character — highlight, midtone, shadow, outline + 1-2 accent colors.
- Transparent backgrounds: sprite buffers init to
alpha=0; only drawn pixels getalpha=255. The two-pass outline rule below keeps backgrounds clean.
Two-pass outline rule (CRITICAL)
Never draw outline pixels in-place during the same buffer scan that reads opaque pixels — each newly-opaque outline pixel triggers another outline pixel on the next iteration, cascading a dark flood-fill across the entire right/bottom of the cell.
// CORRECT — collect first, draw second:
function addOutline(buf, W, x0, y0, sz, oR, oG, oB) {
const toFill = [];
for (let y = y0; y < y0 + sz; y++)
for (let x = x0; x < x0 + sz; x++) {
if (buf[(y * W + x) * 4 + 3] < 200) continue;
for (const [dx, dy] of [[1,0],[-1,0],[0,1],[0,-1]]) {
const nx = x + dx, ny = y + dy;
if (nx < x0 || nx >= x0 + sz || ny < y0 || ny >= y0 + sz) continue; // clamp to cell
if (buf[(ny * W + nx) * 4 + 3] < 200) toFill.push(nx, ny);
}
}
for (let i = 0; i < toFill.length; i += 2)
pix(buf, W, toFill[i], toFill[i + 1], oR, oG, oB);
}Call addOutline() once per cell, after all other pixels are drawn.
Procedural mode details
- Cell size: 48 px (Phaser scales to display size via
setDisplaySize— cell size doesn't change hitboxes). - Per (entity, state):
- Body color from entity's
color(named-color phrase → hex via lookup, falls back to gray). - Humanoid characters: ellipse head, rectangular torso, arm + leg pairs. Idle = symmetric. Walk = ±2 px leg X offset between the two walk frames.
- Non-humanoid enemies: shape appropriate to description (blob, quadruped, flying creature).
- Eyes for player/enemy/boss/npc kinds.
- Call
addOutline()once per cell, after all pixels are drawn, using the two-pass approach above. - Outline color: darkest shade of character's primary color (not pure black — e.g. dark brown for a tan character).
- Body color from entity's
Scripts
scripts/generate_sheets.mjs <project-dir> [--placeholder] [--quality=low|medium|high]scripts/chroma_key.mjs <png-file>— magenta → alpha post-processor (used internally and exposed for ad-hoc use).
References
references/gpt-image-2.md— GPT Image 2 endpoint, request body, constraints, content-filter notes, provider options (fal.ai default + OpenAI direct).
Dependencies
sharp— image post-processing (npm dep).- External (optional, for full-fidelity prompt template):
~/.all-skills/sprite-sheet/skill provides one battle-tested wrapper. The skill's GPT Image 2 mode also runs without it via the bundled direct-call script.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

