office-sprite
π―Skillfrom paulrobello/claude-office
office-sprite skill from paulrobello/claude-office
Installation
npx skills add https://github.com/paulrobello/claude-office --skill office-spriteSkill Details
>
Overview
# Office Sprite Generator
Create game-ready sprites for the Claude Office Visualizer using Nano Banana MCP and ImageMagick.
Project Context
The Claude Office Visualizer uses a 45-degree front/top-down perspective (NOT isometric). This means:
- Objects are viewed primarily from the front
- Slight top-down angle shows a bit of the top surface
- You do NOT see multiple side faces like in isometric views
- Similar to classic 2D RPGs or top-down office games
Art Style: Retro 16-bit pixel art with clean edges and limited anti-aliasing.
Workflow
Step 1: Generate with Nano Banana
Use mcpl to call Nano Banana with this prompt template:
```bash
mcpl call nanobanana generate_image '{
"prompt": "[OBJECT DESCRIPTION], front view with slight top-down angle, NOT isometric, pixel art style, retro 16-bit game sprite, isolated on solid magenta background #FF00FF, clean edges, no shadows on background, game sprite asset, centered composition, no text, no watermarks, simple design",
"output_path": "/Users/probello/Repos/claude-office/frontend/public/sprites/[NAME]_raw.png"
}'
```
Prompt Variables:
[OBJECT DESCRIPTION]: Detailed description of the object (e.g., "Office water cooler dispenser with blue water bottle jug on top of white dispenser stand with hot and cold taps")[NAME]: Sprite filename (e.g., "watercooler", "desk", "plant")
Step 2: VALIDATE THE IMAGE
CRITICAL: Before proceeding with ImageMagick processing, you MUST:
- Copy the generated image to the raw location:
```bash
cp "/Users/probello/nanobanana-images/temp_images/[UUID].png" \
"/Users/probello/Repos/claude-office/frontend/public/sprites/[NAME]_raw.png"
```
- View the image using the Read tool to verify:
- Perspective is correct (front view, NOT isometric/3D cube view)
- Subject is centered and fully visible
- Background is solid magenta (may have black letterboxing on sides)
- Art style matches retro pixel art aesthetic
- If the image is NOT correct:
- Regenerate with adjusted prompt
- Do NOT proceed to ImageMagick processing
- Common issues:
- Isometric view: Add "NOT isometric, front facing view" more emphatically
- Wrong style: Specify "16-bit pixel art, retro game sprite" more clearly
- Cut off subject: Add "full object visible, not cropped"
Step 3: Process with ImageMagick
Only after validation passes, remove the magenta background using the helper script:
```bash
# Using the helper script (recommended)
/Users/probello/Repos/claude-office/.claude/skills/office-sprite/scripts/process_sprite.sh \
/Users/probello/Repos/claude-office/frontend/public/sprites/[NAME]_raw.png \
/Users/probello/Repos/claude-office/frontend/public/sprites/[NAME].png
```
The script uses a multi-pass workflow combining FFmpeg and ImageMagick:
- FFmpeg geq filter: Removes pixels where RβB and G is low (purple/magenta hues)
- ImageMagick multi-pass: Catches remaining bright magenta shades (#FF00FF, #CC00CC, etc.)
- ImageMagick dark purple cleanup: Removes dark edge pixels like rgb(32,0,31)
For legacy flood-fill method (faster but may leave pink edges):
```bash
process_sprite.sh input.png output.png --legacy
```
Manual multi-pass workflow (if script unavailable):
```bash
INPUT="/Users/probello/Repos/claude-office/frontend/public/sprites/[NAME]_raw.png"
OUTPUT="/Users/probello/Repos/claude-office/frontend/public/sprites/[NAME].png"
# Step 1: FFmpeg - remove purple hue pixels (RβB, G low)
ffmpeg -y -i "$INPUT" \
-vf "geq=r='r(X,Y)':g='g(X,Y)':b='b(X,Y)':a='if(between(r(X,Y)-b(X,Y),-60,60)lt(g(X,Y),r(X,Y)0.7)lt(g(X,Y),b(X,Y)0.7)*gt(r(X,Y)+b(X,Y),100),0,alpha(X,Y))'" \
-update 1 -frames:v 1 /tmp/step1.png
# Step 2: ImageMagick - remove bright magenta shades
magick /tmp/step1.png -alpha set -channel RGBA \
-fuzz 20% -transparent "magenta" \
-fuzz 15% -transparent "#CC00CC" \
-fuzz 15% -transparent "#880088" \
-fuzz 15% -transparent "#660066" \
/tmp/step2.png
# Step 3: ImageMagick - remove dark purple edge pixels
magick /tmp/step2.png \
-fuzz 8% -fill none \
-opaque "rgb(32,0,31)" \
-opaque "rgb(34,0,31)" \
-trim +repage -strip \
"$OUTPUT"
# Verify transparency
magick "$OUTPUT" -format "Size: %wx%h, Opaque: %[opaque]" info:
```
Why multi-pass? AI-generated images often have anti-aliased edges that blend the subject with the magenta background. Single-pass removal leaves pink/purple fringing. The multi-pass approach targets different shades of magenta/purple for thorough cleanup
Step 4: Verify Final Sprite
View the processed sprite with the Read tool to confirm:
- Clean transparency (no magenta fringing)
- Sprite edges are intact (not eroded)
- Correct dimensions for game use
Step 5: Update Game Code
In OfficeGameV2.tsx, sprites are loaded and displayed like this:
```typescript
// Add texture state
const [spriteTexture, setSpriteTexture] = useState
// Load texture in useEffect
useEffect(() => {
const loadTextures = async () => {
try {
const texture = await Assets.load("/sprites/[NAME].png");
setSpriteTexture(texture);
} catch (e) {
console.warn("Failed to load sprite:", e);
}
};
loadTextures();
}, []);
// Render sprite with fallback to placeholder
{spriteTexture ? (
texture={spriteTexture}
anchor={0.5}
scale={SCALE_FACTOR}
/>
) : (
)}
```
Scale Calculation:
- Target display width / Sprite actual width = scale factor
- Example: For 50px display width with 189px sprite:
scale={50/189}orscale={0.26}
Furniture Reference
Current furniture sizes from furnitureManager.ts:
| Type | Width | Height | Notes |
|------|-------|--------|-------|
| desk | 140px | 80px | With chair position |
| plant | 40px | 40px | Potted plant |
| watercooler | 50px | 50px | Water dispenser |
| filing_cabinet | 60px | 80px | Metal cabinet |
| couch | 120px | 60px | Office couch |
| table | 100px | 60px | Meeting table |
Additional elements from OfficeGameV2.tsx:
| Element | Approx Size | Notes |
|---------|-------------|-------|
| Wall clock | 88x88px | Analog clock face |
| Whiteboard | 330x170px | With todo display |
| Elevator | 128x160px | With doors |
| Safety sign | 140x100px | Days without incident |
Output Location
All sprites go to: /Users/probello/Repos/claude-office/frontend/public/sprites/
[name]_raw.png- Original generated image (keep for reference)[name].png- Processed sprite with transparency
Anti-Patterns
DO NOT:
- Skip the validation step - always view the raw image first
- Use
-transparentinstead of flood fill - it removes ALL matching pixels - Proceed with isometric/wrong perspective images - regenerate instead
- Use white or black as chroma key - they appear in subjects
- Forget to trim - wastes texture memory
DO:
- Always validate before processing
- Use flood fill from corners for clean background removal
- Keep raw images as backup
- Verify final sprite has transparency (
Opaque: False) - Test sprite in game before moving to next asset