Game audio systems, music, spatial audio, sound effects, and voice implementation. Build immersive audio experiences with professional middleware integration.
Implements production-ready audio systems with pooling, FMOD integration, and spatial audio. Use when creating sound managers, adaptive music state machines, or troubleshooting audio issues like popping, voice limits, and jarring transitions.
/plugin marketplace add pluginagentmarketplace/custom-plugin-game-developer/plugin install custom-plugin-game-developer@pluginagentmarketplace-game-developerThis skill inherits all available tools. When active, it can use any tool Claude has access to.
assets/audio_config.yamlreferences/AUDIO_GUIDE.mdscripts/audio_manager.py┌─────────────────────────────────────────────────────────────┐
│ GAME AUDIO PIPELINE │
├─────────────────────────────────────────────────────────────┤
│ SOURCES: SFX | Music | Voice | Ambient │
│ ↓ │
│ MIDDLEWARE: Wwise / FMOD / Engine Audio │
│ ↓ │
│ PROCESSING: 3D Spatial | Reverb | EQ | Compression │
│ ↓ │
│ MIXING: Master → Submixes → Individual Tracks │
│ ↓ │
│ OUTPUT: Speakers / Headphones (Stereo/Surround/Binaural) │
└─────────────────────────────────────────────────────────────┘
// ✅ Production-Ready: Audio Manager
public class AudioManager : MonoBehaviour
{
public static AudioManager Instance { get; private set; }
[System.Serializable]
public class SoundBank
{
public string id;
public AudioClip[] clips;
[Range(0f, 1f)] public float volume = 1f;
[Range(0.1f, 3f)] public float pitchVariation = 0.1f;
}
[SerializeField] private SoundBank[] _soundBanks;
[SerializeField] private int _poolSize = 20;
private Dictionary<string, SoundBank> _bankLookup;
private Queue<AudioSource> _sourcePool;
private void Awake()
{
if (Instance != null) { Destroy(gameObject); return; }
Instance = this;
DontDestroyOnLoad(gameObject);
InitializePool();
BuildLookup();
}
public void PlaySound(string id, Vector3 position)
{
if (!_bankLookup.TryGetValue(id, out var bank)) return;
if (bank.clips.Length == 0) return;
var source = GetPooledSource();
source.transform.position = position;
source.clip = bank.clips[Random.Range(0, bank.clips.Length)];
source.volume = bank.volume;
source.pitch = 1f + Random.Range(-bank.pitchVariation, bank.pitchVariation);
source.Play();
StartCoroutine(ReturnToPool(source, source.clip.length));
}
private AudioSource GetPooledSource()
{
if (_sourcePool.Count > 0) return _sourcePool.Dequeue();
return CreateNewSource();
}
private void InitializePool() { /* ... */ }
private void BuildLookup() { /* ... */ }
private AudioSource CreateNewSource() { /* ... */ }
private IEnumerator ReturnToPool(AudioSource s, float delay) { /* ... */ }
}
// ✅ Production-Ready: FMOD Event Player
public class FMODEventPlayer : MonoBehaviour
{
[SerializeField] private FMODUnity.EventReference _eventRef;
private FMOD.Studio.EventInstance _instance;
private bool _isPlaying;
public void Play()
{
if (_isPlaying) Stop();
_instance = FMODUnity.RuntimeManager.CreateInstance(_eventRef);
_instance.set3DAttributes(FMODUnity.RuntimeUtils.To3DAttributes(transform));
_instance.start();
_isPlaying = true;
}
public void SetParameter(string name, float value)
{
if (_isPlaying)
_instance.setParameterByName(name, value);
}
public void Stop(bool allowFadeout = true)
{
if (!_isPlaying) return;
_instance.stop(allowFadeout
? FMOD.Studio.STOP_MODE.ALLOWFADEOUT
: FMOD.Studio.STOP_MODE.IMMEDIATE);
_instance.release();
_isPlaying = false;
}
private void OnDestroy() => Stop(false);
}
3D AUDIO CONFIGURATION:
┌─────────────────────────────────────────────────────────────┐
│ ATTENUATION CURVES: │
│ │
│ Volume │████████████ │
│ │ ████ │
│ │ ████ │
│ │ ████ │
│ └──────────────────────────→ Distance │
│ 0m 10m 30m 50m │
│ │
│ Min Distance: 1m (full volume) │
│ Max Distance: 50m (inaudible) │
│ Rolloff: Logarithmic (realistic) │
└─────────────────────────────────────────────────────────────┘
MUSIC STATE TRANSITIONS:
┌─────────────────────────────────────────────────────────────┐
│ │
│ [EXPLORATION] ←──────────→ [TENSION] │
│ │ │ │
│ ↓ ↓ │
│ [DISCOVERY] [COMBAT] │
│ │ │
│ ↓ │
│ [VICTORY] / [DEFEAT] │
│ │
│ Transition Rules: │
│ • Crossfade on beat boundaries │
│ • 2-4 bar transition windows │
│ • Intensity parameter controls layers │
└─────────────────────────────────────────────────────────────┘
| Bus | Content | Target Level |
|---|---|---|
| Master | Final mix | -3dB peak |
| Music | BGM, Stingers | -12dB to -6dB |
| SFX | Gameplay sounds | -6dB to 0dB |
| Voice | Dialogue, VO | -6dB to -3dB |
| Ambient | Environment | -18dB to -12dB |
┌─────────────────────────────────────────────────────────────┐
│ PROBLEM: Audio popping/clicking │
├─────────────────────────────────────────────────────────────┤
│ SOLUTIONS: │
│ → Add fade in/out (5-10ms) │
│ → Check sample rate mismatches │
│ → Increase audio buffer size │
│ → Use audio source pooling │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ PROBLEM: Too many simultaneous sounds │
├─────────────────────────────────────────────────────────────┤
│ SOLUTIONS: │
│ → Implement voice limiting per category │
│ → Priority system (important sounds steal) │
│ → Distance-based culling │
│ → Virtual voices (middleware feature) │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ PROBLEM: Music transitions are jarring │
├─────────────────────────────────────────────────────────────┤
│ SOLUTIONS: │
│ → Align transitions to musical bars │
│ → Use crossfades (1-4 seconds) │
│ → Prepare transition stingers │
│ → Match keys between sections │
└─────────────────────────────────────────────────────────────┘
| Platform | Max Voices | Compression | Streaming |
|---|---|---|---|
| Mobile | 16-32 | High (Vorbis) | Required |
| Console | 64-128 | Medium | Large files |
| PC | 128-256 | Low | Optional |
Use this skill: When implementing audio, designing sound, or composing music.
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.