From gamedev
Validates asset manifests against PNGs on disk, probes sprite sheets/tilesets for non-empty grid frames, reports PNG dimensions for 2D game projects like Love2D.
npx claudepluginhub kyh/vibedgamesThis skill uses the workspace's default tool permissions.
Use the bundled scripts in `scripts/` to keep your game's art pipeline consistent and debuggable.
Defines import, slicing, atlas packing, and naming rules for 2D sprite assets. Useful for standardizing sprite sheets, replacing placeholders, and validating new assets in 2D projects.
Exports pixel art sprites from Aseprite to PNG, GIF, spritesheets, and JSON metadata for game engines like Unity, Godot, Phaser. Supports layouts, scaling, and frame exports.
Generates 2D game assets using AI image APIs (DALL-E, Replicate, fal.ai) and prepares sprites, sprite sheets, tilesets for Godot 4.x import. Use for pixel art characters, UI elements, animation frames.
Share bugs, ideas, or general feedback.
Use the bundled scripts in scripts/ to keep your game's art pipeline consistent and debuggable.
Keep a short “worked example” doc in your own repo whenever you establish an asset-index convention.
In this repo, the practical “what worked / what didn’t” notes from building a Love2D asset index live at:
docs/asset-index-learnings.mdKey takeaways to apply when building/managing an asset index:
backgrounds, tilesets, images, spritesheets), not by size alone.columns/rows.{col,row} frames (alpha-based) instead of assuming a full grid.path as the on-disk truth (case + spaces preserved).When importing AI-generated sprite strips or extracted video frames into game-sized animation frames:
01 should match idle height and later frames should remain visibly shorterWhy this matters:
Practical rule:
For strip importers that support explicit scaling modes, prefer:
median-lower for attack, hurt, or other states with upward pose variationfirst-frame for crouch or other enter-and-lower states that begin from an idle-like standing poseFor video-derived animation specifically:
This repo's run-animation experiments established an important distinction:
If an animation looks like it is "skating" or sliding sideways, check these in order:
Nearest-neighbor import preserves pixels. If the in-between poses still look soft after correct normalization, the softness is usually already present in the source frames.
An asset index (manifest) is a structured metadata file that serves as the single source of truth for all game art. It enables:
| Category | Purpose | Key metadata |
|---|---|---|
backgrounds | Parallax/scrolling layers, static backdrops | path, width, height |
tilesets | Grid-based level tiles | path, tileWidth, tileHeight, columns, rows, margin, spacing |
images | Static sprites (no animation) | path, width, height |
spritesheets | Animated sprites | path, frameWidth, frameHeight, fps, frames or animations |
{
"meta": {
"version": 1,
"root": "assets/game",
"defaultFps": 10
},
"backgrounds": {
"clouds": { "path": "Backgrounds/clouds.png", "width": 256, "height": 128 }
},
"tilesets": {
"desert": {
"path": "Tilesets/desert.png",
"width": 192, "height": 96,
"tileWidth": 16, "tileHeight": 16,
"columns": 12, "rows": 6
}
},
"images": {
"deco": {
"bush": { "path": "Deco/bush.png", "width": 32, "height": 16 }
}
},
"spritesheets": {
"enemies": {
"chicken": {
"path": "Enemies/chicken.png",
"width": 224, "height": 64,
"frameWidth": 32, "frameHeight": 32,
"columns": 7, "rows": 2,
"animations": {
"idle": { "fps": 6, "frames": [[0,0], [1,0]] },
"run": { "fps": 10, "frames": [[0,1], [1,1], [2,1], [3,1]] }
}
}
}
}
}
Frames are referenced as [column, row] pairs within the sprite sheet grid:
[0, 0]frameWidth × frameHeight subdivides the imageframes arrayanimations objectasset_sizes.py to get dimensions of all PNGsasset_sheet_probe.py --frame WxH --list to find non-empty cellsasset_manifest_check.py to ensure manifest ↔ disk syncuv)Run from repo root:
# 1) Check manifest coverage (manifest ↔ disk)
uv run .claude/skills/gamedev-assets/scripts/asset_manifest_check.py --manifest path/to/assets_index.lua --root assets
# 1b) Export Lua manifest to portable JSON (recommended for non-Lua engines/tools)
uv run .claude/skills/gamedev-assets/scripts/asset_manifest_export_json.py --manifest path/to/assets_index.lua --out path/to/assets_index.json
# 2) List PNG sizes
uv run .claude/skills/gamedev-assets/scripts/asset_sizes.py --root assets --json tmp/asset_sizes.json
# 3) Probe sprite sheet for non-empty frames
uv run .claude/skills/gamedev-assets/scripts/asset_sheet_probe.py path/to/sheet.png --frame 32x32 --list --json tmp/probe.json
# 4) Debug tilesets / tilemaps with a manifest-driven GUI editor
uv run .claude/skills/gamedev-assets/scripts/asset_tilemap_editor.py --manifest path/to/assets_index.json
Without uv: Python 3.11+ with Pillow installed.
All Python scripts shipped with this skill include PEP 723 metadata (# /// script ...) so uv run <script.py> installs dependencies automatically (no manual pip install steps).
If you have an existing assets_index.lua (Love2D-style), export it to a portable assets_index.json:
uv run .claude/skills/gamedev-assets/scripts/asset_manifest_export_json.py \
--manifest path/to/assets_index.lua \
--out path/to/assets_index.json
By default the exporter rewrites all path entries to be relative to the output manifest folder and sets meta.root to ".", so the resulting folder can be copied/zip'd and still work.
Use the manifest-driven editor to verify:
tileWidth/tileHeight grid math and columns/rowsRun:
uv run .claude/skills/gamedev-assets/scripts/asset_tilemap_editor.py --manifest path/to/assets_index.json
Note: this GUI uses tkinter, which is provided by your Python distribution/OS (it’s not installed via uv/pip).
Headless exports (no tkinter required):
# Export a grid-overlay PNG for a tileset
uv run .claude/skills/gamedev-assets/scripts/asset_tilemap_editor.py \
--manifest path/to/assets_index.json --tileset <tileset_name> \
--export-tileset-grid tmp/tileset_grid.png --label-ids --scale 6 --trim
# Generate a self-test tilemap (all non-empty tiles in-place) and render it
uv run .claude/skills/gamedev-assets/scripts/asset_tilemap_editor.py \
--manifest path/to/assets_index.json --tileset <tileset_name> \
--make-selftest-map tmp/selftest.json
uv run .claude/skills/gamedev-assets/scripts/asset_tilemap_editor.py \
--manifest path/to/assets_index.json --map tmp/selftest.json \
--export-map-render tmp/selftest.png --scale 6 --trim
# Optional: set a background color and fill rectangles behind tiles (useful for concept mockups)
uv run .claude/skills/gamedev-assets/scripts/asset_tilemap_editor.py \
--manifest path/to/assets_index.json --map tmp/selftest.json \
--export-map-render tmp/selftest_bg.png --scale 6 --bg '#77cfd8' --fill-rect '0,40,24,6,#12a7d5'
Controls:
WASD: move palette selection on the tilesetSpace/Enter: paint, X/Backspace: erase[ / ]: switch tileset, +/-: zoom mapF5: quick-save (tilemap.json by default), F9: quick-load (requires --map)G: grid, H: helpasset_manifest_check.py)Verify every PNG on disk appears in manifest and vice versa.
uv run .claude/skills/gamedev-assets/scripts/asset_manifest_check.py
uv run .claude/skills/gamedev-assets/scripts/asset_manifest_check.py --json tmp/coverage.json
asset_manifest_export_json.py)Export assets_index.lua to assets_index.json (portable across engines/tooling):
uv run .claude/skills/gamedev-assets/scripts/asset_manifest_export_json.py --manifest path/to/assets_index.lua --out path/to/assets_index.json
asset_sheet_probe.py)Find non-empty cells in a sprite sheet grid. Essential for building frames arrays.
uv run .claude/skills/gamedev-assets/scripts/asset_sheet_probe.py image.png --frame 32x32
uv run .claude/skills/gamedev-assets/scripts/asset_sheet_probe.py folder/ --frame 16x16 --list --json tmp/probe.json
asset_sizes.py)Get dimensions for all PNGs under a folder.
uv run .claude/skills/gamedev-assets/scripts/asset_sizes.py
uv run .claude/skills/gamedev-assets/scripts/asset_sizes.py --root assets/ --json tmp/sizes.json
asset_tilemap_editor.py)GUI tool for selecting tiles and painting a grid to validate tileset assumptions.
uv run .claude/skills/gamedev-assets/scripts/asset_tilemap_editor.py --manifest path/to/assets_index.json