{"slug":"roblox-audio-2","title":"roblox-audio","summary":"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.","platform":"Claude","tags":[],"authorName":"LLM Mart","authorSlug":"llm-mart","score":0,"source":"github","price":null,"verified":false,"createdAt":"2026-10-18T17:23:55.820036Z","repo":{"url":"https://github.com/nonlooped/roblox-suite","stars":22,"forks":0,"license":"MIT","updatedAt":"2026-10-17T23:48:49Z"},"bodyHtml":"<hr>\n<h2>name: roblox-audio\ndescription: \"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.\"\nlast_reviewed: 2026-08-18</h2>\n<h1>roblox-audio</h1>\n<p><strong>Official sources:</strong></p>\n<ul>\n<li><a href=\"https://create.roblox.com/docs/en-us/audio/objects\">https://create.roblox.com/docs/en-us/audio/objects</a> (audio graph overview)</li>\n<li><a href=\"https://create.roblox.com/docs/en-us/audio/effects\">https://create.roblox.com/docs/en-us/audio/effects</a> (audio effects)</li>\n<li><a href=\"https://create.roblox.com/docs/en-us/reference/engine/classes/Sound\">https://create.roblox.com/docs/en-us/reference/engine/classes/Sound</a> (legacy <code>Sound</code>)</li>\n<li><a href=\"https://create.roblox.com/docs/en-us/reference/engine/classes/SoundService\">https://create.roblox.com/docs/en-us/reference/engine/classes/SoundService</a></li>\n<li>Engine classes: <code>AudioPlayer</code>, <code>AudioEmitter</code>, <code>AudioListener</code>, <code>AudioDeviceOutput</code>, <code>AudioDeviceInput</code>, <code>AudioTextToSpeech</code>, <code>AudioSpeechToText</code>, <code>Wire</code>, <code>AudioEqualizer</code>, <code>AudioCompressor</code>, <code>AudioReverb</code>, <code>AudioChorus</code>, <code>AudioDistortion</code>, <code>AudioEcho</code>, <code>AudioFlanger</code>, <code>AudioPitchShifter</code>, <code>AudioTremolo</code>, <code>AudioFader</code>, <code>AudioAnalyzer</code></li>\n<li>Full reference: <a href=\"https://create.roblox.com/docs/en-us/reference/engine\">https://create.roblox.com/docs/en-us/reference/engine</a></li>\n</ul>\n<p>Roblox recommends audio objects over <code>Sound</code>, <code>SoundGroup</code>, and <code>SoundEffect</code>. New work should use the graph; legacy code can keep using <code>Sound</code> where the graph offers no advantage.</p>\n<p>Cross-reference:</p>\n<ul>\n<li><a href=\"../roblox-core/SKILL.md\">roblox-core/SKILL.md</a> for services and script locations.</li>\n<li><a href=\"../roblox-animation/SKILL.md\">roblox-animation/SKILL.md</a> for driving audio from animation markers (footsteps, impact sounds).</li>\n<li><a href=\"../roblox-user-interfaces/SKILL.md\">roblox-user-interfaces/SKILL.md</a> for UI-triggered sound feedback.</li>\n<li><a href=\"../roblox-networking/SKILL.md\">roblox-networking/SKILL.md</a> for client-authoritative cosmetic audio vs server-authoritative gameplay audio.</li>\n</ul>\n<h2>The two systems</h2>\n<h3>Modern audio graph (recommended for new work)</h3>\n<p>Modular instances that mirror real-world audio devices. Each object <strong>produces</strong>, <strong>consumes</strong>, <strong>modifies</strong>, or <strong>carries</strong> an audio stream. You wire them together with <code>Wire</code> instances (<code>SourceInstance</code> → <code>TargetInstance</code>).</p>\n<table>\n<thead>\n<tr>\n<th>Object</th>\n<th>Role</th>\n<th>Real-world analog</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>AudioPlayer</code></td>\n<td>Produces a stream from an audio asset ID</td>\n<td>A audio file player</td>\n</tr>\n<tr>\n<td><code>AudioEmitter</code></td>\n<td>Emits a stream into the 3D environment (parent position = emission point)</td>\n<td>A speaker in the world</td>\n</tr>\n<tr>\n<td><code>AudioListener</code></td>\n<td>Picks up streams from the environment (parent = camera or character)</td>\n<td>A microphone in the world</td>\n</tr>\n<tr>\n<td><code>AudioDeviceOutput</code></td>\n<td>Plays a stream to the player's physical speaker/headphones</td>\n<td>The player's hardware output</td>\n</tr>\n<tr>\n<td><code>AudioDeviceInput</code></td>\n<td>Captures audio from the player's physical microphone</td>\n<td>The player's hardware mic</td>\n</tr>\n<tr>\n<td><code>AudioTextToSpeech</code></td>\n<td>Converts text to audio with an artificial voice</td>\n<td>A TTS engine</td>\n</tr>\n<tr>\n<td><code>AudioSpeechToText</code></td>\n<td>Converts spoken audio to text</td>\n<td>A transcription engine</td>\n</tr>\n<tr>\n<td><code>Wire</code></td>\n<td>Carries a stream from <code>SourceInstance</code> to <code>TargetInstance</code></td>\n<td>An audio cable</td>\n</tr>\n</tbody>\n</table>\n<p>Effects (all \"modify\" category): <code>AudioEqualizer</code>, <code>AudioCompressor</code>, <code>AudioReverb</code>, <code>AudioChorus</code>, <code>AudioDistortion</code>, <code>AudioEcho</code>, <code>AudioFlanger</code>, <code>AudioPitchShifter</code>, <code>AudioTremolo</code>, <code>AudioFader</code>, <code>AudioAnalyzer</code>. See <a href=\"references/audio-effects.md\">references/audio-effects.md</a>.</p>\n<h3>Legacy <code>Sound</code> system (still works, discouraged)</h3>\n<p><code>Sound</code> parented to a <code>BasePart</code> or <code>Attachment</code> emits from that position with built-in Doppler and distance rolloff (<code>RollOffMode</code>, <code>RollOffMaxDistance</code>, <code>RollOffMinDistance</code>, <code>EmitterSize</code>). A \"global\" <code>Sound</code> (not parented to a part/attachment) plays at constant volume everywhere. <code>SoundGroup</code> controls group volume and effects; <code>SoundEffect</code> subclasses (<code>EqualizerSoundEffect</code>, <code>ReverbSoundEffect</code>, etc.) apply per-group effects. <code>SoundService</code> exposes global properties (<code>AmbientReverb</code>, <code>DistanceFactor</code>, <code>DopplerScale</code>, <code>RespectFilteringEnabled</code>) that affect <code>Sound</code> playback.</p>\n<p><code>SoundService.AmbientReverb</code> and the Doppler/distance properties affect <strong>only legacy <code>Sound</code></strong>, not the audio graph. The graph has its own effect objects and per-emitter <code>DistanceAttenuation</code> curves.</p>\n<h2>Decision tree: which system?</h2>\n<ul>\n<li><strong>New experience, greenfield audio</strong> → audio graph. It supports TTS, STT, acoustic simulation, and routing.</li>\n<li><strong>Simple 2D SFX or music with no routing/effects</strong> → <code>Sound</code> is acceptable and simpler. Don't rewrite working legacy code just to migrate.</li>\n<li><strong>3D positional audio with custom attenuation curves</strong> → audio graph (<code>AudioEmitter.DistanceAttenuation</code>).</li>\n<li><strong>Multiple sources through one effect (e.g. all gunfire through one compressor)</strong> → audio graph (one effect, many players wired in).</li>\n<li><strong>Text-to-speech or speech-to-text</strong> → audio graph (only the graph has <code>AudioTextToSpeech</code> / <code>AudioSpeechToText</code>).</li>\n<li><strong>Voice chat / spatial voice</strong> → <code>VoiceChatService</code> (separate from in-experience audio; uses <code>AudioDeviceInput</code> under the hood when <code>UseAudioApi</code> is enabled).</li>\n<li><strong>Acoustic simulation (occlusion, diffraction, reverb)</strong> → audio graph with <code>SoundService.AcousticSimulationEnabled = true</code> and per-instance <code>AcousticSimulationEnabled</code> on emitters/listeners.</li>\n<li><strong>Quick prototype / one-shot UI click sound</strong> → <code>Sound</code> is fine.</li>\n</ul>\n<p>See <a href=\"references/audio-graph-vs-sound.md\">references/audio-graph-vs-sound.md</a> for a side-by-side property map and migration notes.</p>\n<h2>2D audio (non-directional)</h2>\n<p>Same volume everywhere. Requires: <code>AudioPlayer</code> → <code>Wire</code> → <code>AudioDeviceOutput</code>, all parented under <code>SoundService</code>.</p>\n<pre><code>--!strict\nlocal SoundService = game:GetService(\"SoundService\")\n\nlocal player = Instance.new(\"AudioPlayer\")\nplayer.AssetId = \"rbxassetid://YOUR_AUDIO_ID\"\nplayer.Looping = true\nplayer.Volume = 1\nplayer.Parent = SoundService\n\nlocal output = Instance.new(\"AudioDeviceOutput\")\noutput.Parent = SoundService\n\nlocal wire = Instance.new(\"Wire\")\nwire.SourceInstance = player\nwire.TargetInstance = output\nwire.Parent = SoundService\n\nplayer:Play()\n</code></pre>\n<h2>3D audio (positional)</h2>\n<p>Volume changes with the listener's distance to the emitter. Requires six objects: <code>AudioPlayer</code> → <code>Wire</code> → <code>AudioEmitter</code> (parented to the 3D part), and <code>AudioListener</code> → <code>Wire</code> → <code>AudioDeviceOutput</code> (under <code>SoundService</code>). Set <code>SoundService.ListenerLocation</code> to <code>Character</code> or <code>Camera</code> (the engine auto-creates the <code>AudioDeviceOutput</code> under <code>SoundService</code> at runtime when you do).</p>\n<pre><code>--!strict\nlocal SoundService = game:GetService(\"SoundService\")\nSoundService.ListenerLocation = Enum.ListenerLocation.Camera -- or Character\n\n-- On the 3D part that should emit audio:\nlocal part = workspace:WaitForChild(\"NoisyPart\")\nlocal player = Instance.new(\"AudioPlayer\")\nplayer.AssetId = \"rbxassetid://YOUR_AUDIO_ID\"\nplayer.Looping = true\nplayer.Parent = part\n\nlocal emitter = Instance.new(\"AudioEmitter\")\n-- Custom curve: DistanceAttenuation is a NumberSequence (x = distance studs, y = volume 0..1).\n-- This curve is only used when DistanceAttenuationMode == Custom (the default).\nemitter.DistanceAttenuation = NumberSequence.new({\n    NumberSequenceKeypoint.new(0, 1),    -- full volume at 0 studs\n    NumberSequenceKeypoint.new(50, 0.5), -- half volume at 50 studs\n    NumberSequenceKeypoint.new(70, 0),   -- silent at 70 studs\n})\n-- Preset alternative (no custom curve needed):\n-- emitter.DistanceAttenuationMode = Enum.DistanceAttenuationMode.Inverse\n-- emitter.DistanceAttenuationBounds = NumberRange.new(4, 10000) -- [min,max] for the preset rolloff\nemitter.Parent = part\n\nlocal wire = Instance.new(\"Wire\")\nwire.SourceInstance = player\nwire.TargetInstance = emitter\nwire.Parent = part\n\nplayer:Play()\n</code></pre>\n<p>The emitter's <strong>parent position</strong> determines where audio emits from. <code>AudioEmitter</code> ignores its own orientation; rotate the parent part/attachment to steer emission.</p>\n<p><strong>Distance model:</strong> <code>AudioEmitter.DistanceAttenuationMode</code> selects the rolloff formula (<code>Custom</code> by default; uses your <code>DistanceAttenuation</code> curve; other presets use <code>DistanceAttenuationBounds</code> which defaults to <code>[4, 10000]</code> and ignore the custom curve). <code>GetDistanceAttenuation()</code> always returns the custom curve even when a preset is active. Don't assume it reflects the audible rolloff unless <code>Mode == Custom</code>. <code>SetDistanceAttenuation(curve)</code> only affects playback when <code>Mode == Custom</code>. Angle attenuation is set via <code>SetAngleAttenuation({[angle]=volume})</code> (0–180° → 0–1); use for directional sources (e.g. avatar voice projects forward).</p>\n<p><strong>Acoustic simulation (occlusion/diffraction/reverb):</strong> Enable <code>SoundService.AcousticSimulationEnabled</code> and <code>AcousticSimulationEnabled</code> on both the emitter and listener. The current reference no longer exposes the separate per-instance <code>OcclusionEnabled</code>, <code>DiffractionEnabled</code>, and <code>ReverbEnabled</code> toggles; do not generate calls to them. Use <code>emitter:GetAudibilityFor(listener)</code> or <code>listener:GetAudibilityFor(emitter)</code> for combined distance and angle attenuation (0–1).</p>\n<h2>Listener location</h2>\n<p><code>SoundService.ListenerLocation</code> (a <code>ListenerLocation</code> enum) controls where the <code>AudioListener</code> is auto-created:</p>\n<ul>\n<li><strong>Default</strong>: camera in experiences with voice chat.</li>\n<li><strong>None</strong>: no auto-listener; create one via script.</li>\n<li><strong>Character</strong>: parented to the local player's character (<code>Humanoid.RootPart</code>).</li>\n<li><strong>Camera</strong>: parented to <code>workspace.CurrentCamera</code>.</li>\n</ul>\n<p>When set to <code>Character</code> or <code>Camera</code>, the engine auto-creates an <code>AudioDeviceOutput</code> under <code>SoundService</code> at runtime. The <code>AudioListener</code> picks up audio from <code>AudioEmitter</code>s based on distance and the emitter's <code>DistanceAttenuation</code> curve.</p>\n<h2>Triggering audio from scripts</h2>\n<pre><code>local audio = script.Parent :: AudioPlayer\nsomeEvent:Connect(function()\n    audio:Play()\nend)\n</code></pre>\n<p><code>AudioPlayer:Play(atTime?)</code>, <code>:Stop(atTime?)</code>. When <code>atTime</code> is supplied the action is scheduled against <code>SoundService:GetMixerTime()</code> for sample-accurate, framerate-independent timing (rhythm games / beat sync). <code>:Cancel(actionId)</code> cancels a future-scheduled Play/Stop (returns true if cancelled). <code>:Pause()</code>, <code>:SeekTime(...)</code>, <code>:GetWaveform(timeRange)</code> (samples volume without playing; useful for waveform visualization vs live <code>AudioAnalyzer</code>). <code>AudioPlayer.TimeVolume</code> is tweenable. See <a href=\"references/audio-effects.md\">references/audio-effects.md</a> for tweening volume and effect parameters.</p>\n<h2>Preloading audio</h2>\n<p>Preload prominent audio assets before they're needed (loading screen, round start) to avoid first-play hitches on lower-end devices:</p>\n<pre><code>--!strict\nlocal ContentProvider = game:GetService(\"ContentProvider\")\nlocal audioPlayer = workspace:WaitForChild(\"MusicPlayer\") :: AudioPlayer\nContentProvider:PreloadAsync({ audioPlayer })\n</code></pre>\n<p>For the legacy <code>Sound</code> system, preload the <code>Sound</code> instance the same way.</p>\n<h2>Performance limits</h2>\n<ul>\n<li><strong>Concurrent voices</strong> (simultaneously playing audio streams) are capped; the cap varies by device. Mobile is significantly lower than desktop.</li>\n<li><strong>Effects cost CPU</strong> per active stream routed through them. Reverb and acoustic simulation are the heaviest.</li>\n<li><strong>Acoustic simulation</strong> (<code>SoundService.AcousticSimulationEnabled</code>) adds per-emitter occlusion/diffraction/reverb cost; disable on low-end clients or when not needed.</li>\n<li><strong>Mobile throttling:</strong> 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.</li>\n<li><strong><code>AudioAnalyzer</code></strong> is for inspection only; don't chain it into audible paths unnecessarily.</li>\n</ul>\n<p>Profile audio with the MicroProfiler (audio appears under worker threads) and the Developer Console Memory tab.</p>\n<h2>Script context (client vs server)</h2>\n<ul>\n<li><strong>Playback</strong> of <code>AudioPlayer</code>, <code>Sound</code>, and effects is <strong>client-side</strong>. Each client plays its own audio. The server does not mix audio for clients.</li>\n<li><strong>Replication:</strong> <code>AudioPlayer</code> state (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 <strong>client-authoritative emission</strong>: 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).</li>\n<li><strong>Music/ambience</strong> that should be synchronized across all clients can be server-driven (the <code>AudioPlayer</code> lives in <code>ReplicatedStorage</code> or <code>SoundService</code> and the server calls <code>:Play()</code>), but be aware each client still renders locally and may drift.</li>\n<li><strong><code>AudioDeviceInput</code></strong> (microphone) is client-only. It captures the local player's mic. Pair with <code>VoiceChatService</code> for spatial voice. Access control: <code>SetUserIdAccessList(userIds)</code> + <code>AccessType</code> (<code>Allow</code> = only listed users hear the input, <code>Deny</code> = all except listed; default <code>Deny</code>), <code>GetUserIdAccessList()</code> returns the allow/deny list.</li>\n<li><strong>Never trust client audio state for gameplay.</strong> A client claiming \"I played the reload sound\" tells you nothing authoritative; validate gameplay effects on the server (see roblox-networking).</li>\n</ul>\n<h2>Audio asset permissions</h2>\n<ul>\n<li>Audio assets uploaded before the <strong>2022 audio privacy changes</strong> may be private or have restricted use. Assets you upload to your own experience are usable by that experience.</li>\n<li>The <strong>Creator Store</strong> has a library of free-to-use audio assets. These are safe to reference by asset ID in any experience.</li>\n<li>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.</li>\n<li>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).</li>\n</ul>\n<h2>Text-to-speech (TTS)</h2>\n<p><code>AudioTextToSpeech</code> converts text (≤300 chars per request) to audio with an artificial voice. The available <code>VoiceId</code> 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 <code>AudioPlayer</code>: for 2D, <code>AudioTextToSpeech</code> → <code>Wire</code> → <code>AudioDeviceOutput</code>; for 3D, <code>AudioTextToSpeech</code> → <code>Wire</code> → <code>AudioEmitter</code> (plus the listener→output wire). Set <code>Text</code>, <code>VoiceId</code>, <code>Volume</code> on the <code>AudioTextToSpeech</code>. <code>:WaitForSpeechReady()</code> yields until <code>AssetFetchStatus</code> is <code>Success</code> (or <code>Failure</code>). All text must comply with Roblox Community Standards and Terms of Use.</p>\n<p><strong>Audio analysis:</strong> <code>AudioAnalyzer</code> window is controlled by <code>AudioWindowSize</code>. <code>Small</code> (lowest latency, low frequency resolution), <code>Medium</code> (balanced), <code>Large</code> (highest resolution, more latency).</p>\n<p>Use cases: accessibility (reading UI text aloud), NPC voiceover without recorded audio, dynamic announcements.</p>\n<h2>Speech-to-text (STT)</h2>\n<p><code>AudioSpeechToText</code> converts speech captured by <code>AudioDeviceInput</code> into text. Requires <code>VoiceChatService.UseAudioApi = Enabled</code>. Wire: <code>AudioDeviceInput</code> → <code>Wire</code> → <code>AudioSpeechToText</code>. Set <code>audioDeviceInput.Player = Players.LocalPlayer</code> 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).</p>\n<p>To use STT without broadcasting voice to other players, disable <code>VoiceChatService.EnableDefaultVoice</code>. All audio for <code>AudioSpeechToText</code> must comply with Community Standards and Terms of Use.</p>\n<h2>Best practices</h2>\n<ul>\n<li><strong>Preload</strong> prominent audio (music, common SFX) during loading. One-shot UI sounds can lazy-load.</li>\n<li><strong>Loop</strong> ambient/music with <code>Looping = true</code> (graph) or <code>Looped = true</code> (legacy). For finite loops N times, use the <code>DidLoop</code> event (legacy <code>Sound</code>) or count plays on the graph.</li>\n<li><strong>Fade in/out</strong> by tweening <code>AudioPlayer.Volume</code> (graph) or <code>Sound.Volume</code> (legacy). <code>AudioFader</code> is the graph-native way to control multiple streams' volume at once.</li>\n<li><strong>Music vs SFX:</strong> route music and SFX through separate <code>AudioFader</code> or <code>SoundGroup</code> so you can mute music independently and apply ducking (SFX ducks music via <code>AudioCompressor</code> sidechain).</li>\n<li><strong>3D vs 2D:</strong> if the sound has a world position, use 3D (<code>AudioEmitter</code>); if it's UI/global, use 2D (<code>AudioDeviceOutput</code> direct).</li>\n<li><strong>Accessibility:</strong> offer TTS for important text, provide subtitle/caption options for VO, and never make audio the only cue for gameplay-critical info.</li>\n<li><strong>Mobile:</strong> test at low quality. The engine may drop effects; design so the experience still works without them.</li>\n<li><strong>Concurrency:</strong> pool <code>AudioPlayer</code>/<code>Sound</code> instances for frequent one-shots rather than creating/destroying per shot.</li>\n</ul>\n<h2>Common mistakes</h2>\n<ul>\n<li>Using <code>Sound</code>/<code>SoundGroup</code>/<code>SoundEffect</code> for new work when the graph is the recommended path.</li>\n<li>Parenting an <code>AudioEmitter</code> to <code>SoundService</code> (it must be parented to a 3D part/attachment for 3D audio).</li>\n<li>Forgetting the <code>Wire</code> (audio won't flow from player to output/emitter).</li>\n<li>Expecting <code>SoundService.AmbientReverb</code> to affect the audio graph (it only affects legacy <code>Sound</code>).</li>\n<li>Setting <code>DistanceAttenuation</code> as a single number instead of a <code>NumberSequence</code> (it's a curve, not a scalar).</li>\n<li>Trusting client audio state for gameplay (reload sounds, hit sounds) instead of server validation.</li>\n<li>Not preloading, causing first-play hitches on mobile.</li>\n<li>Hardcoding asset IDs for third-party audio that may be permission-restricted.</li>\n</ul>\n<h2>Scripts</h2>\n<ul>\n<li><code>scripts/AudioBus.lua</code>: a small music/SFX bus helper using <code>AudioFader</code> to control group volume and duck music when SFX play. Adapt for your mix.</li>\n</ul>\n<h2>How to proceed</h2>\n<ol>\n<li>Pick the system: graph for new/complex work, <code>Sound</code> for simple/legacy.</li>\n<li>Lay out your buses (music, SFX, VO) and route through <code>AudioFader</code> or <code>SoundGroup</code>.</li>\n<li>Place 3D emitters on the parts that should make sound; set <code>DistanceAttenuation</code> per emitter.</li>\n<li>Add effects where they add value (reverb in caves, muffling underwater, ducking).</li>\n<li>Preload, then trigger from events (animation markers, UI, gameplay).</li>\n<li>Profile concurrent voices and effect cost on the lowest target device.</li>\n<li>Verify asset permissions for any third-party audio.</li>\n</ol>\n\n<h2>Reference index</h2>\n<ul>\n<li><a href=\"references/audio-effects.md\">audio-effects.md</a>: Route effects, mix audio buses, duck music, or tune attenuation.</li>\n<li><a href=\"references/audio-graph-vs-sound.md\">audio-graph-vs-sound.md</a>: Choose an audio system or migrate legacy Sound code.</li>\n</ul>\n\n<p>Acoustic API references: <a href=\"https://create.roblox.com/docs/reference/engine/classes/AudioEmitter\">https://create.roblox.com/docs/reference/engine/classes/AudioEmitter</a> and <a href=\"https://create.roblox.com/docs/reference/engine/classes/AudioListener\">https://create.roblox.com/docs/reference/engine/classes/AudioListener</a>.</p>\n","files":[{"path":"references/audio-effects.md","sizeBytes":7098,"isText":true},{"path":"references/audio-graph-vs-sound.md","sizeBytes":5294,"isText":true},{"path":"scripts/AudioBus.lua","sizeBytes":3642,"isText":false},{"path":"SKILL.md","sizeBytes":18554,"isText":true}],"reviewScore":null,"reviewSummary":null,"trust":{"provenance":"trusted-source-unreviewed","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow.","bodySource":null},"bodyLocked":false,"purchaseUrl":null,"sourceUrl":null,"report":{"provenance":"trusted-source-unreviewed","screen":{"ran":true,"outcome":"clean","suspicious":0,"notes":0,"hiddenCharacters":false},"virusScan":{"engine":"clamav","status":"clean","scannedAt":"2026-10-18T17:24:14.461462Z","sha256":"9C240660512DB4FBCBC0D4EAEBE1D75B7153234ECC043438A4E0350EEDA0A1CC","sizeBytes":13932},"review":null,"source":{"repositoryUrl":"https://github.com/nonlooped/roblox-suite","path":"roblox-audio","license":"MIT","commit":"2904c1660c702d82f1ab67f46ddf619d6abc9a2d","subtreeSha":"876596C9DE1A0835152E25A1B6D25E0BA1645249004C85720A54AC5416590BAC","lastSyncedAt":"2026-10-18T17:23:55.435396Z"},"reviewedAt":"2026-10-18T17:24:23.663814Z","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow."},"install":[{"target":"skills-cli","command":"npx skills add https://github.com/nonlooped/roblox-suite/tree/main/roblox-audio"},{"target":"claude-code","command":"claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install nonlooped-roblox-suite@llmmart"},{"target":"git","command":"git clone https://github.com/nonlooped/roblox-suite.git"}]}