# API Reference Complete API reference for all asset systems in the Game Arcade platform. ## Table of Contents 1. [AssetManager](#assetmanager) 2. [MusicEngine](#musicengine) 3. [BackgroundEngine](#backgroundengine) 4. [AvatarSystem](#avatarsystem) 5. [ContextRenderer](#contextrenderer) 6. [ContextCatalog](#contextcatalog) 7. [AssetCatalog](#assetcatalog) 8. [AssetPresets](#assetpresets) 9. [AssetCompatibility](#assetcompatibility) 10. [Common Patterns](#common-patterns) 11. [Troubleshooting](#troubleshooting) --- ## AssetManager Main coordinator for all asset systems. Provides unified access to music, backgrounds, avatars, and contexts. ### Properties | Property | Type | Description | |----------|------|-------------| | `initialized` | boolean | Whether the manager has been initialized | | `stats` | Object | Statistics about loaded assets | ### Methods #### initialize() ```javascript AssetManager.initialize(options) → Promise<{stats}> ``` Initialize all asset systems. Call once at startup before using any other asset methods. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `options` | Object | No | Configuration options | | `options.preloadMusic` | boolean | No | Preload all music (default: false) | | `options.preloadBackgrounds` | boolean | No | Preload background assets (default: true) | | `options.cacheAvatars` | boolean | No | Enable avatar caching (default: true) | | `options.maxCacheSize` | number | No | Maximum cache entries (default: 100) | **Returns:** `Promise` - Stats object with loaded asset counts **Example:** ```javascript const stats = await AssetManager.initialize({ preloadMusic: false, preloadBackgrounds: true }); console.log(stats.music.songs); // 160 console.log(stats.backgrounds.themes); // 12 console.log(stats.avatars.parts); // 340 console.log(stats.contexts.total); // 44 ``` --- #### getRecommendations() ```javascript AssetManager.getRecommendations(gameStyle, keywords, mood) → Array ``` Get asset recommendations based on game description. Returns the top 3 matching asset combinations. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `gameStyle` | string | Yes | One of the 11 game styles | | `keywords` | string\|Array | Yes | Description text or keyword array | | `mood` | string | No | Override auto-detected mood | **Valid Game Styles:** - `action-arcade` - `puzzle-logic` - `adventure-story` - `educational` - `simulation` - `sports-racing` - `strategy` - `rhythm-music` - `horror-survival` - `casual-relaxing` - `multiplayer-party` **Valid Moods:** - `Epic` - `Chill` - `Dark` - `Upbeat` - `Mysterious` - `Retro` - `Dramatic` - `Peaceful` **Returns:** `Array` - Top 3 recommendations **Recommendation Object:** ```javascript { config: { music: { mood: string, songId: string }, background: { theme: string, variant: string }, context: { id: string, variant: string } }, score: number, // 0-100 match score explanation: string // Human-readable explanation } ``` **Example:** ```javascript const recs = AssetManager.getRecommendations( 'action-arcade', 'space shooter aliens lasers explosions', 'Epic' ); console.log(recs[0]); // { // config: { // music: { mood: 'Epic', songId: 'epic-battle-04' }, // background: { theme: 'space', variant: 'nebula' }, // context: { id: 'shooter-standard', variant: 'default' } // }, // score: 94, // explanation: 'Space theme with epic music matches action shooter keywords' // } ``` --- #### findPreset() ```javascript AssetManager.findPreset(name) → Preset | null ``` Find a named preset by exact name or partial match. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `name` | string | Yes | Preset name (case-insensitive) | **Returns:** `Preset | null` - Matching preset or null if not found **Preset Object:** ```javascript { id: string, name: string, description: string, config: { music: { mood: string, songId?: string }, background: { theme: string, variant: string, effects?: Array }, context: { id: string, variant?: string } }, tags: Array, gameStyles: Array } ``` **Example:** ```javascript const preset = AssetManager.findPreset('retro-platformer'); if (preset) { await AssetManager.loadGameAssets(preset.config); } ``` --- #### loadGameAssets() ```javascript AssetManager.loadGameAssets(config) → Promise ``` Load and prepare all assets for a game based on configuration. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `config` | Object | Yes | Asset configuration object | | `config.music` | Object | No | Music configuration | | `config.music.mood` | string | No | Music mood category | | `config.music.songId` | string | No | Specific song ID | | `config.background` | Object | No | Background configuration | | `config.background.theme` | string | Yes | Background theme | | `config.background.variant` | string | Yes | Theme variant | | `config.background.effects` | Array | No | Visual effects to apply | | `config.context` | Object | No | Context configuration | | `config.context.id` | string | Yes | Context ID | | `config.context.variant` | string | No | Context variant | **Returns:** `Promise` - Object containing loaded asset references **LoadedAssets Object:** ```javascript { music: { song: Song, ready: boolean }, background: { theme: Theme, variant: Variant, renderFn: Function }, context: { context: Context, sprites: Map } } ``` **Example:** ```javascript const assets = await AssetManager.loadGameAssets({ music: { mood: 'Upbeat' }, background: { theme: 'nature', variant: 'forest' }, context: { id: 'platformer-standard' } }); // Start music MusicEngine.playSong(assets.music.song.id); // Use in game loop function render(time) { assets.background.renderFn(ctx, width, height, time); } ``` --- #### validateCombination() ```javascript AssetManager.validateCombination(config) → ValidationResult ``` Validate that an asset combination is compatible and complete. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `config` | Object | Yes | Configuration to validate | **Returns:** `ValidationResult` ```javascript { valid: boolean, errors: Array, warnings: Array, suggestions: Array } ``` **Example:** ```javascript const result = AssetManager.validateCombination({ music: { mood: 'Epic' }, background: { theme: 'nature', variant: 'peaceful-meadow' }, context: { id: 'shooter-standard' } }); console.log(result); // { // valid: true, // errors: [], // warnings: ['Epic music may not match peaceful background'], // suggestions: ['Consider using "forest" variant for better mood match'] // } ``` --- #### describeAssets() ```javascript AssetManager.describeAssets(config) → AssetDescription ``` Get human-readable descriptions of an asset configuration. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `config` | Object | Yes | Asset configuration | **Returns:** `AssetDescription` ```javascript { summary: string, music: { name: string, description: string, mood: string, tempo: string }, background: { name: string, description: string, colors: Array }, context: { name: string, description: string, animations: Array } } ``` **Example:** ```javascript const desc = AssetManager.describeAssets({ music: { songId: 'epic-battle-04' }, background: { theme: 'space', variant: 'nebula' }, context: { id: 'shooter-standard' } }); console.log(desc.summary); // "Epic orchestral music with a colorful space nebula background, // featuring a shooter-style player with laser animations" ``` --- #### getVariation() ```javascript AssetManager.getVariation(config, variationType) → Object ``` Get a variation of the current configuration. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `config` | Object | Yes | Current configuration | | `variationType` | string | No | Type of variation (default: 'similar') | **Variation Types:** - `similar` - Same mood/theme, different specific assets - `contrast` - Opposite mood, complementary visuals - `random` - Random compatible combination - `seasonal` - Seasonal variation if available **Returns:** `Object` - New configuration object **Example:** ```javascript const original = { music: { mood: 'Epic' }, background: { theme: 'castle', variant: 'throne-room' } }; const variation = AssetManager.getVariation(original, 'similar'); // Returns different Epic song, different castle variant ``` --- #### searchAssets() ```javascript AssetManager.searchAssets(query, options) → SearchResults ``` Search across all asset types. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `query` | string | Yes | Search query | | `options` | Object | No | Search options | | `options.types` | Array | No | Asset types to search (default: all) | | `options.limit` | number | No | Maximum results per type (default: 10) | | `options.includeMetadata` | boolean | No | Include full metadata (default: false) | **Valid Types:** `['music', 'background', 'context', 'preset']` **Returns:** `SearchResults` ```javascript { music: Array, backgrounds: Array<{theme, variant}>, contexts: Array, presets: Array, totalCount: number } ``` **Example:** ```javascript const results = AssetManager.searchAssets('forest', { types: ['background', 'music'], limit: 5 }); console.log(results.backgrounds); // [{ theme: 'nature', variant: 'forest' }, // { theme: 'nature', variant: 'enchanted-forest' }] ``` --- #### getRandomCombination() ```javascript AssetManager.getRandomCombination(constraints) → Object ``` Generate a random compatible asset combination. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `constraints` | Object | No | Constraints for random selection | | `constraints.mood` | string | No | Required mood | | `constraints.gameStyle` | string | No | Required game style compatibility | | `constraints.excludeThemes` | Array | No | Themes to exclude | | `constraints.excludeContexts` | Array | No | Contexts to exclude | **Returns:** `Object` - Random configuration **Example:** ```javascript const random = AssetManager.getRandomCombination({ mood: 'Upbeat', gameStyle: 'casual-relaxing', excludeThemes: ['horror', 'space'] }); ``` --- ## MusicEngine Procedural music synthesis using Tone.js. Generates and plays dynamic music in various moods and styles. ### Properties | Property | Type | Description | |----------|------|-------------| | `isPlaying` | boolean | Whether music is currently playing | | `currentSong` | Song\|null | Currently playing song | | `volume` | number | Current volume (0-1) | | `muted` | boolean | Whether audio is muted | ### Methods #### initialize() ```javascript MusicEngine.initialize() → Promise ``` Initialize the music engine. Called automatically by AssetManager. **Example:** ```javascript await MusicEngine.initialize(); ``` --- #### playRandomSong() ```javascript MusicEngine.playRandomSong(mood) → string ``` Play a random song from the specified mood category. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `mood` | string | Yes | Mood category | **Valid Moods:** `Epic`, `Chill`, `Dark`, `Upbeat`, `Mysterious`, `Retro`, `Dramatic`, `Peaceful` **Returns:** `string` - ID of the song that started playing **Example:** ```javascript const songId = MusicEngine.playRandomSong('Epic'); console.log(`Now playing: ${songId}`); ``` --- #### playSong() ```javascript MusicEngine.playSong(songId) → boolean ``` Play a specific song by its ID. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `songId` | string | Yes | Unique song identifier | **Returns:** `boolean` - True if song started playing, false if not found **Example:** ```javascript if (MusicEngine.playSong('epic-battle-04')) { console.log('Song started'); } else { console.log('Song not found'); } ``` --- #### stopMusic() ```javascript MusicEngine.stopMusic() → void ``` Stop the currently playing music immediately. **Example:** ```javascript MusicEngine.stopMusic(); ``` --- #### pauseMusic() ```javascript MusicEngine.pauseMusic() → void ``` Pause the currently playing music. Can be resumed with `resumeMusic()`. **Example:** ```javascript MusicEngine.pauseMusic(); ``` --- #### resumeMusic() ```javascript MusicEngine.resumeMusic() → void ``` Resume paused music. **Example:** ```javascript MusicEngine.resumeMusic(); ``` --- #### setVolume() ```javascript MusicEngine.setVolume(level) → void ``` Set the music volume. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `level` | number | Yes | Volume level (0-1) | **Example:** ```javascript MusicEngine.setVolume(0.7); // 70% volume ``` --- #### getVolume() ```javascript MusicEngine.getVolume() → number ``` Get the current volume level. **Returns:** `number` - Current volume (0-1) --- #### mute() ```javascript MusicEngine.mute() → void ``` Mute audio without changing volume setting. --- #### unmute() ```javascript MusicEngine.unmute() → void ``` Unmute audio, restoring previous volume. --- #### fadeOut() ```javascript MusicEngine.fadeOut(duration) → Promise ``` Gradually fade out the music. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `duration` | number | No | Fade duration in milliseconds (default: 1000) | **Returns:** `Promise` - Resolves when fade completes **Example:** ```javascript await MusicEngine.fadeOut(2000); // 2 second fade MusicEngine.playRandomSong('Dark'); ``` --- #### fadeIn() ```javascript MusicEngine.fadeIn(songId, duration) → Promise ``` Start a song with a fade in effect. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `songId` | string | Yes | Song to play | | `duration` | number | No | Fade duration in ms (default: 1000) | **Returns:** `Promise` - Resolves when fade completes **Example:** ```javascript await MusicEngine.fadeIn('peaceful-meadow-02', 1500); ``` --- #### crossfade() ```javascript MusicEngine.crossfade(songId, duration) → Promise ``` Crossfade from current song to a new song. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `songId` | string | Yes | Song to crossfade to | | `duration` | number | No | Crossfade duration in ms (default: 2000) | **Returns:** `Promise` - Resolves when crossfade completes **Example:** ```javascript await MusicEngine.crossfade('epic-battle-04', 1500); ``` --- #### getCatalog() ```javascript MusicEngine.getCatalog() → Array ``` Get all available songs. **Returns:** `Array` - All songs in the catalog **Song Object:** ```javascript { id: string, name: string, mood: string, tempo: number, // BPM duration: number, // seconds instruments: Array, tags: Array, intensity: number // 1-10 } ``` **Example:** ```javascript const songs = MusicEngine.getCatalog(); console.log(`Total songs: ${songs.length}`); // 160 ``` --- #### findSongs() ```javascript MusicEngine.findSongs(filters) → Array ``` Find songs matching specified filters. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `filters` | Object | Yes | Filter criteria | | `filters.mood` | string | No | Filter by mood | | `filters.minTempo` | number | No | Minimum tempo (BPM) | | `filters.maxTempo` | number | No | Maximum tempo (BPM) | | `filters.instruments` | Array | No | Required instruments | | `filters.tags` | Array | No | Required tags (any match) | | `filters.intensity` | number\|Array | No | Exact or [min, max] range | **Returns:** `Array` - Matching songs **Example:** ```javascript const songs = MusicEngine.findSongs({ mood: 'Epic', minTempo: 120, intensity: [7, 10] }); ``` --- #### getSongsByMood() ```javascript MusicEngine.getSongsByMood(mood) → Array ``` Get all songs in a specific mood category. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `mood` | string | Yes | Mood category | **Returns:** `Array` - Songs in that mood **Example:** ```javascript const epicSongs = MusicEngine.getSongsByMood('Epic'); console.log(`Epic songs: ${epicSongs.length}`); // 20 ``` --- #### getMoods() ```javascript MusicEngine.getMoods() → Array ``` Get all available mood categories. **Returns:** `Array` - Available moods **Example:** ```javascript const moods = MusicEngine.getMoods(); // ['Epic', 'Chill', 'Dark', 'Upbeat', 'Mysterious', 'Retro', 'Dramatic', 'Peaceful'] ``` --- #### getSongInfo() ```javascript MusicEngine.getSongInfo(songId) → Song | null ``` Get detailed information about a specific song. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `songId` | string | Yes | Song identifier | **Returns:** `Song | null` - Song object or null if not found --- #### onSongEnd() ```javascript MusicEngine.onSongEnd(callback) → Function ``` Register a callback for when a song ends. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `callback` | Function | Yes | Called when song ends | **Returns:** `Function` - Unsubscribe function **Example:** ```javascript const unsubscribe = MusicEngine.onSongEnd(() => { MusicEngine.playRandomSong('Epic'); // Loop }); // Later: unsubscribe(); ``` --- ## BackgroundEngine Procedural background rendering system. Generates animated backgrounds using canvas drawing. ### Properties | Property | Type | Description | |----------|------|-------------| | `themes` | Array | Available theme names | | `activeEffects` | Array | Currently active effects | ### Methods #### initialize() ```javascript BackgroundEngine.initialize() → Promise ``` Initialize the background engine. Called automatically by AssetManager. --- #### render() ```javascript BackgroundEngine.render(ctx, theme, variant, width, height, time, options) → void ``` Render a background to a canvas context. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `ctx` | CanvasRenderingContext2D | Yes | Canvas 2D context | | `theme` | string | Yes | Theme name | | `variant` | string | Yes | Variant name | | `width` | number | Yes | Canvas width in pixels | | `height` | number | Yes | Canvas height in pixels | | `time` | number | Yes | Time in seconds (for animation) | | `options` | Object | No | Rendering options | | `options.effects` | Array | No | Visual effects to apply | | `options.parallax` | Object | No | Parallax configuration | | `options.colorShift` | number | No | Hue shift in degrees | **Available Effects:** - `particles` - Floating particles - `rain` - Rain effect - `snow` - Snow effect - `fog` - Fog overlay - `lightning` - Lightning flashes - `stars-twinkle` - Twinkling stars - `clouds-moving` - Moving clouds - `leaves-falling` - Falling leaves - `fireflies` - Glowing fireflies - `heat-distortion` - Heat wave effect **Example:** ```javascript function gameLoop(timestamp) { const time = timestamp / 1000; // Convert to seconds BackgroundEngine.render( ctx, 'nature', 'forest', canvas.width, canvas.height, time, { effects: ['leaves-falling', 'fog'] } ); requestAnimationFrame(gameLoop); } requestAnimationFrame(gameLoop); ``` --- #### renderStatic() ```javascript BackgroundEngine.renderStatic(ctx, theme, variant, width, height, options) → void ``` Render a static (non-animated) background. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `ctx` | CanvasRenderingContext2D | Yes | Canvas 2D context | | `theme` | string | Yes | Theme name | | `variant` | string | Yes | Variant name | | `width` | number | Yes | Canvas width | | `height` | number | Yes | Canvas height | | `options` | Object | No | Rendering options | **Example:** ```javascript // Render once for menu screens BackgroundEngine.renderStatic(ctx, 'castle', 'entrance', 800, 600); ``` --- #### getThemes() ```javascript BackgroundEngine.getThemes() → Array ``` Get all available theme names. **Returns:** `Array` - Theme names **Example:** ```javascript const themes = BackgroundEngine.getThemes(); // ['nature', 'space', 'underwater', 'castle', 'city', 'desert', // 'arctic', 'cave', 'sky', 'abstract', 'horror', 'fantasy'] ``` --- #### getVariants() ```javascript BackgroundEngine.getVariants(theme) → Array ``` Get all variant names for a theme. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `theme` | string | Yes | Theme name | **Returns:** `Array` - Variant names for the theme **Example:** ```javascript const variants = BackgroundEngine.getVariants('nature'); // ['forest', 'meadow', 'mountain', 'river', 'beach', 'jungle', 'autumn-forest'] ``` --- #### getThemeInfo() ```javascript BackgroundEngine.getThemeInfo(theme) → ThemeInfo | null ``` Get detailed information about a theme. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `theme` | string | Yes | Theme name | **Returns:** `ThemeInfo | null` ```javascript { name: string, description: string, variants: Array<{ name: string, description: string, colors: Array, suggestedEffects: Array }>, compatibleMoods: Array, tags: Array } ``` --- #### getEffects() ```javascript BackgroundEngine.getEffects() → Array ``` Get all available visual effects. **Returns:** `Array` ```javascript { id: string, name: string, description: string, performance: 'low' | 'medium' | 'high', compatibleThemes: Array | 'all' } ``` --- #### preloadTheme() ```javascript BackgroundEngine.preloadTheme(theme) → Promise ``` Preload a theme's assets for smoother rendering. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `theme` | string | Yes | Theme to preload | **Returns:** `Promise` - Resolves when preloaded --- #### createRenderFunction() ```javascript BackgroundEngine.createRenderFunction(theme, variant, options) → Function ``` Create a reusable render function for a specific background. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `theme` | string | Yes | Theme name | | `variant` | string | Yes | Variant name | | `options` | Object | No | Permanent options | **Returns:** `Function` - `(ctx, width, height, time) => void` **Example:** ```javascript const renderForest = BackgroundEngine.createRenderFunction( 'nature', 'forest', { effects: ['fog'] } ); function gameLoop(time) { renderForest(ctx, canvas.width, canvas.height, time / 1000); requestAnimationFrame(gameLoop); } ``` --- #### setGlobalEffect() ```javascript BackgroundEngine.setGlobalEffect(effectId, enabled) → void ``` Enable or disable a global effect. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `effectId` | string | Yes | Effect identifier | | `enabled` | boolean | Yes | Whether to enable | --- #### getColorPalette() ```javascript BackgroundEngine.getColorPalette(theme, variant) → Array ``` Get the color palette for a background. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `theme` | string | Yes | Theme name | | `variant` | string | Yes | Variant name | **Returns:** `Array` - Hex color codes **Example:** ```javascript const colors = BackgroundEngine.getColorPalette('nature', 'forest'); // ['#1a472a', '#2d5a27', '#228b22', '#90ee90', '#87ceeb'] ``` --- ## AvatarSystem Avatar creation, customization, rendering, and management system. ### Properties | Property | Type | Description | |----------|------|-------------| | `currentAvatar` | Avatar\|null | Currently loaded avatar | | `parts` | Object | Available parts by category | ### Methods #### initialize() ```javascript AvatarSystem.initialize() → Promise ``` Initialize the avatar system. Called automatically by AssetManager. --- #### create() ```javascript AvatarSystem.create(customization) → Avatar ``` Create a new avatar with specified customization. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `customization` | Object | No | Customization options | | `customization.base` | string | No | Base body type | | `customization.skinTone` | string | No | Skin tone color | | `customization.hairStyle` | string | No | Hair style ID | | `customization.hairColor` | string | No | Hair color | | `customization.eyes` | string | No | Eye style ID | | `customization.eyeColor` | string | No | Eye color | | `customization.outfit` | string | No | Outfit ID | | `customization.accessories` | Array | No | Equipped accessories | **Returns:** `Avatar` - New avatar object **Avatar Object:** ```javascript { id: string, version: number, customization: Object, accessories: Map, createdAt: Date, updatedAt: Date } ``` **Example:** ```javascript const avatar = AvatarSystem.create({ base: 'humanoid', skinTone: '#f5d0b0', hairStyle: 'spiky', hairColor: '#3d2314', eyes: 'round', eyeColor: '#4a90d9', outfit: 'casual-tee' }); ``` --- #### createRandom() ```javascript AvatarSystem.createRandom(constraints) → Avatar ``` Create a random avatar. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `constraints` | Object | No | Constraints for randomization | | `constraints.base` | string | No | Fixed base type | | `constraints.style` | string | No | Style category | **Returns:** `Avatar` - Random avatar **Example:** ```javascript const randomAvatar = AvatarSystem.createRandom({ style: 'fantasy' }); ``` --- #### loadUserAvatar() ```javascript AvatarSystem.loadUserAvatar(userId) → Promise ``` Load a user's saved avatar from the server. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `userId` | string | Yes | User identifier | **Returns:** `Promise` - User's avatar **Example:** ```javascript const avatar = await AvatarSystem.loadUserAvatar(currentUser.id); ``` --- #### saveUserAvatar() ```javascript AvatarSystem.saveUserAvatar(userId, avatar) → Promise ``` Save a user's avatar to the server. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `userId` | string | Yes | User identifier | | `avatar` | Avatar | Yes | Avatar to save | **Returns:** `Promise` - Success status --- #### render() ```javascript AvatarSystem.render(avatar, mode, ctx, x, y, options) → void ``` Render an avatar to a canvas context. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `avatar` | Avatar | Yes | Avatar to render | | `mode` | string | Yes | Render mode | | `ctx` | CanvasRenderingContext2D | Yes | Canvas context | | `x` | number | Yes | X position | | `y` | number | Yes | Y position | | `options` | Object | No | Rendering options | | `options.scale` | number | No | Scale factor (default: 1) | | `options.flip` | boolean | No | Flip horizontally | | `options.animation` | string | No | Current animation | | `options.frame` | number | No | Animation frame | **Render Modes:** - `full` - Full avatar with all details - `portrait` - Head and shoulders only - `icon` - Small icon version - `silhouette` - Solid color silhouette - `game` - Optimized for gameplay **Example:** ```javascript AvatarSystem.render(avatar, 'game', ctx, playerX, playerY, { scale: 2, flip: facingLeft, animation: 'walk', frame: Math.floor(time * 10) % 8 }); ``` --- #### renderToImage() ```javascript AvatarSystem.renderToImage(avatar, mode, options) → Promise ``` Render avatar to an image element. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `avatar` | Avatar | Yes | Avatar to render | | `mode` | string | Yes | Render mode | | `options` | Object | No | Rendering options | | `options.width` | number | No | Output width | | `options.height` | number | No | Output height | **Returns:** `Promise` - Rendered image --- #### equipAccessory() ```javascript AvatarSystem.equipAccessory(avatar, slot, itemId) → boolean ``` Equip an accessory to an avatar. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `avatar` | Avatar | Yes | Avatar to modify | | `slot` | string | Yes | Accessory slot | | `itemId` | string | Yes | Accessory ID | **Accessory Slots:** - `head` - Hats, helmets, headbands - `face` - Glasses, masks - `neck` - Necklaces, scarves - `hand-left` - Left hand items - `hand-right` - Right hand items - `back` - Capes, wings, backpacks - `pet` - Companion pets **Returns:** `boolean` - True if equipped successfully **Example:** ```javascript AvatarSystem.equipAccessory(avatar, 'head', 'wizard-hat'); AvatarSystem.equipAccessory(avatar, 'pet', 'dragon-hatchling'); ``` --- #### unequipAccessory() ```javascript AvatarSystem.unequipAccessory(avatar, slot) → string | null ``` Remove an accessory from a slot. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `avatar` | Avatar | Yes | Avatar to modify | | `slot` | string | Yes | Slot to clear | **Returns:** `string | null` - Removed item ID or null if empty --- #### getAccessories() ```javascript AvatarSystem.getAccessories(category) → Array ``` Get available accessories by category. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `category` | string | No | Filter by category | **Returns:** `Array` ```javascript { id: string, name: string, slot: string, category: string, unlockLevel: number, rarity: 'common' | 'uncommon' | 'rare' | 'epic' | 'legendary' } ``` --- #### customize() ```javascript AvatarSystem.customize(avatar, changes) → Avatar ``` Apply customization changes to an avatar. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `avatar` | Avatar | Yes | Avatar to modify | | `changes` | Object | Yes | Customization changes | **Returns:** `Avatar` - Modified avatar (same reference) **Example:** ```javascript AvatarSystem.customize(avatar, { hairColor: '#ff0000', outfit: 'knight-armor' }); ``` --- #### validate() ```javascript AvatarSystem.validate(avatar) → ValidationResult ``` Validate an avatar object. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `avatar` | Avatar | Yes | Avatar to validate | **Returns:** `ValidationResult` ```javascript { valid: boolean, errors: Array, warnings: Array } ``` --- #### clone() ```javascript AvatarSystem.clone(avatar) → Avatar ``` Create a deep copy of an avatar. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `avatar` | Avatar | Yes | Avatar to clone | **Returns:** `Avatar` - New avatar copy --- #### export() ```javascript AvatarSystem.export(avatar) → string ``` Export avatar to a JSON string. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `avatar` | Avatar | Yes | Avatar to export | **Returns:** `string` - JSON representation --- #### import() ```javascript AvatarSystem.import(json) → Avatar ``` Import avatar from JSON string. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `json` | string | Yes | JSON avatar data | **Returns:** `Avatar` - Imported avatar --- #### getPartOptions() ```javascript AvatarSystem.getPartOptions(category) → Array ``` Get all options for an avatar part category. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `category` | string | Yes | Part category | **Categories:** `base`, `hair`, `eyes`, `mouth`, `outfit`, `shoes` **Returns:** `Array` ```javascript { id: string, name: string, preview: string, // Preview image URL unlockLevel: number, colors: Array // Available color options } ``` --- #### getAnimations() ```javascript AvatarSystem.getAnimations(avatar) → Array ``` Get available animations for an avatar. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `avatar` | Avatar | Yes | Avatar to check | **Returns:** `Array` - Animation names **Standard Animations:** - `idle` - `walk` - `run` - `jump` - `fall` - `land` - `attack` - `hurt` - `die` - `celebrate` --- ## ContextRenderer Applies and renders game contexts on avatars. Contexts define how avatars behave and appear in different game types. ### Methods #### apply() ```javascript ContextRenderer.apply(avatar, contextId, options) → AvatarWithContext ``` Apply a game context to an avatar. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `avatar` | Avatar | Yes | Base avatar | | `contextId` | string | Yes | Context to apply | | `options` | Object | No | Context options | | `options.variant` | string | No | Context variant | | `options.color` | string | No | Primary color override | | `options.preserveAccessories` | boolean | No | Keep equipped accessories | **Returns:** `AvatarWithContext` - Avatar with applied context **AvatarWithContext Object:** ```javascript { avatar: Avatar, context: Context, variant: string, state: { animation: string, frame: number, direction: 'left' | 'right', effects: Array } } ``` **Example:** ```javascript const player = ContextRenderer.apply(avatar, 'platformer-standard', { variant: 'hero', preserveAccessories: true }); ``` --- #### remove() ```javascript ContextRenderer.remove(avatarWithContext) → Avatar ``` Remove context from an avatar. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `avatarWithContext` | AvatarWithContext | Yes | Avatar with context | **Returns:** `Avatar` - Original avatar --- #### render() ```javascript ContextRenderer.render(avatarWithContext, ctx, x, y, options) → void ``` Render an avatar with its context. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `avatarWithContext` | AvatarWithContext | Yes | Avatar with context | | `ctx` | CanvasRenderingContext2D | Yes | Canvas context | | `x` | number | Yes | X position | | `y` | number | Yes | Y position | | `options` | Object | No | Rendering options | | `options.scale` | number | No | Scale factor | | `options.time` | number | No | Time for animation | | `options.debug` | boolean | No | Show hitboxes | **Example:** ```javascript function gameLoop(time) { ctx.clearRect(0, 0, width, height); ContextRenderer.render(player, ctx, playerX, playerY, { scale: 2, time: time / 1000 }); requestAnimationFrame(gameLoop); } ``` --- #### animate() ```javascript ContextRenderer.animate(avatarWithContext, animationId, options) → boolean ``` Start or change an animation on an avatar. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `avatarWithContext` | AvatarWithContext | Yes | Avatar with context | | `animationId` | string | Yes | Animation to play | | `options` | Object | No | Animation options | | `options.loop` | boolean | No | Loop animation (default: varies) | | `options.speed` | number | No | Speed multiplier (default: 1) | | `options.onComplete` | Function | No | Callback when animation ends | **Returns:** `boolean` - True if animation started **Example:** ```javascript if (keys.ArrowRight) { player.state.direction = 'right'; ContextRenderer.animate(player, 'run'); } else if (keys.ArrowLeft) { player.state.direction = 'left'; ContextRenderer.animate(player, 'run'); } else { ContextRenderer.animate(player, 'idle'); } // One-shot animation with callback ContextRenderer.animate(player, 'attack', { loop: false, onComplete: () => canAttack = true }); ``` --- #### stopAnimation() ```javascript ContextRenderer.stopAnimation(avatarWithContext) → void ``` Stop the current animation, reverting to idle. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `avatarWithContext` | AvatarWithContext | Yes | Avatar with context | --- #### addEffect() ```javascript ContextRenderer.addEffect(avatarWithContext, effectId, options) → boolean ``` Add a visual effect to an avatar. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `avatarWithContext` | AvatarWithContext | Yes | Avatar with context | | `effectId` | string | Yes | Effect to add | | `options` | Object | No | Effect options | | `options.duration` | number | No | Auto-remove after ms | | `options.color` | string | No | Effect color | | `options.intensity` | number | No | Effect intensity (0-1) | **Available Effects:** - `glow` - Outer glow - `trail` - Motion trail - `sparkle` - Sparkle particles - `fire` - Fire aura - `ice` - Ice crystals - `electric` - Electric sparks - `heal` - Healing particles - `shield` - Shield bubble - `speed-lines` - Speed effect - `damage-flash` - Red flash **Returns:** `boolean` - True if effect added **Example:** ```javascript // Temporary power-up glow ContextRenderer.addEffect(player, 'glow', { color: '#ffff00', duration: 10000 }); // Damage feedback ContextRenderer.addEffect(player, 'damage-flash', { duration: 200 }); ``` --- #### removeEffect() ```javascript ContextRenderer.removeEffect(avatarWithContext, effectId) → boolean ``` Remove an effect from an avatar. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `avatarWithContext` | AvatarWithContext | Yes | Avatar with context | | `effectId` | string | Yes | Effect to remove | **Returns:** `boolean` - True if effect was removed --- #### clearEffects() ```javascript ContextRenderer.clearEffects(avatarWithContext) → void ``` Remove all effects from an avatar. --- #### getHitbox() ```javascript ContextRenderer.getHitbox(avatarWithContext, type) → Hitbox ``` Get collision hitbox for the avatar in current state. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `avatarWithContext` | AvatarWithContext | Yes | Avatar with context | | `type` | string | No | Hitbox type (default: 'body') | **Hitbox Types:** - `body` - Main collision box - `feet` - Ground detection - `head` - Ceiling detection - `attack` - Attack range (if attacking) **Returns:** `Hitbox` ```javascript { x: number, // Relative to avatar position y: number, width: number, height: number } ``` **Example:** ```javascript const hitbox = ContextRenderer.getHitbox(player, 'body'); const worldHitbox = { x: playerX + hitbox.x, y: playerY + hitbox.y, width: hitbox.width, height: hitbox.height }; ``` --- #### setDirection() ```javascript ContextRenderer.setDirection(avatarWithContext, direction) → void ``` Set facing direction. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `avatarWithContext` | AvatarWithContext | Yes | Avatar with context | | `direction` | string | Yes | 'left' or 'right' | --- #### getAvailableAnimations() ```javascript ContextRenderer.getAvailableAnimations(avatarWithContext) → Array ``` Get all animations available for this context. **Returns:** `Array` ```javascript { id: string, name: string, frames: number, duration: number, // ms per frame loops: boolean } ``` --- ## ContextCatalog Catalog of all available game contexts. ### Methods #### getAll() ```javascript ContextCatalog.getAll() → Array ``` Get all available contexts. **Returns:** `Array` ```javascript { id: string, name: string, description: string, category: string, variants: Array, animations: Array, gameStyles: Array, tags: Array } ``` --- #### get() ```javascript ContextCatalog.get(contextId) → Context | null ``` Get a specific context by ID. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `contextId` | string | Yes | Context identifier | **Returns:** `Context | null` --- #### findByGameStyle() ```javascript ContextCatalog.findByGameStyle(gameStyle) → Array ``` Find contexts compatible with a game style. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `gameStyle` | string | Yes | Game style | **Returns:** `Array` - Compatible contexts **Example:** ```javascript const contexts = ContextCatalog.findByGameStyle('action-arcade'); // Returns shooter, platformer, fighting contexts ``` --- #### findByCategory() ```javascript ContextCatalog.findByCategory(category) → Array ``` Find contexts by category. **Categories:** - `action` - Action game contexts - `puzzle` - Puzzle game contexts - `adventure` - Adventure contexts - `vehicle` - Vehicle/racing contexts - `sports` - Sports game contexts - `special` - Special/unique contexts --- #### search() ```javascript ContextCatalog.search(query) → Array ``` Search contexts by name, description, or tags. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `query` | string | Yes | Search query | **Returns:** `Array` - Matching contexts --- #### getVariants() ```javascript ContextCatalog.getVariants(contextId) → Array ``` Get all variants for a context. **Returns:** `Array` ```javascript { id: string, name: string, description: string, preview: string } ``` --- ## AssetCatalog Unified catalog for browsing all assets. ### Methods #### browse() ```javascript AssetCatalog.browse(category, options) → BrowseResult ``` Browse assets by category. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `category` | string | Yes | Asset category | | `options` | Object | No | Browse options | | `options.page` | number | No | Page number (default: 1) | | `options.perPage` | number | No | Items per page (default: 20) | | `options.sort` | string | No | Sort field | | `options.filter` | Object | No | Filter criteria | **Categories:** `music`, `backgrounds`, `contexts`, `accessories`, `presets` **Returns:** `BrowseResult` ```javascript { items: Array, total: number, page: number, perPage: number, totalPages: number } ``` --- #### search() ```javascript AssetCatalog.search(query, options) → SearchResult ``` Search across all asset categories. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `query` | string | Yes | Search query | | `options` | Object | No | Search options | | `options.categories` | Array | No | Limit to categories | | `options.limit` | number | No | Max results (default: 50) | **Returns:** `SearchResult` ```javascript { results: Array<{ category: string, asset: Asset, score: number }>, totalCount: number } ``` --- #### getStats() ```javascript AssetCatalog.getStats() → CatalogStats ``` Get statistics about the asset catalog. **Returns:** `CatalogStats` ```javascript { music: { total: 160, byMood: Object }, backgrounds: { themes: 12, variants: 84 }, contexts: { total: 44, byCategory: Object }, accessories: { total: 280, bySlot: Object }, presets: { total: 50 } } ``` --- #### getRecent() ```javascript AssetCatalog.getRecent(category, limit) → Array ``` Get recently added assets. --- #### getPopular() ```javascript AssetCatalog.getPopular(category, limit) → Array ``` Get most popular/used assets. --- ## AssetPresets Pre-configured asset combinations for quick setup. ### Methods #### getAll() ```javascript AssetPresets.getAll() → Array ``` Get all available presets. **Returns:** `Array` ```javascript { id: string, name: string, description: string, config: { music: Object, background: Object, context: Object }, thumbnail: string, tags: Array, gameStyles: Array } ``` --- #### get() ```javascript AssetPresets.get(presetId) → Preset | null ``` Get a specific preset. --- #### findByGameStyle() ```javascript AssetPresets.findByGameStyle(gameStyle) → Array ``` Find presets matching a game style. --- #### findByTags() ```javascript AssetPresets.findByTags(tags, matchAll) → Array ``` Find presets by tags. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `tags` | Array | Yes | Tags to match | | `matchAll` | boolean | No | Require all tags (default: false) | --- #### apply() ```javascript AssetPresets.apply(presetId) → Promise ``` Apply a preset, loading all its assets. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `presetId` | string | Yes | Preset identifier | **Returns:** `Promise` - Loaded asset references **Example:** ```javascript const assets = await AssetPresets.apply('retro-platformer'); MusicEngine.playSong(assets.music.song.id); ``` --- #### create() ```javascript AssetPresets.create(name, config, metadata) → Preset ``` Create a custom preset (user presets). **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `name` | string | Yes | Preset name | | `config` | Object | Yes | Asset configuration | | `metadata` | Object | No | Additional metadata | **Returns:** `Preset` - Created preset --- #### save() ```javascript AssetPresets.save(preset) → Promise ``` Save a user preset to the server. --- #### delete() ```javascript AssetPresets.delete(presetId) → Promise ``` Delete a user preset. --- #### getUserPresets() ```javascript AssetPresets.getUserPresets(userId) → Promise> ``` Get a user's saved presets. --- ## AssetCompatibility Validates and checks compatibility between assets. ### Methods #### validate() ```javascript AssetCompatibility.validate(config) → ValidationResult ``` Validate an asset configuration for compatibility. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `config` | Object | Yes | Asset configuration | **Returns:** `ValidationResult` ```javascript { valid: boolean, errors: Array<{ code: string, message: string, field: string }>, warnings: Array<{ code: string, message: string, suggestion: string }> } ``` **Example:** ```javascript const result = AssetCompatibility.validate({ music: { mood: 'Peaceful' }, background: { theme: 'horror', variant: 'haunted-house' }, context: { id: 'shooter-standard' } }); console.log(result); // { // valid: true, // errors: [], // warnings: [ // { // code: 'MOOD_MISMATCH', // message: 'Peaceful music may not match horror theme', // suggestion: 'Consider using Dark or Mysterious mood' // } // ] // } ``` --- #### isCompatible() ```javascript AssetCompatibility.isCompatible(asset1, asset2) → boolean ``` Check if two assets are compatible. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `asset1` | Object | Yes | First asset {type, id} | | `asset2` | Object | Yes | Second asset {type, id} | **Returns:** `boolean` - True if compatible **Example:** ```javascript const compatible = AssetCompatibility.isCompatible( { type: 'background', id: 'space:nebula' }, { type: 'context', id: 'shooter-standard' } ); // true ``` --- #### getCompatibleAssets() ```javascript AssetCompatibility.getCompatibleAssets(asset, targetType) → Array ``` Get assets compatible with a given asset. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `asset` | Object | Yes | Source asset {type, id} | | `targetType` | string | Yes | Type of assets to find | **Returns:** `Array` - Compatible assets **Example:** ```javascript const backgrounds = AssetCompatibility.getCompatibleAssets( { type: 'context', id: 'platformer-standard' }, 'background' ); // Returns backgrounds suitable for platformers ``` --- #### suggestFixes() ```javascript AssetCompatibility.suggestFixes(config) → Array ``` Get suggestions to improve an asset configuration. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `config` | Object | Yes | Current configuration | **Returns:** `Array` ```javascript { type: 'music' | 'background' | 'context', current: Object, suggested: Object, reason: string, improvement: string } ``` --- #### getMoodCompatibility() ```javascript AssetCompatibility.getMoodCompatibility(mood, theme) → number ``` Get compatibility score between a music mood and background theme. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `mood` | string | Yes | Music mood | | `theme` | string | Yes | Background theme | **Returns:** `number` - Compatibility score (0-100) **Example:** ```javascript const score = AssetCompatibility.getMoodCompatibility('Epic', 'space'); // 95 - highly compatible const score2 = AssetCompatibility.getMoodCompatibility('Peaceful', 'horror'); // 15 - poor compatibility ``` --- ## Common Patterns ### Basic Game Setup ```javascript async function initGame() { // Initialize all systems await AssetManager.initialize(); // Load game-specific assets const assets = await AssetManager.loadGameAssets({ music: { mood: 'Upbeat' }, background: { theme: 'nature', variant: 'forest' }, context: { id: 'platformer-standard' } }); // Start music MusicEngine.playRandomSong('Upbeat'); // Load player avatar const avatar = await AvatarSystem.loadUserAvatar(userId); const player = ContextRenderer.apply(avatar, 'platformer-standard'); // Game loop function gameLoop(timestamp) { const time = timestamp / 1000; // Clear canvas ctx.clearRect(0, 0, canvas.width, canvas.height); // Render background BackgroundEngine.render( ctx, 'nature', 'forest', canvas.width, canvas.height, time ); // Update and render player updatePlayer(player); ContextRenderer.render(player, ctx, playerX, playerY, { time }); requestAnimationFrame(gameLoop); } requestAnimationFrame(gameLoop); } ``` --- ### Switching Music Mood ```javascript // Smooth transition when entering boss fight async function onBossFight() { await MusicEngine.fadeOut(1000); MusicEngine.playRandomSong('Epic'); } // Crossfade for seamless transition function onAreaChange(newArea) { const moodMap = { forest: 'Peaceful', dungeon: 'Dark', boss: 'Epic', victory: 'Upbeat' }; const newMood = moodMap[newArea]; const songs = MusicEngine.findSongs({ mood: newMood }); const randomSong = songs[Math.floor(Math.random() * songs.length)]; MusicEngine.crossfade(randomSong.id, 2000); } ``` --- ### Animation Control ```javascript function updatePlayer(player) { // Movement animations if (keys.ArrowRight) { ContextRenderer.setDirection(player, 'right'); if (isGrounded) { ContextRenderer.animate(player, keys.Shift ? 'run' : 'walk'); } playerX += keys.Shift ? 8 : 4; } else if (keys.ArrowLeft) { ContextRenderer.setDirection(player, 'left'); if (isGrounded) { ContextRenderer.animate(player, keys.Shift ? 'run' : 'walk'); } playerX -= keys.Shift ? 8 : 4; } else if (isGrounded) { ContextRenderer.animate(player, 'idle'); } // Jump animation if (keys.Space && isGrounded) { ContextRenderer.animate(player, 'jump'); velocityY = -15; isGrounded = false; } // Falling animation if (!isGrounded && velocityY > 0) { ContextRenderer.animate(player, 'fall'); } // Attack animation (one-shot) if (keys.z && canAttack) { canAttack = false; ContextRenderer.animate(player, 'attack', { loop: false, onComplete: () => { canAttack = true; } }); } } ``` --- ### Dynamic Background Effects ```javascript // Weather system class WeatherSystem { constructor() { this.currentWeather = 'clear'; } setWeather(weather) { // Remove old effects BackgroundEngine.setGlobalEffect('rain', false); BackgroundEngine.setGlobalEffect('snow', false); BackgroundEngine.setGlobalEffect('fog', false); BackgroundEngine.setGlobalEffect('lightning', false); // Apply new weather switch (weather) { case 'rain': BackgroundEngine.setGlobalEffect('rain', true); MusicEngine.crossfade('rain-ambience', 2000); break; case 'storm': BackgroundEngine.setGlobalEffect('rain', true); BackgroundEngine.setGlobalEffect('lightning', true); MusicEngine.crossfade('storm-dramatic', 2000); break; case 'snow': BackgroundEngine.setGlobalEffect('snow', true); MusicEngine.crossfade('winter-peaceful', 2000); break; case 'fog': BackgroundEngine.setGlobalEffect('fog', true); MusicEngine.crossfade('mysterious-ambient', 2000); break; } this.currentWeather = weather; } } ``` --- ### Power-up Effects ```javascript function applyPowerUp(player, powerUpType) { switch (powerUpType) { case 'speed': ContextRenderer.addEffect(player, 'speed-lines', { duration: 10000, color: '#00ffff' }); playerSpeed *= 2; setTimeout(() => playerSpeed /= 2, 10000); break; case 'shield': ContextRenderer.addEffect(player, 'shield', { duration: 15000, color: '#4444ff' }); isInvulnerable = true; setTimeout(() => isInvulnerable = false, 15000); break; case 'fire': ContextRenderer.addEffect(player, 'fire', { color: '#ff4400' }); attackDamage *= 2; break; case 'heal': ContextRenderer.addEffect(player, 'heal', { duration: 2000 }); health = Math.min(health + 30, maxHealth); break; } } function onPlayerHit(player, damage) { if (isInvulnerable) return; health -= damage; // Visual feedback ContextRenderer.addEffect(player, 'damage-flash', { duration: 200 }); // Screen shake screenShake(10, 200); if (health <= 0) { ContextRenderer.animate(player, 'die', { loop: false, onComplete: showGameOver }); } } ``` --- ### Preset-Based Game Loading ```javascript async function loadGameWithPreset(presetName) { const preset = AssetManager.findPreset(presetName); if (!preset) { console.error(`Preset "${presetName}" not found`); return null; } // Validate the preset const validation = AssetCompatibility.validate(preset.config); if (!validation.valid) { console.error('Invalid preset:', validation.errors); return null; } // Show any warnings if (validation.warnings.length > 0) { console.warn('Preset warnings:', validation.warnings); } // Load all assets const assets = await AssetManager.loadGameAssets(preset.config); return { preset, assets, description: AssetManager.describeAssets(preset.config) }; } // Usage const game = await loadGameWithPreset('retro-platformer'); console.log(game.description.summary); // "8-bit chiptune music with pixelated forest background, // featuring a classic platformer hero with retro animations" ``` --- ### Responsive Asset Recommendations ```javascript async function setupGameFromDescription(description, gameStyle) { // Get AI-powered recommendations const recommendations = AssetManager.getRecommendations( gameStyle, description ); // Use the top recommendation const topRec = recommendations[0]; console.log(`Selected: ${topRec.explanation} (score: ${topRec.score})`); // Load the recommended assets const assets = await AssetManager.loadGameAssets(topRec.config); return { assets, config: topRec.config, alternatives: recommendations.slice(1) }; } // Usage const game = await setupGameFromDescription( 'A spooky adventure in a haunted mansion with ghosts and puzzles', 'adventure-story' ); // Automatically selects dark/mysterious music, horror mansion background, // and adventure context ``` --- ## Troubleshooting ### Music Not Playing **Symptom:** `MusicEngine.playSong()` returns true but no sound. **Solutions:** 1. **User interaction required:** Most browsers require user interaction before playing audio. ```javascript document.addEventListener('click', () => { MusicEngine.playRandomSong('Upbeat'); }, { once: true }); ``` 2. **Check volume:** ```javascript console.log('Volume:', MusicEngine.getVolume()); console.log('Muted:', MusicEngine.muted); MusicEngine.setVolume(0.7); MusicEngine.unmute(); ``` 3. **Ensure initialization:** ```javascript await AssetManager.initialize(); // or await MusicEngine.initialize(); ``` --- ### Background Not Animating **Symptom:** Background appears static, not moving. **Solutions:** 1. **Pass time parameter:** The time must increase each frame. ```javascript // Wrong - time is always 0 BackgroundEngine.render(ctx, theme, variant, w, h, 0); // Correct - time increases function gameLoop(timestamp) { const time = timestamp / 1000; // Convert to seconds BackgroundEngine.render(ctx, theme, variant, w, h, time); requestAnimationFrame(gameLoop); } ``` 2. **Time should be in seconds:** ```javascript // Wrong - milliseconds BackgroundEngine.render(ctx, theme, variant, w, h, Date.now()); // Correct - seconds BackgroundEngine.render(ctx, theme, variant, w, h, Date.now() / 1000); ``` --- ### Avatar Not Rendering **Symptom:** Avatar appears blank or throws errors. **Solutions:** 1. **Validate avatar object:** ```javascript const validation = AvatarSystem.validate(avatar); if (!validation.valid) { console.error('Avatar errors:', validation.errors); avatar = AvatarSystem.create(); // Use default } ``` 2. **Check mode is valid:** ```javascript // Valid modes: 'full', 'portrait', 'icon', 'silhouette', 'game' AvatarSystem.render(avatar, 'game', ctx, x, y); ``` 3. **Ensure context is applied for game rendering:** ```javascript // If using ContextRenderer, must apply context first const player = ContextRenderer.apply(avatar, 'platformer-standard'); ContextRenderer.render(player, ctx, x, y); ``` --- ### Context Mismatch **Symptom:** Avatar looks wrong or animations don't work. **Solutions:** 1. **Validate configuration:** ```javascript const result = AssetCompatibility.validate({ context: { id: 'shooter-standard' }, background: { theme: 'nature', variant: 'forest' } }); if (result.warnings.length > 0) { console.warn('Compatibility warnings:', result.warnings); } ``` 2. **Check game style compatibility:** ```javascript const contexts = ContextCatalog.findByGameStyle('action-arcade'); console.log('Compatible contexts:', contexts.map(c => c.id)); ``` 3. **Use recommendations:** ```javascript const recs = AssetManager.getRecommendations('action-arcade', 'space shooter'); const bestContext = recs[0].config.context; ``` --- ### Performance Issues **Symptom:** Game runs slowly or stutters. **Solutions:** 1. **Reduce background effects:** ```javascript // Disable expensive effects BackgroundEngine.render(ctx, theme, variant, w, h, time, { effects: [] // No effects }); ``` 2. **Use static backgrounds for menus:** ```javascript // Render once instead of every frame BackgroundEngine.renderStatic(ctx, theme, variant, w, h); ``` 3. **Preload assets:** ```javascript await BackgroundEngine.preloadTheme('nature'); await AssetManager.initialize({ preloadBackgrounds: true }); ``` 4. **Use simpler render modes:** ```javascript // Use 'game' mode instead of 'full' for gameplay AvatarSystem.render(avatar, 'game', ctx, x, y); ``` --- ### Asset Not Found **Symptom:** Methods return null or false. **Solutions:** 1. **Check asset exists:** ```javascript const song = MusicEngine.getSongInfo('my-song-id'); if (!song) { console.error('Song not found. Available songs:'); console.log(MusicEngine.getCatalog().map(s => s.id)); } ``` 2. **Search for similar assets:** ```javascript const results = AssetManager.searchAssets('forest', { types: ['background'] }); console.log('Found backgrounds:', results.backgrounds); ``` 3. **Use fallbacks:** ```javascript const preset = AssetManager.findPreset('my-preset') || AssetManager.findPreset('default-platformer'); ``` --- ## Error Codes | Code | Description | Solution | |------|-------------|----------| | `ASSET_NOT_FOUND` | Requested asset doesn't exist | Check asset ID, use search | | `INVALID_MOOD` | Music mood not recognized | Use `MusicEngine.getMoods()` | | `INVALID_THEME` | Background theme not recognized | Use `BackgroundEngine.getThemes()` | | `INVALID_CONTEXT` | Context ID not recognized | Use `ContextCatalog.getAll()` | | `INCOMPATIBLE_ASSETS` | Assets don't work together | Use `AssetCompatibility.suggestFixes()` | | `NOT_INITIALIZED` | System not initialized | Call `AssetManager.initialize()` | | `AUDIO_BLOCKED` | Browser blocked audio | Require user interaction first | | `AVATAR_INVALID` | Malformed avatar object | Use `AvatarSystem.validate()` | | `CONTEXT_REQUIRED` | Operation requires context | Use `ContextRenderer.apply()` | | `ANIMATION_NOT_FOUND` | Animation doesn't exist for context | Use `ContextRenderer.getAvailableAnimations()` | --- ## Version History | Version | Date | Changes | |---------|------|---------| | 2.0.0 | 2026-02-05 | Added ContextRenderer, expanded MusicEngine | | 1.5.0 | 2026-01-15 | Added AssetCompatibility, presets system | | 1.0.0 | 2025-12-01 | Initial release |