Files
gamercomp/frontend/public/docs/API_REFERENCE.md
T
2026-04-30 02:14:25 +00:00

2755 lines
63 KiB
Markdown

# 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<Object>` - 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<Recommendation>
```
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<Recommendation>` - 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<string>,
gameStyles: Array<string>
}
```
**Example:**
```javascript
const preset = AssetManager.findPreset('retro-platformer');
if (preset) {
await AssetManager.loadGameAssets(preset.config);
}
```
---
#### loadGameAssets()
```javascript
AssetManager.loadGameAssets(config) Promise<LoadedAssets>
```
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<LoadedAssets>` - 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<string, Sprite>
}
}
```
**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<string>,
warnings: Array<string>,
suggestions: Array<string>
}
```
**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<string>
},
context: {
name: string,
description: string,
animations: Array<string>
}
}
```
**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<Song>,
backgrounds: Array<{theme, variant}>,
contexts: Array<Context>,
presets: Array<Preset>,
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<void>
```
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<void>
```
Gradually fade out the music.
**Parameters:**
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `duration` | number | No | Fade duration in milliseconds (default: 1000) |
**Returns:** `Promise<void>` - Resolves when fade completes
**Example:**
```javascript
await MusicEngine.fadeOut(2000); // 2 second fade
MusicEngine.playRandomSong('Dark');
```
---
#### fadeIn()
```javascript
MusicEngine.fadeIn(songId, duration) Promise<void>
```
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<void>` - Resolves when fade completes
**Example:**
```javascript
await MusicEngine.fadeIn('peaceful-meadow-02', 1500);
```
---
#### crossfade()
```javascript
MusicEngine.crossfade(songId, duration) Promise<void>
```
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<void>` - Resolves when crossfade completes
**Example:**
```javascript
await MusicEngine.crossfade('epic-battle-04', 1500);
```
---
#### getCatalog()
```javascript
MusicEngine.getCatalog() Array<Song>
```
Get all available songs.
**Returns:** `Array<Song>` - All songs in the catalog
**Song Object:**
```javascript
{
id: string,
name: string,
mood: string,
tempo: number, // BPM
duration: number, // seconds
instruments: Array<string>,
tags: Array<string>,
intensity: number // 1-10
}
```
**Example:**
```javascript
const songs = MusicEngine.getCatalog();
console.log(`Total songs: ${songs.length}`); // 160
```
---
#### findSongs()
```javascript
MusicEngine.findSongs(filters) Array<Song>
```
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<Song>` - Matching songs
**Example:**
```javascript
const songs = MusicEngine.findSongs({
mood: 'Epic',
minTempo: 120,
intensity: [7, 10]
});
```
---
#### getSongsByMood()
```javascript
MusicEngine.getSongsByMood(mood) Array<Song>
```
Get all songs in a specific mood category.
**Parameters:**
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `mood` | string | Yes | Mood category |
**Returns:** `Array<Song>` - Songs in that mood
**Example:**
```javascript
const epicSongs = MusicEngine.getSongsByMood('Epic');
console.log(`Epic songs: ${epicSongs.length}`); // 20
```
---
#### getMoods()
```javascript
MusicEngine.getMoods() Array<string>
```
Get all available mood categories.
**Returns:** `Array<string>` - 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<string> | Available theme names |
| `activeEffects` | Array<string> | Currently active effects |
### Methods
#### initialize()
```javascript
BackgroundEngine.initialize() Promise<void>
```
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<string>
```
Get all available theme names.
**Returns:** `Array<string>` - 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<string>
```
Get all variant names for a theme.
**Parameters:**
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `theme` | string | Yes | Theme name |
**Returns:** `Array<string>` - 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<string>,
suggestedEffects: Array<string>
}>,
compatibleMoods: Array<string>,
tags: Array<string>
}
```
---
#### getEffects()
```javascript
BackgroundEngine.getEffects() Array<EffectInfo>
```
Get all available visual effects.
**Returns:** `Array<EffectInfo>`
```javascript
{
id: string,
name: string,
description: string,
performance: 'low' | 'medium' | 'high',
compatibleThemes: Array<string> | 'all'
}
```
---
#### preloadTheme()
```javascript
BackgroundEngine.preloadTheme(theme) Promise<void>
```
Preload a theme's assets for smoother rendering.
**Parameters:**
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `theme` | string | Yes | Theme to preload |
**Returns:** `Promise<void>` - 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<string>
```
Get the color palette for a background.
**Parameters:**
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `theme` | string | Yes | Theme name |
| `variant` | string | Yes | Variant name |
**Returns:** `Array<string>` - 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<void>
```
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<string, string>,
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<Avatar>
```
Load a user's saved avatar from the server.
**Parameters:**
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `userId` | string | Yes | User identifier |
**Returns:** `Promise<Avatar>` - User's avatar
**Example:**
```javascript
const avatar = await AvatarSystem.loadUserAvatar(currentUser.id);
```
---
#### saveUserAvatar()
```javascript
AvatarSystem.saveUserAvatar(userId, avatar) Promise<boolean>
```
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<boolean>` - 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<HTMLImageElement>
```
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<HTMLImageElement>` - 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<Accessory>
```
Get available accessories by category.
**Parameters:**
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `category` | string | No | Filter by category |
**Returns:** `Array<Accessory>`
```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<string>,
warnings: Array<string>
}
```
---
#### 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<PartOption>
```
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<PartOption>`
```javascript
{
id: string,
name: string,
preview: string, // Preview image URL
unlockLevel: number,
colors: Array<string> // Available color options
}
```
---
#### getAnimations()
```javascript
AvatarSystem.getAnimations(avatar) Array<string>
```
Get available animations for an avatar.
**Parameters:**
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `avatar` | Avatar | Yes | Avatar to check |
**Returns:** `Array<string>` - 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<string>
}
}
```
**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<AnimationInfo>
```
Get all animations available for this context.
**Returns:** `Array<AnimationInfo>`
```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<Context>
```
Get all available contexts.
**Returns:** `Array<Context>`
```javascript
{
id: string,
name: string,
description: string,
category: string,
variants: Array<string>,
animations: Array<string>,
gameStyles: Array<string>,
tags: Array<string>
}
```
---
#### 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<Context>
```
Find contexts compatible with a game style.
**Parameters:**
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `gameStyle` | string | Yes | Game style |
**Returns:** `Array<Context>` - Compatible contexts
**Example:**
```javascript
const contexts = ContextCatalog.findByGameStyle('action-arcade');
// Returns shooter, platformer, fighting contexts
```
---
#### findByCategory()
```javascript
ContextCatalog.findByCategory(category) Array<Context>
```
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<Context>
```
Search contexts by name, description, or tags.
**Parameters:**
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `query` | string | Yes | Search query |
**Returns:** `Array<Context>` - Matching contexts
---
#### getVariants()
```javascript
ContextCatalog.getVariants(contextId) Array<VariantInfo>
```
Get all variants for a context.
**Returns:** `Array<VariantInfo>`
```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<Asset>,
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<Asset>
```
Get recently added assets.
---
#### getPopular()
```javascript
AssetCatalog.getPopular(category, limit) Array<Asset>
```
Get most popular/used assets.
---
## AssetPresets
Pre-configured asset combinations for quick setup.
### Methods
#### getAll()
```javascript
AssetPresets.getAll() Array<Preset>
```
Get all available presets.
**Returns:** `Array<Preset>`
```javascript
{
id: string,
name: string,
description: string,
config: {
music: Object,
background: Object,
context: Object
},
thumbnail: string,
tags: Array<string>,
gameStyles: Array<string>
}
```
---
#### get()
```javascript
AssetPresets.get(presetId) Preset | null
```
Get a specific preset.
---
#### findByGameStyle()
```javascript
AssetPresets.findByGameStyle(gameStyle) Array<Preset>
```
Find presets matching a game style.
---
#### findByTags()
```javascript
AssetPresets.findByTags(tags, matchAll) Array<Preset>
```
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<LoadedAssets>
```
Apply a preset, loading all its assets.
**Parameters:**
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `presetId` | string | Yes | Preset identifier |
**Returns:** `Promise<LoadedAssets>` - 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<boolean>
```
Save a user preset to the server.
---
#### delete()
```javascript
AssetPresets.delete(presetId) Promise<boolean>
```
Delete a user preset.
---
#### getUserPresets()
```javascript
AssetPresets.getUserPresets(userId) Promise<Array<Preset>>
```
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<Asset>
```
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<Asset>` - 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<Suggestion>
```
Get suggestions to improve an asset configuration.
**Parameters:**
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `config` | Object | Yes | Current configuration |
**Returns:** `Array<Suggestion>`
```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 |