@spelljam/audio-engine
v3.0.0
Published
A Spotify-backed theme-driven ambient music engine for browser environments.
Readme
@spelljam/audio-engine
A Spotify-backed theme-driven ambient music engine for browser environments. Send it a
Scene; it selects and plays appropriate music from Spotify.
Project: SpellJam
Repository: spelljam-audio-engine
npm package: @spelljam/audio-engine
Purpose and Scope
This package is the audio control layer of the SpellJam ecosystem. Its responsibility is to accept a Scene object and coordinate playback via the Spotify Web API.
A Scene has two independent dimensions:
mood— emotional and musical character.atmosphere— environmental colour.
The engine uses a TrackCatalog to map mood and atmosphere combinations to specific Spotify tracks.
Spotify Integration
This library requires a Spotify Premium account for playback and a registered Spotify Application to obtain a clientId. It uses the PKCE auth flow for secure, client-side authentication.
Features
- Spotify-Driven Playback: Leverages the vast Spotify library for high-quality ambient music.
- Scene-Driven Selection: Automatically selects tracks based on the current
moodandatmosphere. - Intelligent Queueing: Automatically queues related tracks (e.g., from the same album) to ensure continuous playback.
- History Management: Avoids immediate repetition of tracks.
- Master Control: unified API for volume, playback state, and device management.
Repository Structure
spelljam-audio-engine/
├── src/
│ ├── index.ts ← public API — re-exports only
│ ├── types.ts ← Scene, Mood, Atmosphere, etc.
│ ├── api/ ← Spotify Web API client
│ ├── auth/ ← Spotify PKCE authentication logic
│ ├── catalog/ ← Track mapping and selection logic
│ └── controller/ ← Main SpotifyController factoryScene Vocabulary
Moods
| Mood | Example D&D context |
| --------------- | ------------------------------------- |
| "peaceful" | Safe rest, gentle downtime |
| "exploration" | Traveling, discovering new locations |
| "suspense" | Tense moments, investigation |
| "battle" | Combat encounters |
| "boss" | Major set pieces, epic confrontations |
| "tavern" | Inns, social gatherings |
| "town" | Busy streets, markets |
| "melancholy" | Sadness, loss, aftermath |
| "triumph" | Victory, positive resolutions |
| "mystical" | Magic, wonder, fey realms |
Atmospheres
| Atmosphere | Example D&D context |
| ---------------- | ----------------------------------- |
| "forest" | Woods, nature |
| "cave" | Underground, natural caverns |
| "rain" | Light to moderate precipitation |
| "storm" | Heavy rain, thunder |
| "ocean" | Seaside, on a boat |
| "city" | Urban environments |
| "tavern_crowd" | Busy indoor social setting |
| "magic" | Arcane resonance, spellcasting |
| "fire" | Campfires, burning buildings |
| "desert" | Hot, dry, sandy regions |
| "swamp" | Wetlands, marshes |
| "snow" | Cold, wintry conditions |
| "mountains" | High altitude, rocky terrain |
| "dungeon" | Worked stone, oppressive atmosphere |
| "night" | Nocturnal environments |
| null | No specific atmosphere |
Usage
Initializing the Controller
import { createSpotifyController } from '@spelljam/audio-engine';
const controller = createSpotifyController({
clientId: 'YOUR_SPOTIFY_CLIENT_ID',
redirectUri: 'YOUR_REDIRECT_URI',
scopes: ['streaming', 'user-read-playback-state', 'user-modify-playback-state'],
});
// Start auth flow
if (!controller.isAuthenticated()) {
await controller.authenticate();
}Updating the Scene
// Update everything
await controller.setScene({
mood: 'battle',
atmosphere: 'dungeon',
});
// Change mood only
await controller.setMood('boss');
// Change atmosphere only
await controller.setAtmosphere('fire');Playback Control
await controller.play();
await controller.pause();
await controller.setVolume(50); // 0-100
await controller.next();Development
npm install
npm run build
npm test