roblox-audio
Skill25 starsChanged 56 days agoMITView on GitHub
Build or debug Roblox music, spatial audio, effects, text-to-speech, and speech-to-text. Use for audio graphs, asset permissions, playback problems, or migration from Sound.
3 other projects use a version of this.
Adopted by
Most recently taken up by
- EL4CTEO/roblox-skillstheir own version, first seen Sep 28, 2026
- TabooHarmony/roblox-braintheir own version, first seen Sep 23, 2026
- szlay/roblox-basetheir own version, first seen Jul 24, 2026
Other versions3 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 3
- TabooHarmony/roblox-brain★ 150same name
- EL4CTEO/roblox-skills★ 92same name
- szlay/roblox-base★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository16 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- roblox-animationSkill
- roblox-coreSkill
- roblox-datastoresSkill
- roblox-gamepassesSkill
- roblox-mcpSkill
- roblox-networkingSkill
- roblox-npcsSkill
- roblox-open-cloudSkill
- roblox-physicsSkill
- roblox-rojoSkill
- robloxSkill
- roblox-teleportSkill
- roblox-testingSkill
- roblox-user-interfacesSkill
- roblox-vfxSkill
The file
We split this skill into the rules it gives an agent
9 rules. About 0 are common, 6 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈6
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 135
None: no auto-listener; create one via script.
- Very specific: line 139
When set to Character or Camera, the engine auto-creates an AudioDeviceOutput under SoundService at runtime.
- Distinctive: line 196
Use cases: accessibility (reading UI text aloud), NPC voiceover without recorded audio, dynamic announcements.
- Very specific: line 210
3D vs 2D: if the sound has a world position, use 3D (AudioEmitter).
- Distinctive: line 212
Mobile: test at low quality. The engine may drop effects.
- Distinctive: line 223
Not preloading, causing first-play hitches on mobile.
- Very specific: line 234
Place 3D emitters on the parts that should make sound.
- Distinctive: line 235
Add effects where they add value (reverb in caves, muffling underwater, ducking).
- Distinctive: line 238
Verify asset permissions for any third-party audio.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
roblox-audio
Official sources:
- https://create.roblox.com/docs/en-us/audio/objects (audio graph overview)
- https://create.roblox.com/docs/en-us/audio/effects (audio effects)
- https://create.roblox.com/docs/en-us/reference/engine/classes/Sound (legacy
Sound) - https://create.roblox.com/docs/en-us/reference/engine/classes/SoundService
- Engine classes:
AudioPlayer,AudioEmitter,AudioListener,AudioDeviceOutput,AudioDeviceInput,AudioTextToSpeech,AudioSpeechToText,Wire,AudioEqualizer,AudioCompressor,AudioReverb,AudioChorus,AudioDistortion,AudioEcho,AudioFlanger,AudioPitchShifter,AudioTremolo,AudioFader,AudioAnalyzer - Full reference: https://create.roblox.com/docs/en-us/reference/engine
Roblox recommends audio objects over Sound, SoundGroup, and SoundEffect. New work should use the graph; legacy code can keep using Sound where the graph offers no advantage.
Cross-reference:
- roblox-core/SKILL.md for services and script locations.
- roblox-animation/SKILL.md for driving audio from animation markers (footsteps, impact sounds).
- roblox-user-interfaces/SKILL.md for UI-triggered sound feedback.
- roblox-networking/SKILL.md for client-authoritative cosmetic audio vs server-authoritative gameplay audio.
The two systems
Modern audio graph (recommended for new work)
Modular instances that mirror real-world audio devices. Each object produces, consumes, modifies, or carries an audio stream. You wire them together with Wire instances (SourceInstance → TargetInstance).
| Object | Role | Real-world analog |
AudioPlayer | Produces a stream from an audio asset ID | A audio file player |
AudioEmitter | Emits a stream into the 3D environment (parent position = emission point) | A speaker in the world |
AudioListener | Picks up streams from the environment (parent = camera or character) | A microphone in the world |
AudioDeviceOutput | Plays a stream to the player's physical speaker/headphones | The player's hardware output |
AudioDeviceInput | Captures audio from the player's physical microphone | The player's hardware mic |
AudioTextToSpeech | Converts text to audio with an artificial voice | A TTS engine |
AudioSpeechToText | Converts spoken audio to text | A transcription engine |
Wire | Carries a stream from SourceInstance to TargetInstance | An audio cable |
Effects (all "modify" category): AudioEqualizer, AudioCompressor, AudioReverb, AudioChorus, AudioDistortion, AudioEcho, AudioFlanger, AudioPitchShifter, AudioTremolo, AudioFader, AudioAnalyzer. See references/audio-effects.md.
Legacy Sound system (still works, discouraged)
Sound parented to a BasePart or Attachment emits from that position with built-in Doppler and distance rolloff (RollOffMode, RollOffMaxDistance, RollOffMinDistance, EmitterSize). A "global" Sound (not parented to a part/attachment) plays at constant volume everywhere. SoundGroup controls group volume and effects; SoundEffect subclasses (EqualizerSoundEffect, ReverbSoundEffect, etc.) apply per-group effects. SoundService exposes global properties (AmbientReverb, DistanceFactor, DopplerScale, RespectFilteringEnabled) that affect Sound playback.
SoundService.AmbientReverb and the Doppler/distance properties affect only legacy Sound, not the audio graph. The graph has its own effect objects and per-emitter DistanceAttenuation curves.
Decision tree: which system?
- New experience, greenfield audio → audio graph. It supports TTS, STT, acoustic simulation, and routing.
- Simple 2D SFX or music with no routing/effects →
Soundis acceptable and simpler. Don't rewrite working legacy code just to migrate. - 3D positional audio with custom attenuation curves → audio graph (
AudioEmitter.DistanceAttenuation). - Multiple sources through one effect (e.g. all gunfire through one compressor) → audio graph (one effect, many players wired in).
- Text-to-speech or speech-to-text → audio graph (only the graph has
AudioTextToSpeech/AudioSpeechToText). - Voice chat / spatial voice →
VoiceChatService(separate from in-experience audio; usesAudioDeviceInputunder the hood whenUseAudioApiis enabled). - Acoustic simulation (occlusion, diffraction, reverb) → audio graph with
SoundService.AcousticSimulationEnabled = trueand per-instanceAcousticSimulationEnabledon emitters/listeners. - Quick prototype / one-shot UI click sound →
Soundis fine.
See references/audio-graph-vs-sound.md for a side-by-side property map and migration notes.
2D audio (non-directional)
Same volume everywhere. Requires: AudioPlayer → Wire → AudioDeviceOutput, all parented under SoundService.
--!strict
local SoundService = game:GetService("SoundService")
local player = Instance.new("AudioPlayer")
player.AssetId = "rbxassetid://YOUR_AUDIO_ID"
player.Looping = true
player.Volume = 1
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)
Volume changes with the listener's distance to the emitter. Requires six objects: AudioPlayer → Wire → AudioEmitter (parented to the 3D part), and AudioListener → Wire → AudioDeviceOutput (under SoundService). Set SoundService.ListenerLocation to Character or Camera (the engine auto-creates the AudioDeviceOutput under SoundService at runtime when you do).
--!strict
local SoundService = game:GetService("SoundService")
SoundService.ListenerLocation = Enum.ListenerLocation.Camera -- or Character
-- On the 3D part that should emit audio:
local part = workspace:WaitForChild("NoisyPart")
local player = Instance.new("AudioPlayer")
player.AssetId = "rbxassetid://YOUR_AUDIO_ID"
player.Looping = true
player.Parent = part
local emitter = Instance.new("AudioEmitter")
-- Custom curve: DistanceAttenuation is a NumberSequence (x = distance studs, y = volume 0..1).
-- This curve is only used when DistanceAttenuationMode == Custom (the default).
emitter.DistanceAttenuation = NumberSequence.new({
NumberSequenceKeypoint.new(0, 1), -- full volume at 0 studs
NumberSequenceKeypoint.new(50, 0.5), -- half volume at 50 studs
NumberSequenceKeypoint.new(70, 0), -- silent at 70 studs
})
-- Preset alternative (no custom curve needed):
-- emitter.DistanceAttenuationMode = Enum.DistanceAttenuationMode.Inverse
-- emitter.DistanceAttenuationBounds = NumberRange.new(4, 10000) -- [min,max] for the preset rolloff
emitter.Parent = part
local wire = Instance.new("Wire")
wire.SourceInstance = player
wire.TargetInstance = emitter
wire.Parent = part
player:Play()The emitter's parent position determines where audio emits from. AudioEmitter ignores its own orientation; rotate the parent part/attachment to steer emission.
Distance model: AudioEmitter.DistanceAttenuationMode selects the rolloff formula (Custom by default; uses your DistanceAttenuation curve; other presets use DistanceAttenuationBounds which defaults to [4, 10000] and ignore the custom curve). GetDistanceAttenuation() always returns the custom curve even when a preset is active. Don't assume it reflects the audible rolloff unless Mode == Custom. SetDistanceAttenuation(curve) only affects playback when Mode == Custom. Angle attenuation is set via SetAngleAttenuation({[angle]=volume}) (0–180° → 0–1); use for directional sources (e.g. avatar voice projects forward).
Acoustic simulation (occlusion/diffraction/reverb): Enable SoundService.AcousticSimulationEnabled and AcousticSimulationEnabled on both the emitter and listener. The current reference no longer exposes the separate per-instance OcclusionEnabled, DiffractionEnabled, and ReverbEnabled toggles; do not generate calls to them. Use emitter:GetAudibilityFor(listener) or listener:GetAudibilityFor(emitter) for combined distance and angle attenuation (0–1).
Listener location
SoundService.ListenerLocation (a ListenerLocation enum) controls where the AudioListener is auto-created:
- Default: camera in experiences with voice chat.
- None: no auto-listener; create one via script.
- Character: parented to the local player's character (
Humanoid.RootPart). - Camera: parented to
workspace.CurrentCamera.
When set to Character or Camera, the engine auto-creates an AudioDeviceOutput under SoundService at runtime. The AudioListener picks up audio from AudioEmitters based on distance and the emitter's DistanceAttenuation curve.
Triggering audio from scripts
local audio = script.Parent :: AudioPlayer
someEvent:Connect(function()
audio:Play()
end)AudioPlayer:Play(atTime?), :Stop(atTime?). When atTime is supplied the action is scheduled against SoundService:GetMixerTime() for sample-accurate, framerate-independent timing (rhythm games / beat sync). :Cancel(actionId) cancels a future-scheduled Play/Stop (returns true if cancelled). :Pause(), :SeekTime(...), :GetWaveform(timeRange) (samples volume without playing; useful for waveform visualization vs live AudioAnalyzer). AudioPlayer.TimeVolume is tweenable. See references/audio-effects.md for tweening volume and effect parameters.
Preloading audio
Preload prominent audio assets before they're needed (loading screen, round start) to avoid first-play hitches on lower-end devices:
--!strict
local ContentProvider = game:GetService("ContentProvider")
local audioPlayer = workspace:WaitForChild("MusicPlayer") :: AudioPlayer
ContentProvider:PreloadAsync({ audioPlayer })For the legacy Sound system, preload the Sound instance the same way.
Performance limits
- Concurrent voices (simultaneously playing audio streams) are capped; the cap varies by device. Mobile is significantly lower than desktop.
- Effects cost CPU per active stream routed through them. Reverb and acoustic simulation are the heaviest.
- Acoustic simulation (
SoundService.AcousticSimulationEnabled) adds per-emitter occlusion/diffraction/reverb cost; disable on low-end clients or when not needed. - Mobile throttling: the engine may drop or degrade audio effects on low-memory clients (e.g. flipbooks were dropped on older phones; the same applies to some audio effects). Test at low quality levels.
AudioAnalyzeris for inspection only; don't chain it into audible paths unnecessarily.
Profile audio with the MicroProfiler (audio appears under worker threads) and the Developer Console Memory tab.
Script context (client vs server)
- Playback of
AudioPlayer,Sound, and effects is client-side. Each client plays its own audio. The server does not mix audio for clients. - Replication:
AudioPlayerstate (playing/paused/stopped) replicates from server to clients if the instance is in a replicated location, but per-client volume/effects are local. For one-shot SFX, prefer client-authoritative emission: server signals "this event happened" via RemoteEvent, each affected client plays the sound locally. This avoids replicating per-burst timing and respects each client's quality settings (same pattern as VFX; see roblox-vfx skill). - Music/ambience that should be synchronized across all clients can be server-driven (the
AudioPlayerlives inReplicatedStorageorSoundServiceand the server calls:Play()), but be aware each client still renders locally and may drift. AudioDeviceInput(microphone) is client-only. It captures the local player's mic. Pair withVoiceChatServicefor spatial voice. Access control:SetUserIdAccessList(userIds)+AccessType(Allow= only listed users hear the input,Deny= all except listed; defaultDeny),GetUserIdAccessList()returns the allow/deny list.- Never trust client audio state for gameplay. A client claiming "I played the reload sound" tells you nothing authoritative; validate gameplay effects on the server (see roblox-networking).
Audio asset permissions
- Audio assets uploaded before the 2022 audio privacy changes may be private or have restricted use. Assets you upload to your own experience are usable by that experience.
- The Creator Store has a library of free-to-use audio assets. These are safe to reference by asset ID in any experience.
- Audio uploaded by other creators may be unusable in your experience unless they've marked it for public use. If you reference a third-party audio asset ID and it doesn't play, permissions are the usual cause.
- For new audio, upload through the Creator Dashboard's asset manager or the Open Cloud Assets API (see roblox-open-cloud skill for programmatic upload).
Text-to-speech (TTS)
AudioTextToSpeech converts text (≤300 chars per request) to audio with an artificial voice. The available VoiceId values are 1–11 (English variants), 101–102 (Spanish), 201–202 (German), 301–302 (Italian), 401–402 (French), 501–502 (Mandarin Chinese), 601–602 (Hindi), 701–702 (Japanese), 801–802 (Arabic), 901–902 (Korean), and 1001–1002 (Portuguese); odd IDs are male and even IDs are female for the locale-specific pairs. Wire it like an AudioPlayer: for 2D, AudioTextToSpeech → Wire → AudioDeviceOutput; for 3D, AudioTextToSpeech → Wire → AudioEmitter (plus the listener→output wire). Set Text, VoiceId, Volume on the AudioTextToSpeech. :WaitForSpeechReady() yields until AssetFetchStatus is Success (or Failure). All text must comply with Roblox Community Standards and Terms of Use.
Audio analysis: AudioAnalyzer window is controlled by AudioWindowSize. Small (lowest latency, low frequency resolution), Medium (balanced), Large (highest resolution, more latency).
Use cases: accessibility (reading UI text aloud), NPC voiceover without recorded audio, dynamic announcements.
Speech-to-text (STT)
AudioSpeechToText converts speech captured by AudioDeviceInput into text. Requires VoiceChatService.UseAudioApi = Enabled. Wire: AudioDeviceInput → Wire → AudioSpeechToText. Set audioDeviceInput.Player = Players.LocalPlayer at runtime to target the local player's mic. Roblox auto-detects the spoken language (17 supported: Arabic, Chinese Simplified/Traditional, English, French, German, Indonesian, Italian, Japanese, Korean, Polish, Portuguese, Spanish, Russian, Turkish, Thai, Vietnamese).
To use STT without broadcasting voice to other players, disable VoiceChatService.EnableDefaultVoice. All audio for AudioSpeechToText must comply with Community Standards and Terms of Use.
Best practices
- Preload prominent audio (music, common SFX) during loading. One-shot UI sounds can lazy-load.
- Loop ambient/music with
Looping = true(graph) orLooped = true(legacy). For finite loops N times, use theDidLoopevent (legacySound) or count plays on the graph. - Fade in/out by tweening
AudioPlayer.Volume(graph) orSound.Volume(legacy).AudioFaderis the graph-native way to control multiple streams' volume at once. - Music vs SFX: route music and SFX through separate
AudioFaderorSoundGroupso you can mute music independently and apply ducking (SFX ducks music viaAudioCompressorsidechain). - 3D vs 2D: if the sound has a world position, use 3D (
AudioEmitter); if it's UI/global, use 2D (AudioDeviceOutputdirect). - Accessibility: offer TTS for important text, provide subtitle/caption options for VO, and never make audio the only cue for gameplay-critical info.
- Mobile: test at low quality. The engine may drop effects; design so the experience still works without them.
- Concurrency: pool
AudioPlayer/Soundinstances for frequent one-shots rather than creating/destroying per shot.
Common mistakes
- Using
Sound/SoundGroup/SoundEffectfor new work when the graph is the recommended path. - Parenting an
AudioEmittertoSoundService(it must be parented to a 3D part/attachment for 3D audio). - Forgetting the
Wire(audio won't flow from player to output/emitter). - Expecting
SoundService.AmbientReverbto affect the audio graph (it only affects legacySound). - Setting
DistanceAttenuationas a single number instead of aNumberSequence(it's a curve, not a scalar). - Trusting client audio state for gameplay (reload sounds, hit sounds) instead of server validation.
- Not preloading, causing first-play hitches on mobile.
- Hardcoding asset IDs for third-party audio that may be permission-restricted.
Scripts
scripts/AudioBus.lua: a small music/SFX bus helper usingAudioFaderto control group volume and duck music when SFX play. Adapt for your mix.
How to proceed
- Pick the system: graph for new/complex work,
Soundfor simple/legacy. - Lay out your buses (music, SFX, VO) and route through
AudioFaderorSoundGroup. - Place 3D emitters on the parts that should make sound; set
DistanceAttenuationper emitter. - Add effects where they add value (reverb in caves, muffling underwater, ducking).
- Preload, then trigger from events (animation markers, UI, gameplay).
- Profile concurrent voices and effect cost on the lowest target device.
- Verify asset permissions for any third-party audio.
<!-- catalog:references:start -->Reference index
- audio-effects.md: Route effects, mix audio buses, duck music, or tune attenuation.
- audio-graph-vs-sound.md: Choose an audio system or migrate legacy Sound code.
<!-- catalog:references:end -->Acoustic API references: https://create.roblox.com/docs/reference/engine/classes/AudioEmitter and https://create.roblox.com/docs/reference/engine/classes/AudioListener.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

