skills/sprite-sheet/SKILL.md
Sprite sheet and texture atlas production guide for game asset optimization in Rust (Macroquad/Bevy) and Godot. Use when packing sprites, reducing draw calls, generating atlas metadata, or optimizing rendering/memory for HTML5/mobile games. Triggers on sprite sheet, texture atlas, asset packing, draw call optimization, animation frames, and 2D game asset pipeline work.
npx skillsauth add kjaylee/misskim-skills sprite-sheetInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Category: Game Development | Asset Optimization
Tech Stack: Rust (Macroquad, Bevy), Godot 4.x
Created: 2026-02-06
Status: ✅ Complete
Sprite sheets (texture atlases) are essential for efficient game asset management, reducing draw calls, memory usage, and load times by packing multiple sprites into a single texture.
sprite-sheet.png (2048×2048)
├─ player_idle_01 (0, 0, 64, 64)
├─ player_run_01 (64, 0, 64, 64)
├─ enemy_walk_01 (128, 0, 32, 32)
└─ ... (metadata in JSON/XML)
Components:
Loading:
use macroquad::prelude::*;
#[derive(Clone, Copy)]
struct SpriteFrame {
x: f32, y: f32, w: f32, h: f32,
}
impl SpriteFrame {
fn as_rect(&self) -> Rect {
Rect::new(self.x, self.y, self.w, self.h)
}
}
#[macroquad::main("Sprite Demo")]
async fn main() {
let texture = load_texture("assets/spritesheet.png").await.unwrap();
texture.set_filter(FilterMode::Nearest); // Pixel art
let frames = vec![
SpriteFrame { x: 0.0, y: 0.0, w: 64.0, h: 64.0 },
SpriteFrame { x: 64.0, y: 0.0, w: 64.0, h: 64.0 },
];
let mut frame_idx = 0;
let mut timer = 0.0;
loop {
clear_background(BLACK);
// Animation logic
timer += get_frame_time();
if timer > 0.1 {
frame_idx = (frame_idx + 1) % frames.len();
timer = 0.0;
}
// Draw specific frame
let frame = frames[frame_idx];
draw_texture_ex(
&texture,
100.0, 100.0, // destination
WHITE,
DrawTextureParams {
source: Some(frame.as_rect()),
dest_size: Some(vec2(128.0, 128.0)), // scale 2x
..Default::default()
},
);
next_frame().await
}
}
Key Points:
source parameter in DrawTextureParams for sub-rectangleFilterMode::Nearest for pixel art, Linear for smooth spritesserdeSetup:
use bevy::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest())) // pixel art
.add_systems(Startup, setup)
.add_systems(Update, animate_sprite)
.run();
}
fn setup(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut texture_atlases: ResMut<Assets<TextureAtlasLayout>>,
) {
commands.spawn(Camera2dBundle::default());
let texture = asset_server.load("sprites/character.png");
// Define atlas layout (8 columns, 4 rows, each 64×64)
let layout = TextureAtlasLayout::from_grid(
UVec2::new(64, 64),
8, 4,
Some(UVec2::new(2, 2)), // padding
Some(UVec2::new(4, 4)), // offset
);
let atlas_layout = texture_atlases.add(layout);
// Spawn entity with atlas
commands.spawn((
SpriteBundle {
texture,
transform: Transform::from_scale(Vec3::splat(2.0)),
..default()
},
TextureAtlas {
layout: atlas_layout,
index: 0,
},
AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
));
}
#[derive(Component)]
struct AnimationTimer(Timer);
fn animate_sprite(
time: Res<Time>,
mut query: Query<(&mut AnimationTimer, &mut TextureAtlas)>,
) {
for (mut timer, mut atlas) in &mut query {
timer.0.tick(time.delta());
if timer.0.just_finished() {
atlas.index = (atlas.index + 1) % 8; // 8 frames loop
}
}
}
Key Points:
TextureAtlasLayout defines grid or custom rectanglesTextureAtlas component stores current frame indexTimer for frame-based animationMethod A: AtlasTexture (Editor):
atlas to your PNGregion (x, y, w, h)Method B: AnimatedSprite2D:
# res://player.gd
extends AnimatedSprite2D
func _ready():
# Load sprite frames resource (created in editor)
sprite_frames = load("res://assets/player_frames.tres")
animation = "idle"
play()
# player_frames.tres setup:
# 1. Create SpriteFrames resource
# 2. Add animation "idle"
# 3. Import frames from atlas with "Add Frames from Sprite Sheet"
# 4. Specify H/V frames or custom regions
Method C: Code-based Atlas (GDScript):
extends Sprite2D
var atlas_texture: Texture2D
var frames: Array = [
Rect2(0, 0, 64, 64),
Rect2(64, 0, 64, 64),
Rect2(128, 0, 64, 64),
]
var current_frame := 0
var timer := 0.0
func _ready():
atlas_texture = load("res://assets/spritesheet.png")
texture = atlas_texture
func _process(delta):
timer += delta
if timer > 0.1:
current_frame = (current_frame + 1) % frames.size()
region_enabled = true
region_rect = frames[current_frame]
timer = 0.0
Key Points:
AnimatedSprite2D for most cases (editor-friendly)region_enabled + region_rect for manual control| Tool | Platform | Price | Best For | Export Formats | |------|----------|-------|----------|----------------| | TexturePacker | Win/Mac/Linux | Free/$40 | Professional workflows | JSON, XML, Cocos2d, Phaser, Unity | | Aseprite | Win/Mac/Linux | $20 | Pixel art animation | JSON, PNG strips | | Free Texture Packer | Web | Free | Quick web projects | JSON, CSS | | ShoeBox | Adobe AIR | Free | Batch processing | Custom XML/JSON | | Kenney Asset Studio | Win/Mac/Linux | Free | Kenney.nl assets only | PNG, JSON | | Godot Editor | Built-in | Free | Godot projects | .tres (SpriteFrames) |
characters.png (1024×1024, 64 characters)quick-xml or serde_json crateExtraction Script (Unity Editor C#):
using UnityEngine;
using UnityEditor;
using System.IO;
public class SpriteSheetExporter : EditorWindow {
[MenuItem("Tools/Export Sprite Sheet")]
static void Export() {
var sprites = Selection.GetFiltered<Sprite>(SelectionMode.Assets);
if (sprites.Length == 0) return;
var texture = sprites[0].texture;
var path = EditorUtility.SaveFilePanel("Export", "", "spritesheet.png", "png");
// Copy texture to path
File.WriteAllBytes(path, texture.EncodeToPNG());
// Export metadata
var json = "[";
foreach (var s in sprites) {
var r = s.textureRect;
json += $"{{\"name\":\"{s.name}\",\"x\":{r.x},\"y\":{r.y},\"w\":{r.width},\"h\":{r.height}}},";
}
json = json.TrimEnd(',') + "]";
File.WriteAllText(path + ".json", json);
}
}
⚠️ Legal Note: Most Unity Asset Store licenses prohibit redistribution. Use only for private projects or local testing.
1. Create sprites (Aseprite/Photoshop)
2. Export individual PNGs
3. Pack with TexturePacker → atlas.png + atlas.json
4. Load in engine with custom parser or plugin
5. Test on target devices (mobile = critical)
serde_json, quick-xml, rongame-dev-rust-godot/ - Main tech stack documentationAGENTS.md - Asset license policy (Kenney.nl CC0 only for public games)/Volumes/workspace/Asset Store-5.x/ - Local Unity assets (private use only)Last Updated: 2026-02-06
Maintained By: Agent (kjaylee workspace)
testing
게임 아이디어를 검토해 와우 팩터 5개를 추가하고, 스펙→TC→구현→QA→런칭까지 한 번에 밀어붙이는 일일 게임 런칭 써클. 기존 자동 게임 파이프라인을 대체/승격할 때 사용.
data-ai
Advanced YouTube analysis, transcripts, and metadata extraction.
development
Modern web design engineering skills including design tokens, advanced UI/UX methodologies, accessibility, and game-specific UI patterns. Use for building commercial-grade, performant, and accessible web interfaces.
development
Review UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "check accessibility", "audit design", "review UX", or "check my site against best practices".