Claude Skill

roblox-audio

Use when implementing Roblox audio playback, spatial sound, music, sound effects, SoundGroups, or dynamic audio effects.

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download tabooharmony-roblox-brain-skills_gameplay_roblox-audio-6051c35.zip · 5 KB
Part of tabooharmony/roblox-brain — 29 skills

Install

skills CLI npx skills add https://github.com/TabooHarmony/roblox-brain/tree/main/skills/gameplay/roblox-audio
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install tabooharmony-roblox-brain@llmmart
Git git clone https://github.com/TabooHarmony/roblox-brain.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole tabooharmony/roblox-brain collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Roblox Audio

When to Load

Load when implementing audio playback, spatial/3D sound, background music, sound effects, audio mixing (SoundGroups), or dynamic effects. Covers both legacy Sound objects and the newer modular AudioPlayer/Wire system.

Quick Reference

Two Systems: Legacy (Sound/SoundGroup/SoundEffect): simpler. New modular (AudioPlayer/AudioEmitter/Wire/AudioDeviceOutput): preferred for new projects, required for voice chat.

Sound Placement: BasePart child → volumetric. Attachment/MeshPart → point source. SoundService/Workspace → global (BGM/UI).

Legacy Setup:

local s = Instance.new("Sound")
s.SoundId = "rbxassetid://ID"; s.Looped = true; s.Volume = 0.25
s.RollOffMode = Enum.RollOffMode.InverseTapered
s.RollOffMinDistance = 10; s.RollOffMaxDistance = 100
s.Parent = SoundService; s:Play()

SoundGroups (mixer): Nest SoundGroup under Master for player-adjustable Music vs SFX volume. bgMusic.SoundGroup = musicGroup. Effects (ReverbSoundEffect, EqualizerSoundEffect, CompressorSoundEffect, etc.) parent to Sound/SoundGroup. Ducking: CompressorSoundEffect with SideChain = sfxGroup on music.

New Modular: 2D: AudioPlayer → Wire → AudioDeviceOutput. 3D: AudioPlayer → Wire → AudioEmitter (on Part). Studio/plugin-only SoundService.DefaultListenerLocation controls the default listener; wire an explicit AudioListener for runtime control.

One-Shot SFX:

local function playSFX(parent, id)
    local s = Instance.new("Sound"); s.SoundId = id
    s.RollOffMode = Enum.RollOffMode.InverseTapered
    s.RollOffMinDistance = 10; s.RollOffMaxDistance = 80
    s.Parent = parent; s:Play()
    s.Ended:Once(function() s:Destroy() end)
end

Preload: ContentProvider:PreloadAsync({sound1, sound2}). Client SFX: FireClient → OnClientEvent creates invisible Part + playSFX.

Pitfalls: Server sounds have latency → play feedback on client. Default RollOffMaxDistance=10000 studs → set explicitly. Volume > 1 clips. Rapid-fire → check IsPlaying. Always Destroy() one-shots after Ended.

See references/full.md for detailed examples, effect table, and client-side patterns.

Files (roblox-brain)
  • references
    • full.md 9.2 KB
      # Roblox Audio: Full Reference
      
      
      > **Code in this reference is illustrative. Adapt to your game and verify in Studio before production use.**
      
      ## Legacy System (Sound Objects)
      
      ### Where to Place Sounds
      
      | Location | Behavior | Use for |
      |----------|----------|---------|
      | Child of block/sphere/cylinder BasePart | Volumetric: emits from entire surface, volume changes with distance AND part size | Ambient zones, large area sounds |
      | Child of Attachment, MeshPart, TrussPart, WedgePart | Point source: emits from single point, volume changes with distance | Footsteps, impacts, small objects |
      | Within SoundService or Workspace | Global: same volume everywhere regardless of position | Background music, UI sounds |
      
      ### Basic Playback
      
      ```luau
      -- Background music (global, in SoundService)
      local SoundService = game:GetService("SoundService")
      local bgMusic = Instance.new("Sound")
      bgMusic.Name = "BackgroundMusic"
      bgMusic.SoundId = "rbxassetid://1843463175"
      bgMusic.Looped = true
      bgMusic.Volume = 0.25
      bgMusic.Parent = SoundService
      bgMusic:Play()
      ```
      
      ```luau
      -- Positional sound (3D, on a part)
      local waterfall = Instance.new("Sound")
      waterfall.SoundId = "rbxassetid://ASSET_ID"
      waterfall.Looped = true
      waterfall.Volume = 0.5
      waterfall.RollOffMode = Enum.RollOffMode.InverseTapered
      waterfall.RollOffMinDistance = 10  -- full volume within this range
      waterfall.RollOffMaxDistance = 100 -- silent beyond this range
      waterfall.Parent = workspace.WaterfallPart
      waterfall:Play()
      ```
      
      ### RollOff Modes
      
      | Mode | Behavior |
      |------|----------|
      | `Inverse` | Realistic falloff (1/distance). Drops quickly near source, slowly far away. |
      | `Linear` | Linear falloff between min and max distance. |
      | `InverseTapered` | Inverse near the source, tapers to silence at max. Most natural for games. |
      | `LinearSquare` | Attempt at realistic with linear square curve. |
      
      - `RollOffMinDistance`: distance (studs) where volume starts decreasing. Default 10.
      - `RollOffMaxDistance`: distance where volume reaches zero. Default 10000 (effectively infinite).
      
      ### SoundGroups (Audio Mixer)
      
      SoundGroups let you control volume of multiple sounds at once. Nest them for a mix tree.
      
      ```luau
      -- Create mix hierarchy in SoundService
      local master = Instance.new("SoundGroup")
      master.Name = "Master"
      master.Volume = 1
      master.Parent = SoundService
      
      local music = Instance.new("SoundGroup")
      music.Name = "Music"
      music.Volume = 0.5
      music.Parent = master  -- nested under Master
      
      local sfx = Instance.new("SoundGroup")
      sfx.Name = "SFX"
      sfx.Volume = 0.8
      sfx.Parent = master
      
      -- Assign a sound to a group
      bgMusic.SoundGroup = music
      ```
      
      Adjusting `master.Volume` affects ALL nested groups. Players can control Music vs SFX independently.
      
      ### Dynamic Effects
      
      Parent these to a Sound or SoundGroup to modify audio:
      
      | Effect | What it does | Use for |
      |--------|-------------|---------|
      | `ReverbSoundEffect` | Simulates room reflections | Caves, large halls, bathrooms |
      | `EqualizerSoundEffect` | Control volume of frequency bands | Muffled underwater, radio effect |
      | `CompressorSoundEffect` | Reduces dynamic range | Consistent volume, ducking |
      | `ChorusSoundEffect` | Thickens sound with copies | Ethereal voices, dream sequences |
      | `DistortionSoundEffect` | Adds distortion/overdrive | Damaged radio, horror |
      | `FlangeSoundEffect` | Sweeping comb filter | Sci-fi, psychedelic |
      | `PitchShiftSoundEffect` | Changes pitch without speed | Chipmunk voice, deep voice |
      | `TremoloSoundEffect` | Periodic volume modulation | Vibrato, pulsing |
      
      ```luau
      -- Add reverb to all sounds in a cave zone
      local caveGroup = Instance.new("SoundGroup")
      caveGroup.Name = "Cave"
      caveGroup.Parent = master
      
      local reverb = Instance.new("ReverbSoundEffect")
      reverb.DecayTime = 3.0
      reverb.Density = 1.0
      reverb.Diffusion = 1.0
      reverb.WetLevel = -6  -- dB, how much reverb vs dry signal
      reverb.Parent = caveGroup
      ```
      
      ### Ducking (Lower music when SFX plays)
      
      Use CompressorSoundEffect with a SideChain:
      
      ```luau
      -- Music ducks when SFX plays
      local compressor = Instance.new("CompressorSoundEffect")
      compressor.Threshold = -20
      compressor.Ratio = 4
      compressor.Attack = 0.01
      compressor.Release = 0.2
      compressor.SideChain = sfx  -- SFX group triggers the compression
      compressor.Parent = music   -- Music group gets compressed
      ```
      
      ## New Modular System (Audio Objects)
      
      The new system uses explicit wiring between audio components. Each object maps to a real-world audio device:
      
      | Object | Real-world equivalent | Role |
      |--------|----------------------|------|
      | `AudioPlayer` | Media player / turntable | Produces audio from an asset |
      | `AudioEmitter` | Speaker in 3D space | Emits audio positionally |
      | `AudioListener` | Microphone | Picks up audio from 3D space |
      | `AudioDeviceOutput` | Headphones/speakers | Plays to the real player |
      | `AudioDeviceInput` | Physical microphone | Captures real player voice |
      | `Wire` | Audio cable | Carries stream between objects |
      | `AudioTextToSpeech` | TTS engine | Converts text to speech |
      | `AudioEqualizer` | EQ pedal | Modifies frequency response |
      | `AudioCompressor` | Compressor pedal | Controls dynamic range |
      | `AudioReverb` | Reverb unit | Adds room reflections |
      
      ### 2D Audio (non-positional)
      
      ```
      AudioPlayer → Wire → AudioDeviceOutput
      ```
      
      ```luau
      -- In SoundService:
      local player = Instance.new("AudioPlayer")
      player.AssetId = "rbxassetid://MUSIC_ID"
      player.Looping = true
      player.Volume = 0.5
      player.Parent = SoundService
      
      local output = Instance.new("AudioDeviceOutput")
      output.Parent = SoundService
      
      local wire = Instance.new("Wire")
      wire.SourceInstance = player
      wire.TargetInstance = output
      wire.Parent = SoundService
      
      player:Play()
      ```
      
      ### 3D Audio (positional)
      
      ```
      AudioPlayer → Wire → AudioEmitter (on Part)
      AudioListener (on Camera/Character) → Wire → AudioDeviceOutput
      ```
      
      ```luau
      -- On the part that emits sound:
      local player = Instance.new("AudioPlayer")
      player.AssetId = "rbxassetid://SFX_ID"
      player.Parent = workspace.CampfirePart
      
      local emitter = Instance.new("AudioEmitter")
      emitter.Parent = workspace.CampfirePart
      
      local wire = Instance.new("Wire")
      wire.SourceInstance = player
      wire.TargetInstance = emitter
      wire.Parent = workspace.CampfirePart
      
      -- Studio/plugin-only SoundService.DefaultListenerLocation controls whether
      -- Roblox creates and wires the default AudioListener and AudioDeviceOutput.
      -- For runtime custom placement, create and wire an explicit AudioListener.
      
      player:Play()
      ```
      
      `AudioEmitter.DistanceAttenuation` controls the volume-over-distance curve.
      
      ### Triggering Audio from Scripts
      
      ```luau
      -- Basic trigger pattern
      local audioPlayer = script.Parent -- AudioPlayer
      local part = audioPlayer.Parent
      
      part.Touched:Connect(function(hit)
          if hit.Parent:FindFirstChildOfClass("Humanoid") then
              audioPlayer:Play()
          end
      end)
      ```
      
      ## Patterns
      
      ### Preloading Critical Audio
      
      ```luau
      local ContentProvider = game:GetService("ContentProvider")
      
      local criticalSounds = {
          Instance.new("Sound"), -- temp instances for preloading
          Instance.new("Sound"),
      }
      criticalSounds[1].SoundId = "rbxassetid://HIT_SOUND"
      criticalSounds[2].SoundId = "rbxassetid://JUMP_SOUND"
      
      ContentProvider:PreloadAsync(criticalSounds)
      -- Now these assets are cached and play instantly
      ```
      
      ### One-Shot SFX (auto-cleanup)
      
      ```luau
      local function playSFX(parent: BasePart, soundId: string)
          local sound = Instance.new("Sound")
          sound.SoundId = soundId
          sound.RollOffMode = Enum.RollOffMode.InverseTapered
          sound.RollOffMinDistance = 10
          sound.RollOffMaxDistance = 80
          sound.Parent = parent
          sound:Play()
          sound.Ended:Once(function()
              sound:Destroy()
          end)
      end
      ```
      
      ### Client-Side Playback
      
      Play sounds on the client for zero-latency feedback. Server tells client WHAT to play:
      
      ```luau
      -- Server
      SFXRemote:FireClient(player, "hit", workspace.Enemy.HumanoidRootPart.Position)
      
      -- Client
      SFXRemote.OnClientEvent:Connect(function(sfxName: string, position: Vector3)
          local part = Instance.new("Part")
          part.Position = position
          part.Anchored = true
          part.Transparency = 1
          part.CanCollide = false
          part.Parent = workspace
          playSFX(part, SFX_IDS[sfxName])
          task.delay(3, function() part:Destroy() end)
      end)
      ```
      
      ## Common Mistakes
      
      - **Playing sounds on the server for feedback**: Server sounds have network latency. Play on client for responsive SFX. Server only for sounds ALL players must hear identically.
      - **No RollOff configuration**: Default RollOffMaxDistance is 10000 studs (basically infinite). Set it explicitly or sounds bleed across the entire map.
      - **Stacking rapid sounds**: Playing the same sound 10x in 0.1s creates ear-splitting overlap. Check `sound.IsPlaying` or use a cooldown.
      - **Forgetting Looped = false on one-shots**: Default is false, but if you clone from a template that has Looped = true, your SFX plays forever.
      - **Not destroying one-shot sounds**: Sounds parented to destroyed parts get GC'd, but sounds in SoundService accumulate. Always Destroy() after Ended.
      - **Volume > 1**: Causes clipping/distortion. Keep ≤ 1. Use SoundGroup volume for amplification.
      - **Using legacy system for voice chat integration**: The new AudioPlayer/Wire system is required for voice chat features (AudioDeviceInput, AudioSpeechToText).
      - **No SoundGroup hierarchy**: Without groups, players can't independently control music vs SFX volume in settings.
      
  • SKILL.md 2.6 KB
    ---
    name: roblox-audio
    description: "Use when implementing Roblox audio playback, spatial sound, music, sound effects, SoundGroups, or dynamic audio effects."
    last_reviewed: 2026-07-26
    sources:
      - https://create.roblox.com/docs/reference/engine/classes/SoundService
      - https://create.roblox.com/docs/audio/objects
      - https://create.roblox.com/docs/audio/effects
      - https://create.roblox.com/docs/sound/groups
      - https://create.roblox.com/docs/sound/dynamic-effects
    ---
    
    # Roblox Audio
    
    ## When to Load
    
    Load when implementing audio playback, spatial/3D sound, background music, sound effects, audio mixing (SoundGroups), or dynamic effects. Covers both legacy Sound objects and the newer modular AudioPlayer/Wire system.
    
    ## Quick Reference
    
    **Two Systems**: Legacy (`Sound`/`SoundGroup`/`SoundEffect`): simpler. New modular (`AudioPlayer`/`AudioEmitter`/`Wire`/`AudioDeviceOutput`): preferred for new projects, required for voice chat.
    
    **Sound Placement**: BasePart child → volumetric. Attachment/MeshPart → point source. SoundService/Workspace → global (BGM/UI).
    
    **Legacy Setup**:
    ```luau
    local s = Instance.new("Sound")
    s.SoundId = "rbxassetid://ID"; s.Looped = true; s.Volume = 0.25
    s.RollOffMode = Enum.RollOffMode.InverseTapered
    s.RollOffMinDistance = 10; s.RollOffMaxDistance = 100
    s.Parent = SoundService; s:Play()
    ```
    
    **SoundGroups** (mixer): Nest `SoundGroup` under Master for player-adjustable Music vs SFX volume. `bgMusic.SoundGroup = musicGroup`. Effects (`ReverbSoundEffect`, `EqualizerSoundEffect`, `CompressorSoundEffect`, etc.) parent to Sound/SoundGroup. Ducking: `CompressorSoundEffect` with `SideChain = sfxGroup` on music.
    
    **New Modular**: 2D: `AudioPlayer → Wire → AudioDeviceOutput`. 3D: `AudioPlayer → Wire → AudioEmitter` (on Part). Studio/plugin-only `SoundService.DefaultListenerLocation` controls the default listener; wire an explicit `AudioListener` for runtime control.
    
    **One-Shot SFX**:
    ```luau
    local function playSFX(parent, id)
        local s = Instance.new("Sound"); s.SoundId = id
        s.RollOffMode = Enum.RollOffMode.InverseTapered
        s.RollOffMinDistance = 10; s.RollOffMaxDistance = 80
        s.Parent = parent; s:Play()
        s.Ended:Once(function() s:Destroy() end)
    end
    ```
    
    **Preload**: `ContentProvider:PreloadAsync({sound1, sound2})`. **Client SFX**: `FireClient` → `OnClientEvent` creates invisible Part + `playSFX`.
    
    **Pitfalls**: Server sounds have latency → play feedback on client. Default `RollOffMaxDistance`=10000 studs → set explicitly. Volume > 1 clips. Rapid-fire → check `IsPlaying`. Always `Destroy()` one-shots after `Ended`.
    
    See `references/full.md` for detailed examples, effect table, and client-side patterns.
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related