Loading...
Loading...
Audio implementation for Roblox. Both legacy Sound objects and the newer modular audio system (AudioPlayer, AudioEmitter, Wire). Positional audio, music, SFX, SoundGroups, dynamic effects. Sourced from official Roblox creator docs.
npx skill4agent add tabooharmony/roblox-brain roblox-audioSoundSoundGroupSoundEffectAudioPlayerAudioEmitterAudioListenerWireAudioDeviceOutput| 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 |
-- 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()-- 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()| Mode | Behavior |
|---|---|
| Realistic falloff (1/distance). Drops quickly near source, slowly far away. |
| Linear falloff between min and max distance. |
| Inverse near the source, tapers to silence at max. Most natural for games. |
| Attempt at realistic with linear square curve. |
RollOffMinDistanceRollOffMaxDistance-- 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 = musicmaster.Volume| Effect | What it does | Use for |
|---|---|---|
| Simulates room reflections | Caves, large halls, bathrooms |
| Control volume of frequency bands | Muffled underwater, radio effect |
| Reduces dynamic range | Consistent volume, ducking |
| Thickens sound with copies | Ethereal voices, dream sequences |
| Adds distortion/overdrive | Damaged radio, horror |
| Sweeping comb filter | Sci-fi, psychedelic |
| Changes pitch without speed | Chipmunk voice, deep voice |
| Periodic volume modulation | Vibrato, pulsing |
-- 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-- 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| Object | Real-world equivalent | Role |
|---|---|---|
| Media player / turntable | Produces audio from an asset |
| Speaker in 3D space | Emits audio positionally |
| Microphone | Picks up audio from 3D space |
| Headphones/speakers | Plays to the real player |
| Physical microphone | Captures real player voice |
| Audio cable | Carries stream between objects |
| TTS engine | Converts text to speech |
| EQ pedal | Modifies frequency response |
| Compressor pedal | Controls dynamic range |
| Reverb unit | Adds room reflections |
AudioPlayer → Wire → AudioDeviceOutput-- 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()AudioPlayer → Wire → AudioEmitter (on Part)
AudioListener (on Camera/Character) → Wire → AudioDeviceOutput-- 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
-- AudioListener is auto-created by SoundService.ListenerLocation setting
-- AudioDeviceOutput is auto-created when ListenerLocation is Character or Camera
player:Play()AudioEmitter.DistanceAttenuation-- 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)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 instantlylocal 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-- 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)sound.IsPlaying