0x0funky/generate2dsprite
Generate and postprocess general 2D game assets and animation sheets: pixel-art sprites, clean HD map props, creatures, characters, NPCs, spells, projectiles, impacts, props, summons, and transparent GIF exports. Use when Codex should infer the asset plan from a natural-language request, match a reference or map art style, call built-in `image_gen` for solid-magenta raw sheets, and use the local processor only for chroma-key cleanup, frame extraction, alignment, QC, and transparent exports.
npx skills add https://github.com/0x0funky/agent-sprite-forge --skill generate2dsprite
Use this skill for self-contained 2D sprite or animation assets.
When a larger game or playable prototype needs sprites, use this skill for the visible sprite assets and keep runtime/game assembly separate. Do not replace requested sprite assets with code-drawn placeholders.
Infer these from the user request:
asset_type: player | npc | creature | character | spell | projectile | impact | prop | summon | fxaction: single | idle | cast | attack | shoot | jump | hurt | combat | walk | run | hover | charge | projectile | impact | explode | deathview: topdown | side | 3/4sheet: auto | 2x2 | 2x3 | 2x4 | 3x3 | 3x4 | 4x4 | 5x5 | custom_grid | strip_1x3 | strip_1x4frames: auto or explicit countbundle: single_asset | unit_bundle | spell_bundle | combat_bundle | line_bundle | hero_action_bundle | engine_atlaseffect_policy: all | largestanchor: center | bottom | feetscale_strategy: fit | preservescale_profile: none | create_from_accepted_action | reuse_existingmargin: tight | normal | safeart_style: pixel_art | clean_hd | pixel_inspired | retro_pixel | map_style | project-nativereference: none | attached_image | generated_image | local_filelayout_guide: none | geometry | character_anchorruntime_contract: none | godot_sprite3dworld_height: desired in-engine subject height when a runtime contract is requestedprompt: the user's theme or visual directionrole: only when the asset is clearly an NPC rolename: optional output slugRead references/modes.md when the request is ambiguous.
4x4, 5x5, or custom engine atlas. A raw generated sheet should represent one action family, one continuous sequence, one canonical directional locomotion sheet, or one prop/asset pack.fx, projectile, or impact sheets and layer them in the game.scale_strategy=preserve and align=feet by default. This preserves raw-cell scale, translates frames to a shared feet line, and avoids bbox-fit shrinking from long swords, spears, weapon trails, capes, or wide melee poses.image_gen for every raw image.image_gen.view_image first; do not rely on a filesystem path in the prompt as the visual reference.$generate2dmap or when the user/project requests a different style. Match the map or reference style first.1x4, 1x6, 1x8, or 1xN for characters, players, controllable heroes, creatures, NPCs, enemies, summons, animated props, or any asset where a body/subject must stay centered. Single-row raw generation is too likely to drift horizontally and crop inconsistently.2x2, 6 frames -> 2x3, 8 frames -> 2x4, 9 frames -> 3x3, 12 frames -> 3x4 or 4x3, 16 frames -> 4x4.image_gen to change only the poses. Do not use a grounded anchor sheet for jumps, knockback, airborne motion, projectiles, or FX.fit_scale per action.2x2, 3x3, and 4x4 packs are only for compact props. Do not put platforms, floors, bridges, walls, ladders, gates, doors, long hazards, wide/tall props, collision-bearing objects, or tileset/strip pieces into square prop packs; use one-by-one, 1x3/1x4 strips, custom wide cells, or a tileset-like atlas instead.#FF00FF background rule unless the user explicitly wants a different processing workflow.Pick the smallest useful output.
Examples:
player + player_sheetplayer + hero_action_bundle2x2 for 4 frames2x2 or 2x3 depending on needed frame count2x22x2player + hero_action_bundle2x2 or 2x3, body-onlyfx sheet when the attack needs a wide visual effectimpact sheet when hits need feedbacknpc + single_asset or unit_bundlecreature + idle + 3x3spell_bundleline_bundleUse references/prompt-rules.md.
Choose art_style before writing the prompt:
pixel_art or retro_pixel for classic sprites, 16-bit RPG actors, and requests that explicitly ask for pixel art.clean_hd for map props or assets intended to match clean hand-painted HD maps.pixel_inspired only when the user wants a pixel-adjacent look without retro chunkiness.map_style or project-native when an existing map, game, or reference should define the style.If a reference is involved:
view_image; for freshly generated references, rely on the image already shown in context.Keep the strict parts:
#FF00FF backgroundMixed-action atlas guardrail:
image_gen to generate unrelated action rows in one raw sheet, such as row 1 idle, row 2 run, row 3 shoot, row 4 jump, for a controllable hero or main character.image_gen to generate raw single-row action strips such as 1x4 idle, 1x4 run, 1x4 shoot, or 1x4 jump for a controllable hero, character, creature, NPC, enemy, summon, or animated prop.4x4, 5x5, custom atlas, or row-strip delivery format, generate the action grids separately, process and QC them separately, then assemble the delivery atlas deterministically.Animated body grid guardrail:
1x4 and other raw single-row sheets are not valid defaults for animated bodies. This includes players, controllable heroes, creatures, NPCs, enemies, summons, animated props, and body-attached combat actions.2x2 for 4-frame body actions. This is the default for idle, short attack, shoot body, jump, hurt, hover, and compact side-view walk/run actions.2x3 for 6-frame body actions such as cast, attack, summon, run, charge, or transformation.2x4, 3x3, 3x4, or 4x4 for longer body actions. Prefer a compact grid over a long row.4x4 can remain a raw generation shape because it is a canonical directional locomotion sheet, not four unrelated action rows.edge_touch_frames is empty.Map prop pack guardrail:
2x2, 3x3, and 4x4 raw prop packs only for compact props such as rocks, shrubs, barrels, crates, lamps, small signs, pots, debris, and small ornaments.1x3 or 1x4 strips for repeatable platform/floor assets, with left cap, middle repeat, right cap, and optional slope/corner/end variant.If a layout guide is useful, generate one before calling built-in image_gen:
python scripts/make_layout_guide.py \
--rows <rows> \
--cols <cols> \
--cell-width 384 \
--cell-height 384 \
--output <run-dir>/references/<rows>x<cols>-layout-guide.png
Then make the guide visible in the conversation context and tell image_gen to use it only for invisible slot count, spacing, centering, and safe padding. The output must not reproduce guide boxes, safe-area rectangles, center marks, labels, borders, or guide background.
Use layout guides deliberately:
prop_pack_3x3, prop_pack_4x4, tileset-like atlases, fixed multi-row animation grids, and non-directional 16-frame action sequences such as casting, summoning, charging, death, or transformation3x3 large idle and high-value showcase loops when previous generations drift in scale or spacing4x4 four-direction walk sheets, because the guide can make directional poses too conservative; use it only after an unguided run fails layout or edge safetyFor grounded high-value character actions, an abstract box guide is weaker than a character anchor sheet. After accepting a neutral/idle master frame, create the anchor sheet:
python scripts/make_anchor_layout.py \
--input <accepted-master-frame.png> \
--rows 2 \
--cols 3 \
--cell-width 512 \
--cell-height 512 \
--subject-height-ratio 0.66 \
--feet-ratio 0.82 \
--output <run-dir>/references/attack-anchor-2x3.png
Make both the master frame and anchor sheet visible to built-in image_gen. State that the master locks identity/style and the anchor sheet locks slot positions, camera distance, standing-equivalent scale, body root, feet line, and padding. Ask the model to change only the action poses and never reproduce guides, borders, labels, or separators.
Use built-in image_gen.
Do not use Three.js, Canvas, SVG, HTML/CSS, PIL drawing, or other code-generated art as the raw sprite source. These are acceptable only for runtime display, debug overlays, deterministic layout guides, or postprocessing already-generated images.
After generation:
$CODEX_HOME/generated_images/...Run scripts/generate2dsprite.py process on the raw image.
The processor is intentionally low-level. The agent chooses:
rows / colsfit_scalealignshared_scalecomponent_modecomponent_paddingscale_strategyedge_touch rejection strategyUse the processor to gather QC metadata, not to make aesthetic decisions for you.
For hero action bundles, process each action grid as its own sheet before any final atlas assembly. Use component_mode=largest for body-only hero grids. Use component_mode=all only for projectile, impact, aura, slash FX, or intentionally detached FX sheets, not for fixed-cell hero body attacks that need stable body scale.
Use --scale-strategy preserve --align feet for grounded hero/player body sheets when the raw art already has acceptable scale but bbox-fit would shrink the character because of a long weapon, extended pose, cape, or integrated melee effect. Preserve mode applies one uniform raw-cell-to-output scale to every frame, including one shared safety margin, then translates each detected subject to the shared anchor. It never applies a different bbox-fit scale per frame. Use the default fit strategy for compact bodies, creatures, projectiles, impacts, and intentionally normalized FX.
For a character with multiple actions, write a scale profile only after an accepted reference action passes QC:
python scripts/generate2dsprite.py process \
--input <accepted-run-raw.png> \
--target player --mode run --rows 2 --cols 3 \
--output-dir <run-dir> \
--cell-size 128 --fit-scale 0.80 \
--align feet --scale-strategy preserve --component-mode largest \
--strict-qc --write-scale-profile <bundle>/character-scale-profile.json \
--profile-name <character-name> --max-profile-scale-drift 0.08
Process later actions with --scale-profile <bundle>/character-scale-profile.json. Profile values override per-command scale, anchor, trim, and component defaults so actions cannot silently use different output magnification. Keep using the same generation grid geometry and character anchor sheet when possible; a processing profile cannot repair a model-generated anatomy-scale change.
When integrating a processed grid as a Godot Sprite3D, request a world-height contract instead of hand-tuning each action in the game:
python scripts/generate2dsprite.py process \
--input <raw-sheet.png> \
--target player --mode idle --rows 2 --cols 3 \
--output-dir <action-dir> \
--cell-size 256 --fit-scale 0.84 \
--align feet --scale-strategy preserve --component-mode largest \
--strict-qc --max-body-scale-cv 0.08 --max-anchor-y-std 0.05 \
--duration 125 --godot-world-height 0.70
This writes godot-sprite3d.json beside the frames. The reference action derives recommended_pixel_size from the QC-measured mean subject height and stores it in the scale profile. Later actions processed with that profile reuse the exact pixel size, so crouching, recoil, hurt, and creature silhouette changes remain real pose changes instead of being normalized back to the reference height. The contract also converts the shared output origin to Godot's Sprite3D.offset, lists animation frames, and records timing. Reuse the same world_height and scale profile for every compatible action in one bundle.
After all actions pass QC, build one Godot animation bundle:
python scripts/generate2dsprite.py build-godot-bundle \
--action idle=<bundle>/idle/godot-sprite3d.json \
--action move=<bundle>/move/godot-sprite3d.json \
--action attack=<bundle>/attack/godot-sprite3d.json \
--action hurt=<bundle>/hurt/godot-sprite3d.json \
--default-action idle --one-shot attack --one-shot hurt \
--output <bundle>/godot-sprite3d-bundle.json
The bundle validates cross-action world height and pixel_size, stores relative contract paths, and declares loop versus one-shot playback. Treat a bundle drift failure as an asset-generation or wrong-profile error; do not compensate with per-action runtime scale.
Check:
paste_clamped framesqc_summary.body_scale_cv stay at or below about 0.08 and qc_summary.anchor_y_std at or below about 0.05qc_summary.profile_body_scale_drift stay within the scale profile limit, normally 0.08If not, rerun with different processor settings or regenerate the raw sheet.
Strict QC distinguishes raw source-cell contact from processed output contact. Prefer regeneration when a body part is visibly clipped. If visual review confirms the raw subject is complete and only an antialiased or harmless contour touches the source-cell boundary, use --allow-source-edge-touch; it never permits output-edge contact, paste clamping, or empty frames.
For elongated creature attacks, any paste_clamped_frames or output_edge_touch_frames means the raw sheet must be regenerated with the shared-silhouette-envelope contract above. Do not use --allow-source-edge-touch until clamp and processed-output edge contact are both zero and visual review confirms the full snout, paws, weapon, wings, or tail are intact.
For grounded high-value humanoid player/hero body actions, run strict QC after generation-first scale control:
python scripts/generate2dsprite.py process \
--input <raw-sheet.png> \
--target player \
--mode attack \
--output-dir <out-dir> \
--rows 2 \
--cols 3 \
--align feet \
--scale-strategy preserve \
--component-mode largest \
--strict-qc \
--max-body-scale-cv 0.08 \
--max-anchor-y-std 0.05
These numeric gates are for grounded humanoid body actions, not jumps, knockback, projectiles, impacts, floating actors, creatures whose attack strongly changes silhouette/posture, or intentionally changing-scale FX. A failed gate is a regeneration signal; do not hide generation drift with per-frame scale normalization.
For ground-contact FX, prefer component_mode=largest when detached embers would corrupt the contact anchor. Accept a looser action-specific max_anchor_y_std only after visual review confirms a fixed baseline, zero output-edge contact, zero paste clamping, and correct in-engine placement. Do not loosen the grounded-character defaults globally.
Cross-action scale-profile drift is a generation QC signal. Preserve legitimate crouching, recoil, and compressed pose bboxes; inspect borderline hurt or knockback sheets visually instead of applying per-frame resize. For ordinary idle, run, walk, and grounded body attacks, reject unexplained profile drift.
For a single sheet, expect:
raw-sheet.pngraw-sheet-clean.pngsheet-transparent.pnganimation.gifprompt-used.txtpipeline-meta.jsongodot-sprite3d.json when --godot-world-height is suppliedgodot-sprite3d-bundle.json for a multi-action Godot unitFor player_sheet, expect:
For spell_bundle or unit_bundle, create one folder per asset in the bundle.
For hero_action_bundle, expect:
engine-atlas-transparent.png only after per-action QC passescharacter-scale-profile.json for grounded body actions when cross-action scale consistency mattersidle2x23x3cast -> prefer 2x3projectile -> prefer 2x2 for short animated loops; use row strips only when the engine specifically requires a strip, and assemble that strip after QC when practicalimpact / explode -> prefer 2x2walk4x4 for four-direction walk2x2hero_action_bundle1x4 strip--scale-strategy preserve --align feet instead of bbox-fit normalization2x22x3 for 6-frame actions and 2x4, 3x3, 3x4, or 4x4 for longer actions4x4, 5x5, or custom atlas4x4, 5x5, and custom gridsshared_scale by default for any multi-frame asset where frame-to-frame consistency matterslargest component mode for hero/player body grids; use all for separate FX/projectile/impact sheetsscale_strategy=preserve for grounded hero/player melee attacks with integrated weapons or wide body poses that would shrink under bbox-fit normalization; use fit for normal compact sheets and FXreferences/modes.md: asset, action, bundle, and sheet selectionreferences/prompt-rules.md: manual prompt patterns and containment rulesscripts/generate2dsprite.py: postprocess primitive for cleanup, extraction, alignment, QC, and GIF exportscripts/make_anchor_layout.py: repeat an accepted character frame into a fixed scale/root generation templatescripts/make_layout_guide.py: create abstract geometry-only guides for prop packs and suitable gridsTake 0x0funky/generate2dsprite from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.