Skip to main content

Integration Issues

Problem Description: Errors occur when installing SDK using package managers.Solution:
  1. Check if Node.js version meets requirements (18.0+)
  2. Clear cache and reinstall:
    # npm
    npm cache clean --force
    npm install @spatialwalk/avatarkit
    
    # yarn
    yarn cache clean
    yarn add @spatialwalk/avatarkit
    
    # pnpm
    pnpm store prune
    pnpm add @spatialwalk/avatarkit
    
  3. Check network connection and mirror source configuration
Prevention:
  • Use the latest stable Node.js version
  • Regularly update dependencies
  • Use the same Node.js version in CI/CD
Problem Description: Type errors occur when using TypeScript.Solution:
  1. Check if TypeScript version meets requirements (5.0+)
  2. Ensure tsconfig.json is configured correctly:
    {
      "compilerOptions": {
        "target": "ES2020",
        "module": "ESNext",
        "lib": ["ES2020", "DOM", "DOM.Iterable"]
      }
    }
    
  3. Reinstall dependencies

Runtime Issues

Problem Description: SDK initialization returns an error.Common Causes:
  1. Network connection issues
  2. Incorrect AppID
  3. Server unavailable
  4. Browser not supported
Solution:
  1. Check network connection
  2. Verify if AppID is correct
  3. Confirm server status
  4. Check browser version and compatibility
Problem Description: Character file loading fails, showing error messages.Possible Causes:
  1. Network connection issues
  2. Incorrect character ID
  3. Unsupported character resource format
  4. Browser cache issues
Troubleshooting Steps:
  1. Check network connection status
  2. Verify if character ID is valid
  3. Check browser console error messages
  4. Clear browser cache
Solution:
import { AvatarManager } from '@spatialwalk/avatarkit'

try {
  const avatarManager = AvatarManager.shared
  const avatar = await avatarManager.load('character-id', (progress) => {
    if (progress.type === LoadProgress.failed) {
      console.error('Load failed:', progress.error)
    }
  })
} catch (error) {
  console.error('Failed to load avatar:', error)
}
Problem Description: WebSocket connection cannot be established.Solution:
  1. Check network connection
  2. Confirm if sessionToken is set correctly
  3. Check firewall and security settings
  4. View browser console error messages
avatarView.avatarController.onConnectionState = (state) => {
  if (state === ConnectionState.failed) {
    console.error('Connection failed')
    // Implement reconnection logic
  }
}

Performance Issues

Problem Description: Digital human rendering frame rate is lower than expected, affecting user experience.Possible Causes:
  1. Insufficient browser performance
  2. Insufficient device performance
  3. Insufficient memory
  4. Using WebGL instead of WebGPU
Optimization Suggestions:
  1. Use modern browsers that support WebGPU
  2. Reduce rendering resolution
  3. Close unnecessary tabs and background processes
  4. Check if browser hardware acceleration is enabled
Code Example:
// Check rendering backend (SDK will automatically select)
// You can view logs in browser console

// Optimization: Reduce number of simultaneously loaded characters
// Optimization: Clean up unnecessary views in a timely manner
avatarView.dispose()
Problem Description: Application memory usage is too high, which may cause crashes.Solution:
  1. Release unnecessary view instances in a timely manner
  2. Use dispose() to clean up resources
  3. Monitor memory usage
  4. Avoid memory leaks
  5. When disposing AvatarView instances, must call dispose() to properly clean up resources.
Code Example:
class MemoryEfficientComponent {
  private avatarView?: AvatarView
  
  cleanup() {
    if (this.avatarView) {
      this.avatarView.dispose()
      this.avatarView = undefined
    }
    
    // If no longer using SDK, clean up global resources
    AvatarKit.cleanup()
  }
  
  async switchCharacter(characterId: string, container: HTMLElement) {
    // Dispose old view before creating new one
    if (this.avatarView) {
      this.avatarView.dispose()
    }
    
    // Load new character
    const avatarManager = AvatarManager.shared
    const newAvatar = await avatarManager.load(characterId)
    
    // Create new view
    this.avatarView = new AvatarView(newAvatar, container)
    await this.avatarView.ready
    
    // SDK mode: start connection
    await this.avatarView.avatarController.start()
  }
}
Problem Description: Character loading time is too long, affecting user experience.Optimization Suggestions:
  1. Preload commonly used characters
  2. Use resource caching (SDK handles automatically)
  3. Optimize network connection
  4. Display loading progress indicators
const avatar = await avatarManager.load('character-id', (progress) => {
  if (progress.type === LoadProgress.downloading) {
    // Display progress
    console.log(`Loading: ${progress.progress}%`)
  }
})

Feature Questions

Solution: SDK will output the rendering backend information used during initialization, which can be viewed in the browser console logs.Example:
// SDK will automatically select the best rendering backend
// Logs will show something like: Using WebGPU renderer or Using WebGL renderer
Solution: SDK provides onError callback where you can handle errors and implement reconnection logic.
avatarView.avatarController.onError = (error) => {
  console.error('AvatarController error:', error)
  // Implement reconnection logic
  setTimeout(() => {
    avatarView.avatarController.start()
  }, 1000)
}
Solution: Use avatarView.updateCameraConfig() method to update camera configuration.
avatarView.updateCameraConfig({
  position: [0, 1.5, 3],
  target: [0, 1, 0],
  fov: 45,
  near: 0.1,
  far: 100
})
Solution: SDK receives audio data in ArrayBuffer format through the send() method. For specific format requirements, please refer to the server protocol documentation.
// Audio data example
const audioData = new ArrayBuffer(1024) // Audio data
avatarView.avatarController.send(audioData, false)

// Must call and set end=true after audio sending ends
avatarView.avatarController.send(new ArrayBuffer(0), true)
Solution: Use setBackgroundImage() method to set background image.
avatarView.setBackgroundImage('https://example.com/background.jpg')

Browser Compatibility

Problem Description: Functionality is abnormal in Safari.Notes:
  • Safari has limited WebGPU support, SDK will automatically fallback to WebGL
  • Ensure using Safari 14+ version
  • Some features may behave differently in Safari
Solution:
  1. Update to the latest Safari version
  2. Check browser console error messages
  3. Confirm WebGL support is normal
Problem Description: Functionality is abnormal in mobile browsers.Notes:
  • iOS Safari 14+ and Android Chrome (Android 8+) are supported
  • Mobile devices mainly use WebGL rendering backend
  • Performance may differ from desktop
Solution:
  1. Ensure mobile browser version meets requirements
  2. Optimize mobile performance settings
  3. Test on different mobile devices

Debugging Tips

Solution: SDK will output log information in the browser console, which can be viewed in developer tools.
// Ensure browser console is open
// SDK will automatically output initialization, connection state, and other information
Solution: Use browser developer tools’ performance monitoring features, or implement custom monitoring.
// Monitor frame rate
let frameCount = 0
let lastTime = performance.now()

function monitorPerformance() {
  frameCount++
  const currentTime = performance.now()
  if (currentTime - lastTime >= 1000) {
    const fps = frameCount
    console.log(`FPS: ${fps}`)
    frameCount = 0
    lastTime = currentTime
  }
  requestAnimationFrame(monitorPerformance)
}
Troubleshooting Steps:
  1. Check browser console error messages
  2. Use browser developer tools’ memory analysis
  3. Check if resource cleanup is correct
  4. Verify network connection status
Solution:
// Clean up in component lifecycle (recommended approach)
// React example
useEffect(() => {
  return () => {
    avatarView?.dispose()
    AvatarKit.cleanup()
  }
}, [])

// Vue example
onUnmounted(() => {
  avatarView?.dispose()
  AvatarKit.cleanup()
})

// If page-level handling is needed, use pagehide event (instead of beforeunload)
window.addEventListener('pagehide', () => {
  avatarView?.dispose()
  AvatarKit.cleanup()
})