# Sound

Sound : `Instance`

## Overview

Sound is an object that plays audio.

When a Sound is parented to a BasePart (including MeshPart) or Attachment, it plays at that location and its volume changes with distance from the listener. Otherwise, it plays at the same volume throughout the place.

Sound is not actually heard on the server; sounds are simulated and played separately on the server and client. Therefore, depending on execution order or values changed locally, the server and client may have different playback positions and different start/end times.

For sounds playing on the server, the current state and properties of the Sound instance set on the server are replicated to users who join later, so they can hear the sound as well.

The playback range of a Sound is determined by the combination of PlaybackRegionsEnabled, StartTimePosition, PlaybackRegion, LoopRegion, and Looped. For detailed playback range control, see the [Sound manual](/manual/studio-manual/object/sound.md#playback-range-control).

## Properties

### IsLoaded

`boolean`

Indicates whether a valid SoundId has been entered and the sound is loaded. Use it together with the Loaded event to check if the sound is loaded before playing.

When the sound is loaded, TimePosition is reset to 0. If you connect the Loaded event after the sound has already loaded, the event will not be called, so it is best to check IsLoaded first.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

if Sound.IsLoaded then
    Sound:Play()
else
    Sound.Loaded:Wait()
    Sound:Play()
end
```

### IsPaused

`boolean`

Returns true when the sound is not playing. It is true when the sound has been paused or stopped via Pause() or Stop(), has never been played, or an invalid SoundId has been entered.

This is a read-only property; use the Pause() or Stop() method to control playback.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

if Sound.IsPaused then
    Sound:Resume()
end
```

### IsPlaying

`boolean`

Returns true when the sound is currently playing. Unlike the Playing property, this is read-only; use the Play() method to control playback.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

if not Sound.IsPlaying then
    Sound:Play()
end
```

### Looped

`boolean`

Sets whether the sound plays in a loop. When set to true, the sound restarts from the beginning (or loop start) after it finishes.

Changing the value during playback applies immediately. While Looped is true, the Ended event does not fire even if the sound reaches the end, and Looped does not apply to sounds played through PlayOnRemove.

You can track the number of loops with the DidLoop event.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.Looped = true
```

### LoopRegion

`NumberRange`

A range in seconds that defines the desired loop start and end time within the PlaybackRegion.

PlaybackRegion determines the range used when starting or restarting a sound with Play(), while LoopRegion determines the range used when loops repeat. Therefore, if you call Play() again during looped playback, playback restarts based on PlaybackRegion.Min, not LoopRegion.Min.

To use this property, PlaybackRegionsEnabled must be true and Looped must be true. This property applies only during looped playback; on the first play, PlaybackRegion is used.

Changing the value while the sound is playing applies immediately. If PlaybackRegionsEnabled = false, you can set the value, but it does not apply to the actual playback range.

LoopRegion is applied as follows:

* First play (DidLoop = 0): PlaybackRegion is used; LoopRegion is ignored.
* Loop play (DidLoop ≥ 1): The narrower of LoopRegion and PlaybackRegion is used.
  * `LoopRegion.Min > PlaybackRegion.Min`: Start at LoopRegion.Min
  * `LoopRegion.Min ≤ PlaybackRegion.Min`: Start at PlaybackRegion.Min
  * `LoopRegion.Max < PlaybackRegion.Max`: End at LoopRegion.Max
  * `LoopRegion.Max ≥ PlaybackRegion.Max`: End at PlaybackRegion.Max
* `LoopRegion.Min = LoopRegion.Max`: This property is disabled and PlaybackRegion is used for the loop as well.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.PlaybackRegionsEnabled = true
Sound.PlaybackRegion = NumberRange.new(0, 30)

Sound.LoopRegion = NumberRange.new(10, 25)
Sound.Looped = true

Sound:Play()
```

### PlaybackLoudness

`number`

Represents the amplitude value of the currently playing sound in the range 0–1000. Useful for audio visualization or sound-reactive effects.

This value is calculated automatically based on the playing audio signal and is not affected by Volume, SoundGroup.Volume, distance attenuation, PlaybackSpeed, or system volume. However, it may become 0 if a 3D sound is outside RollOffMaxDistance. Because the server does not play audio, reading this value on the server always returns 0.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound
local Part = Workspace.Part

game:GetService("RunService").Heartbeat:Connect(function()
    local loudness = Sound.PlaybackLoudness
    Part.Size = Vector3.new(1, 1 + loudness / 100, 1)
end)
```

### PlaybackRegion

`NumberRange`

A range in seconds that defines the desired start and end time within TimeLength.

PlaybackRegionsEnabled must be set to true to use this property.

Changing the value while the sound is playing applies immediately. If PlaybackRegionsEnabled = false, you can set the value, but it does not apply to the actual playback range.

Behavior:

* `PlaybackRegion.Min > 0`: Playback starts at PlaybackRegion.Min.
* `PlaybackRegion.Min ≤ 0`: Playback starts at 0 (negative values are clamped to 0).
* `PlaybackRegion.Max < TimeLength`: Playback ends exactly at that time.
* `PlaybackRegion.Max ≥ TimeLength`: Playback ends at TimeLength.
* `PlaybackRegion.Min = PlaybackRegion.Max`: This property is disabled (playback from 0 to TimeLength).

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.PlaybackRegionsEnabled = true
Sound.PlaybackRegion = NumberRange.new(5, 20)

Sound:Play()
```

### PlaybackRegionsEnabled

`boolean`

Enables PlaybackRegion and LoopRegion so you can play only a specific part of the sound or define a loop segment. When PlaybackRegionsEnabled is on, StartTimePosition is ignored.

Changing the value while the sound is playing is reflected immediately.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.PlaybackRegionsEnabled = true
Sound.PlaybackRegion = NumberRange.new(5, 20)

Sound.LoopRegion = NumberRange.new(10, 15)
Sound.Looped = true

Sound:Play()
```

### PlaybackSpeed

`number`

Sets the playback speed of the sound. 1.0 is normal speed; higher values play faster and lower values play slower. Changing playback speed also changes the pitch.

Changing the value while the sound is playing applies immediately. The currently supported recommended range is 0.5–2.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.PlaybackSpeed = 2.0
Sound:Play()
```

### Playing

`boolean`

Indicates the playback state of the sound and can be set directly.

Behavior:

* Playing = false: Pauses the sound. TimePosition is preserved, and the Paused or Stopped event does not fire.
* Playing = true: Resumes playback from the current TimePosition. The Played or Resumed event does not fire.
* Difference from Play(): Play() starts from StartTimePosition (or PlaybackRegion.Min).

If it is already set to the same value, the operation is ignored.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound:Play()
wait(2)
Sound.Playing = false
wait(1)
Sound.Playing = true
```

### PlayOnRemove

`boolean`

When set to true, the sound plays when the Sound instance is removed. If the sound is not playing when removed, it starts from the beginning; if it is playing when removed, it continues from the current position.

Useful for playing sounds when objects disappear, such as explosion or destruction effects.

Looped does not apply to sounds played through PlayOnRemove. If PlaybackRegionsEnabled = true, PlaybackRegion applies, and the Played, Resumed, Ended, Paused, and Stopped events do not fire.

For sounds played through PlayOnRemove, whether playback is 2D or 3D is determined based on the position where the sound was removed. For 3D sounds, attenuation based on RollOffMinDistance and RollOffMaxDistance still applies.

The sound plays in these cases:

* `sound:Destroy()`
* `sound.Parent = nil`
* `sound.Parent.Parent = nil`

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.PlayOnRemove = true
Sound:Destroy()
```

### PreviewPlaying

`boolean`

Indicates the preview playback state of the sound.

#### Code Samples

### PreviewTimePosition

`number`

Indicates the current playback position of the sound preview in seconds.

#### Code Samples

### RollOffMaxDistance

`number`

Sets the maximum distance in studs at which a 3D sound (parented to a BasePart or Attachment) can be heard. Beyond this distance, the sound is inaudible. Attenuation does not apply to 2D sounds.

How the sound attenuates depends on RollOffMode.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local Sound = part.Sound

Sound.RollOffMaxDistance = 100
```

### RollOffMinDistance

`number`

Sets the minimum distance in studs at which a 3D sound (parented to a BasePart or Attachment) is heard at full volume. Beyond this distance, the sound attenuates according to RollOffMode. Attenuation does not apply to 2D sounds.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local Sound = part.Sound

Sound.RollOffMinDistance = 10
Sound.RollOffMaxDistance = 100
```

### RollOffMode

`Enum.RollOffMode`

Sets how the volume of a 3D sound (parented to a BasePart or Attachment) attenuates with distance. It determines how the sound fades between RollOffMinDistance and RollOffMaxDistance.

The default value is Enum.RollOffMode.Inverse. The Listener is based on the Camera by default, and attenuation does not apply to 2D sounds.

Attenuation is applied under the following conditions:

| Listener distance                                  | Sound volume state                           |
| -------------------------------------------------- | -------------------------------------------- |
| distance ≤ RollOffMinDistance                      | Attenuation is not applied.                  |
| RollOffMinDistance < distance < RollOffMaxDistance | Attenuation is applied based on RollOffMode. |
| distance ≥ RollOffMaxDistance                      | The sound is inaudible.                      |
| RollOffMaxDistance = RollOffMinDistance            | Attenuation is not applied.                  |

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local Sound = part.Sound

Sound.RollOffMode = Enum.RollOffMode.Linear
```

### SoundGroup

`SoundGroup`

Sets the SoundGroup this sound belongs to. All sounds in a SoundGroup are affected by the group’s Volume setting, so you can control their volume together.

Changing SoundGroup while the sound is playing applies immediately. If the SoundGroup's Volume is 0, sounds belonging to that group are not output.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")

local musicGroup = Instance.new("SoundGroup")
musicGroup.Volume = 0.5
musicGroup.Parent = Workspace

local Sound = Workspace.Sound

Sound.SoundGroup = musicGroup
```

### SoundId

`string`

The asset ID of the sound file to play. Specify the sound asset using the `ovdrassetid://` format.

SoundId is an empty string by default. Changing SoundId during playback stops the sound and resets TimePosition to 0, but values such as StartTimePosition, PlaybackRegion, and LoopRegion are preserved. The Stopped or Ended event does not fire in this case.

If SoundId is invalid or empty, TimePosition does not change, and a warning may be output when changing TimePosition. StartTimePosition can be set normally even if SoundId is invalid.

Loading may fail if you enter a nonexistent asset, an asset of a type other than sound, a private asset you do not have permission to access, or a value with an invalid URL format.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.SoundId = "ovdrassetid://1234567890"
Sound:Play()
```

### StartTimePosition

`number`

Sets the position in seconds from which to start when playing with the Play() method. This property only works when PlaybackRegionsEnabled = false.

Notable behavior:

* Negative values are clamped to 0.
* When Looped = true: Applied only on the first play; loops start from 0.
* Resume() or Playing = true resumes from the current TimePosition, not StartTimePosition.
* Values greater than TimeLength are preserved.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.StartTimePosition = 50
Sound:Play()

wait(5)
Sound:Play()
```

### TimeLength

`number`

The total length of the sound in seconds. Returns 0 if the sound is not loaded.

Use with PlaybackSpeed to adjust speed so the sound plays for a desired duration.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.PlaybackSpeed = Sound.TimeLength / 5
Sound:Play()
```

### TimePosition

`number`

The current playback position of the sound in seconds. Changing this value immediately seeks the playback position while the sound is playing.

While the sound is playing, TimePosition increases at a rate of PlaybackSpeed per second and stops when it reaches TimeLength unless Looped is true.

If you set TimePosition below the playable range, playback starts at the start of the playable range. If you set it beyond the playable range, the next loop proceeds when Looped = true; when Looped = false, the Ended event fires and playback ends.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound:Play()
wait(2)
Sound.TimePosition = 10

local progress = Sound.TimePosition / Sound.TimeLength * 100
print("Playback progress:", progress, "%")
```

### Volume

`number`

Sets the volume of the sound. Value between 0 (mute) and 10 (max); default is 0.5.

If the sound is in a SoundGroup, it is also affected by the group’s Volume setting.

The final output volume is affected by Sound.Volume, SoundGroup.Volume, distance attenuation, audio effects, and other factors together.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.Volume = 2.0
Sound:Play()
```

## Methods

### Pause

Pauses the sound. TimePosition is preserved, so you can resume from the same position with Resume().

Only works when a valid sound asset is set. If called on a sound that is already stopped or not playing, the Paused event does not fire.

#### Parameters

#### Return

| `void` |   |
| ------ | - |

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound:Play()
wait(2)
Sound:Pause()
```

### Play

Starts playing the sound. The start position depends on the PlaybackRegionsEnabled setting.

Only works when a valid sound asset is set.

Start position:

* PlaybackRegionsEnabled = false: Starts from StartTimePosition
* PlaybackRegionsEnabled = true: Starts from PlaybackRegion.Min

Calling Play() again while playing seeks back to the start position. In this case, the sound is already playing, so the Played event does not fire.

#### Parameters

#### Return

| `void` |   |
| ------ | - |

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.StartTimePosition = 10
Sound:Play()
```

### Resume

Resumes a stopped sound from the current TimePosition. Used together with Pause().

Only works when a valid sound asset is set. If called on a sound that is already playing, the Resumed event does not fire.

#### Parameters

#### Return

| `void` |   |
| ------ | - |

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound:Play()
wait(2)
Sound:Pause()
wait(1)
Sound:Resume()
```

### Stop

Stops the sound and resets TimePosition to 0 while keeping other properties unchanged.

So after Stop(), calling Play() will start from StartTimePosition.

Only works when a valid sound asset is set. If called on a sound that is already in the Ended or Stopped state, the Stopped event does not fire.

#### Parameters

#### Return

| `void` |   |
| ------ | - |

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.StartTimePosition = 10
Sound:Play()
wait(2)
Sound:Stop()

Sound:Play()
```

## Events

### DidLoop

Fires each time the sound loops. Calling Stop() resets the loop counter to 0.

#### Parameters

| `string` SoundId          | SoundId of the sound that looped     |
| ------------------------- | ------------------------------------ |
| `number` numOfTimesLooped | Number of times the sound has looped |

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.DidLoop:Connect(function(soundId, numOfTimesLooped)
    print("Loop count:", numOfTimesLooped)
    if numOfTimesLooped >= 3 then
        Sound:Stop()
    end
end)

Sound.Looped = true
Sound:Play()
```

### Ended

Fires when the sound has played to the end and stopped.

It does not fire in these cases:

* When Looped = true
* When stopped with Stop() before the end (use the Stopped event instead)

#### Parameters

| `string` SoundId | SoundId of the sound that finished playing |
| ---------------- | ------------------------------------------ |

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.Ended:Connect(function(soundId)
    print("Playback finished:", soundId)
    Sound:Destroy()
end)

Sound:Play()
```

### Loaded

Fires when the sound is loaded. It does not fire if the sound is already loaded, so it is best to check IsLoaded first.

#### Parameters

| `string` SoundId | SoundId of the loaded sound |
| ---------------- | --------------------------- |

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

local function OnLoaded()
    print("Sound has been loaded.")
end
Sound.Loaded:Connect(OnLoaded)
```

### Paused

Fires when the sound is paused via the Pause() method.

#### Parameters

| `string` SoundId | SoundId of the paused sound |
| ---------------- | --------------------------- |

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.Paused:Connect(function(soundId)
    print("Paused:", soundId)
end)

Sound:Play()
wait(1)
Sound:Pause()
```

### Played

Fires when the sound starts playing via the Play() method.

Does not fire when playback starts due to PlayOnRemove = true.

If Play() is called on a sound that is already playing and only seeks back to the start position, this event does not fire.

#### Parameters

| `string` SoundId | SoundId of the sound that played |
| ---------------- | -------------------------------- |

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

local function OnPlayed(soundId)
    print("Sound has started playing:", soundId)
end
Sound.Played:Connect(OnPlayed)
```

### Resumed

Fires when the sound is resumed via the Resume() method.

#### Parameters

| `string` SoundId | SoundId of the resumed sound |
| ---------------- | ---------------------------- |

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.Resumed:Connect(function(soundId)
    print("Resumed:", soundId)
end)

Sound:Play()
wait(1)
Sound:Pause()
wait(1)
Sound:Resume()
```

### Stopped

Fires when a playing sound is stopped with the Stop() method.

It does not fire when the sound is destroyed with Destroy() or when SoundId is changed during playback.

#### Parameters

| `string` SoundId | SoundId of the stopped sound |
| ---------------- | ---------------------------- |

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.Stopped:Connect(function(soundId)
    print("Sound stopped:", soundId)
end)

Sound:Play()
wait(2)
Sound:Stop()
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.overdare.com/development/api-reference/classes/sound.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
