Asset Integration Workflow
Integrate external assets (PixelLab, ElevenLabs) into projects with proper error handling, fallback mechanisms, and testing patterns. Standardizes workflow and reduces integration time by 25-35%.
Overview
Complete workflow for:
- •Asset generation (using async-operation-handler)
- •Asset organization (following project conventions)
- •Integration (preload() method, error handling)
- •Testing (browser verification, fallback mechanisms)
Workflow
Step 1: Asset Generation
Use async-operation-handler for generation:
// Generate asset
const { character_id } = await mcp_pixellab_create_character({
description: "cute wizard with blue robes",
n_directions: 8,
size: 48
});
// Wait for completion with exponential backoff
const character = await pollAsyncOperation(
() => mcp_pixellab_get_character({ character_id }),
{ maxWait: 300000, respectETA: true }
);
Work on integration code while waiting:
// While waiting for asset generation: // 1. Prepare integration code const integrationCode = prepareIntegrationCode(); // 2. Check existing assets const existingAssets = checkExistingAssets(); // 3. Poll for completion const character = await pollAsyncOperation(...);
Step 2: Asset Organization
Follow project conventions:
public/
assets/
sprites/
characters/
wizard-south.png
wizard-north.png
tiles/
grass-tile.png
audio/
music/
bg-music.mp3
sfx/
coin-collect.mp3
Use descriptive file names:
// ✅ GOOD: Descriptive names 'wizard-south-48px.png' 'grass-tile-32px.png' 'bg-music-loop.mp3' // ❌ BAD: Generic names 'image1.png' 'tile.png' 'music.mp3'
Organize by type:
// Organize assets by type
const ASSET_PATHS = {
characters: 'assets/sprites/characters/',
tiles: 'assets/sprites/tiles/',
audio: 'assets/audio/',
music: 'assets/audio/music/',
sfx: 'assets/audio/sfx/'
};
Step 3: Integration
Load assets in preload() method:
// scenes/PreloaderScene.ts
preload() {
// Generated PixelLab assets
this.load.image('wizard-south', 'https://pixellab.ai/characters/abc123/south.png');
this.load.image('wizard-north', 'https://pixellab.ai/characters/abc123/north.png');
this.load.image('wizard-east', 'https://pixellab.ai/characters/abc123/east.png');
this.load.image('wizard-west', 'https://pixellab.ai/characters/abc123/west.png');
// Generated tiles
this.load.image('grass-tile', 'https://pixellab.ai/tiles/xyz789/tile.png');
// Generated map objects
this.load.image('barrel', 'https://pixellab.ai/objects/def456/object.png');
}
Implement try-catch error handling:
preload() {
try {
// Load generated assets
this.load.image('wizard-south', characterUrl);
} catch (error) {
console.warn('Failed to load wizard sprite, using fallback');
this.load.image('wizard-south', 'assets/fallback/wizard.png');
}
}
Add texture existence checks:
create() {
// Check if texture exists before using
if (this.textures.exists('wizard-south')) {
this.wizard = this.add.sprite(100, 100, 'wizard-south');
} else {
// Use fallback
this.wizard = this.add.rectangle(100, 100, 32, 32, 0x00ff00);
console.warn('Wizard texture not found, using placeholder');
}
}
Provide fallback to placeholder graphics:
create() {
if (this.textures.exists('wizard-south')) {
this.wizard = this.add.sprite(100, 100, 'wizard-south');
} else {
// Fallback: Create placeholder rectangle
this.wizard = this.add.rectangle(100, 100, 32, 32, 0x00ff00);
this.wizard.setStrokeStyle(2, 0x000000);
console.warn('Using placeholder for wizard sprite');
}
}
Step 4: Testing
Verify asset loading in browser:
# Open browser agent-browser open http://localhost:3000 # Check for console errors agent-browser console # Verify asset loaded agent-browser eval "window.__TEST__?.gameState()"
Test fallback mechanisms:
// Test fallback by removing asset
// Verify placeholder appears
agent-browser eval "
const scene = window.__TEST__?.getCurrentScene();
scene?.textures?.exists('wizard-south')
"
Check console for warnings:
# Check console for asset loading warnings agent-browser console | grep -i "warn\|error\|failed"
Verify visual rendering:
# Create screenshots folder first (MANDATORY) mkdir -p screenshots/ # Take screenshot to verify visual agent-browser screenshot screenshots/asset-verification.png
Code Search Patterns for Asset References
Verify assets are properly referenced in codebase before runtime testing.
Pattern 1: Search for Asset Filename
Search for asset filename in codebase:
# Search for asset filename grep -r "character.png" src/ grep -r "wizard-south" src/ grep -r "grass-tile" src/ # Search with case-insensitive flag grep -ri "character" src/ # Search in specific file types grep -r "character.png" --include="*.ts" --include="*.js" src/
Pattern 2: Search for Asset Path References
Search for asset path patterns:
# Search for asset path patterns grep -r "assets/sprites" src/ grep -r "assets/audio" src/ grep -r "public/assets" src/ # Search for URL patterns (for PixelLab assets) grep -r "pixellab.ai" src/ grep -r "https://.*\.png" src/
Pattern 3: Search for Preload/Load Methods
Search for asset loading code:
# Search for preload methods grep -r "preload\|load\.image\|load\.audio" src/ # Search for specific asset keys grep -r "load\.image.*wizard" src/ grep -r "load\.audio.*music" src/
Pattern 4: Verify Asset References in Code
Check if asset is referenced in preload/initialization:
// Example: Verify asset is loaded in preload()
// Search for: this.load.image('asset-key', ...)
grep -r "load\.image.*asset-key" src/scenes/
// Example: Verify asset is used in create()
// Search for: this.add.sprite(..., 'asset-key')
grep -r "add\.sprite.*asset-key" src/scenes/
Pattern 5: Framework-Specific Patterns
Phaser Games:
# Search for Phaser asset loading grep -r "this\.load\." src/scenes/ grep -r "this\.textures\.exists" src/scenes/ grep -r "this\.add\.sprite\|this\.add\.image" src/scenes/
React/Web Apps:
# Search for React asset imports grep -r "import.*from.*assets" src/ grep -r "require.*assets" src/ grep -r "\.png\|\.jpg\|\.mp3" src/
Common Integration Points
Check these common locations for asset references:
- •
Preload/Initialization Methods
- •
preload()methods in Phaser scenes - •
useEffecthooks in React - •
componentDidMountin class components
- •
- •
Asset Loading Code
- •
this.load.image()calls - •
this.load.audio()calls - •
importstatements for local assets
- •
- •
Asset Usage Code
- •
this.add.sprite()calls - •
this.add.image()calls - •
<img src="...">tags in React
- •
Runtime Verification Workflow
CRITICAL: Always verify assets work correctly in runtime, not just that they're referenced in code.
Step 1: Verify Asset File Exists
Check asset file exists in correct location:
# Verify asset file exists ls -la public/assets/sprites/character.png ls -la assets/sprites/character.png ls -la src/assets/sprites/character.png # Check file size (should be > 0) stat -f%z public/assets/sprites/character.png # Verify file is readable file public/assets/sprites/character.png
Step 2: Verify Asset Referenced in Code
Use code search patterns above to verify asset is referenced:
# Search for asset references grep -r "character.png" src/ grep -r "load\.image.*character" src/scenes/ # Verify asset key is used grep -r "add\.sprite.*character" src/scenes/
Step 3: Load Application in Browser
Start dev server and open browser:
# Start dev server (if not running) npm run dev # Wait for server to be ready sleep 5 # Open browser agent-browser open "http://localhost:5173?test=1&seed=42"
Step 4: Navigate to Relevant Screen
Navigate to screen where asset should appear:
# For Phaser games: Navigate to scene
agent-browser eval "window.__TEST__.commands.goToScene('GameScene')"
agent-browser wait 500
# For web apps: Navigate to route
agent-browser eval "window.location.href = '/game'"
agent-browser wait 2000
Step 5: Verify Asset Displays Correctly
Check asset is visible and functional:
# Check if texture exists (Phaser)
agent-browser eval "
const scene = window.__TEST__?.getCurrentScene();
scene?.textures?.exists('character-south') || false
"
# Check if sprite is rendered (Phaser)
agent-browser eval "
const scene = window.__TEST__?.getCurrentScene();
const sprite = scene?.children?.getByName('character');
sprite ? { x: sprite.x, y: sprite.y, visible: sprite.visible } : null
"
# Check DOM element exists (Web apps)
agent-browser eval "
document.querySelector('img[src*=\"character\"]') ? true : false
"
Step 6: Verify Asset Functionality
Test asset functionality works as expected:
# Test character movement (if applicable)
agent-browser eval "window.__TEST__.commands.movePlayerTo(100, 200)"
agent-browser eval "window.__TEST__.gameState().player"
# Test asset interaction (if applicable)
agent-browser eval "window.__TEST__.commands.interactWithAsset('character')"
# Verify game state updated correctly
agent-browser eval "window.__TEST__.gameState()"
Step 7: Capture Screenshots for Validation
Capture screenshots for visual validation:
# Create screenshots folder first (MANDATORY) mkdir -p screenshots/ # Capture screenshot agent-browser screenshot screenshots/asset-integration-verification.png # Capture multiple angles if needed agent-browser eval "window.__TEST__.commands.rotateCamera(45)" agent-browser screenshot screenshots/asset-integration-angle2.png
Step 8: Check Console for Errors
Verify no console errors related to asset loading:
# Check console for errors agent-browser console # Filter for asset-related errors agent-browser console | grep -i "asset\|texture\|image\|audio\|failed\|error" # Check for warnings agent-browser console | grep -i "warn"
Complete Runtime Verification Checklist
Before marking asset integration complete, verify:
- • Asset file exists in correct location
- • Asset referenced in code (grep verification)
- • Asset loaded in preload/initialization
- • Application loads without errors
- • Asset displays correctly in runtime
- • Asset functionality works as expected
- • No console errors related to asset
- • Screenshots captured for visual validation
- • Integration verified in actual game/app context
Complete Integration Example
PixelLab Character Integration
// 1. Generate character
const { character_id } = await mcp_pixellab_create_character({
description: "wizard with blue robes",
n_directions: 8,
size: 48
});
// 2. Wait for completion
const character = await pollAsyncOperation(
() => mcp_pixellab_get_character({ character_id }),
{ maxWait: 300000, respectETA: true }
);
// 3. Update preload()
preload() {
// Load all rotations
Object.entries(character.rotations).forEach(([direction, url]) => {
this.load.image(`wizard-${direction}`, url);
});
}
// 4. Use in create()
create() {
// Check texture exists
if (this.textures.exists('wizard-south')) {
this.wizard = this.add.sprite(100, 100, 'wizard-south');
} else {
// Fallback
this.wizard = this.add.rectangle(100, 100, 48, 48, 0x0000ff);
console.warn('Wizard sprite not loaded, using placeholder');
}
}
Error Handling Patterns
Pattern 1: Try-Catch in Preload
preload() {
try {
this.load.image('asset-key', assetUrl);
} catch (error) {
console.warn(`Failed to load asset: ${error.message}`);
this.load.image('asset-key', 'assets/fallback/placeholder.png');
}
}
Pattern 2: Texture Existence Check
create() {
if (this.textures.exists('asset-key')) {
// Use asset
this.sprite = this.add.sprite(x, y, 'asset-key');
} else {
// Use fallback
this.sprite = this.add.rectangle(x, y, 32, 32, 0xff0000);
console.warn('Asset not found, using placeholder');
}
}
Pattern 3: Fallback Graphics
createFallbackSprite(x: number, y: number, color: number) {
const sprite = this.add.rectangle(x, y, 32, 32, color);
sprite.setStrokeStyle(2, 0x000000);
return sprite;
}
Asset Organization Patterns
Pattern 1: By Type
assets/
sprites/
characters/
tiles/
objects/
audio/
music/
sfx/
Pattern 2: By Feature
assets/
game/
characters/
tiles/
menu/
buttons/
backgrounds/
Pattern 3: By Source
assets/
pixellab/
characters/
tiles/
elevenlabs/
audio/
local/
ui/
Testing Patterns
Pattern 1: Browser Verification
# Verify asset loads agent-browser open http://localhost:3000 agent-browser console # Check for errors
Pattern 2: Test Seam Verification
// Add test seam command
window.__TEST__.commands.checkAsset = (key: string) => {
return this.textures.exists(key);
};
// Test in browser
agent-browser eval "window.__TEST__.commands.checkAsset('wizard-south')"
Pattern 3: Fallback Testing
// Test fallback by removing asset // Verify placeholder appears // Check console for warnings
Best Practices
- •Use async-operation-handler for asset generation
- •Work on integration code while waiting
- •Follow project conventions for asset organization
- •Use descriptive file names
- •Load assets in preload() method
- •Implement try-catch error handling
- •Check texture existence before using
- •Provide fallback graphics for missing assets
- •Test in browser to verify loading
- •Check console for warnings
Integration with Other Skills
- •async-operation-handler: Uses for asset generation polling
- •game-asset-pipeline: Complements with pipeline patterns
- •phaser-game-testing: Uses for asset verification testing
Related Skills
- •
async-operation-handler- Async operation polling - •
game-asset-pipeline- Asset generation pipeline - •
phaser-game-testing- Asset verification testing
Remember
- •Generate → Use async-operation-handler
- •Organize → Follow project conventions
- •Integrate → Load in preload(), check existence
- •Test → Verify in browser, check console
- •Fallback → Always provide placeholder graphics