# Configuration

`Sounds System` uses a configuration file located in:

* `data/config.lua`

This file controls spatial audio behavior, update intervals, occlusion settings, validation limits, and server protection values.

### Main Configuration

Example:

```lua
RefreshTime = 200
DistanceBeforeUpdating = 20
DefaultDistance = 10
PositionChangeThreshold = 0.5
DoorOpenThreshold = 0.1
SourceVehicleSearchRadius = 5.0
FarSoundCheckInterval = 5
PanDivisor = 5.0

OcclusionClose = 0.65
OcclusionMedium = 0.8
OcclusionFar = 1.0
OcclusionMediumDist = 4.0
OcclusionFarDist = 8.0
OcclusionPlayerVehicleBonus = 0.3

FadeStepMultiplier = 100

MaxDistance = 100.0
MaxVolume = 1.0
MaxPlayerListSize = 30
PlayWithinDistanceCooldown = 150
MaxSoundNameLength = 64
```

### Spatial Update Settings

#### `RefreshTime`

```lua
RefreshTime = 200
```

Defines how often positional audio is updated.

This value is measured in milliseconds.

Lower values provide smoother audio updates but use more CPU.

#### `DistanceBeforeUpdating`

```lua
DistanceBeforeUpdating = 20
```

Defines the extra distance beyond the sound range before spatial updates start or stop.

#### `DefaultDistance`

```lua
DefaultDistance = 10
```

Defines the default maximum audible distance for new sounds.

#### `PositionChangeThreshold`

```lua
PositionChangeThreshold = 0.5
```

Defines the minimum player movement required before sending a new position update to the DUI.

This helps reduce unnecessary updates.

***

### Vehicle and Occlusion Settings

#### `DoorOpenThreshold`

```lua
DoorOpenThreshold = 0.1
```

Defines the vehicle door angle ratio above which a door is considered open.

#### `SourceVehicleSearchRadius`

```lua
SourceVehicleSearchRadius = 5.0
```

Defines how far the resource searches for a nearby source vehicle when trying to determine occlusion.

#### `PanDivisor`

```lua
PanDivisor = 5.0
```

Controls stereo panning strength.

Higher values reduce stereo separation.

***

### Occlusion Strength

#### `OcclusionClose`

```lua
OcclusionClose = 0.65
```

Occlusion strength used when the sound source is close and blocked.

#### `OcclusionMedium`

```lua
OcclusionMedium = 0.8
```

Occlusion strength used at medium distance.

#### `OcclusionFar`

```lua
OcclusionFar = 1.0
```

Occlusion strength used at far distance.

#### `OcclusionMediumDist`

```lua
OcclusionMediumDist = 4.0
```

Distance threshold for medium occlusion.

#### `OcclusionFarDist`

```lua
OcclusionFarDist = 8.0
```

Distance threshold for far occlusion.

#### `OcclusionPlayerVehicleBonus`

```lua
OcclusionPlayerVehicleBonus = 0.3
```

Additional occlusion applied when the player is inside a closed vehicle.

***

### Fade and Cleanup Settings

#### `FadeStepMultiplier`

```lua
FadeStepMultiplier = 100
```

Controls fade smoothness for fade in and fade out operations.

Higher values produce smoother fading.

#### `FarSoundCheckInterval`

```lua
FarSoundCheckInterval = 5
```

Defines how often far-away sounds are checked for cleanup or respawn.

This value is measured in one-second ticks.

***

### Server Validation Limits

#### `MaxDistance`

```lua
MaxDistance = 100.0
```

Maximum allowed sound distance from client requests.

#### `MaxVolume`

```lua
MaxVolume = 1.0
```

Maximum allowed client-requested volume.

#### `MaxPlayerListSize`

```lua
MaxPlayerListSize = 30
```

Maximum number of players allowed in a `PlayWithinDistance` request.

#### `PlayWithinDistanceCooldown`

```lua
PlayWithinDistanceCooldown = 150
```

Cooldown between `PlayWithinDistance` calls per player.

This value is measured in milliseconds.

#### `MaxSoundNameLength`

```lua
MaxSoundNameLength = 64
```

Maximum allowed sound name length for validated requests.

***

### Audio Source Types

The resource supports three audio source types.

#### Local Files

Supported formats include:

* `.ogg`
* `.mp3`
* `.wav`

These use Howler and a shared DUI instance.

#### YouTube

Any supported YouTube URL is handled through the YouTube IFrame API.

These sounds use dedicated DUI instances.

#### SoundCloud

Supported SoundCloud links use the SoundCloud widget player.

These sounds also use dedicated DUI instances.

***

### Client Exports

### Playback Exports

#### `PlayUrl`

```lua
exports['msk_sounds']:PlayUrl(name, url, volume, loop, options)
```

Plays a non-positional 2D sound.

#### `PlayUrlPos`

```lua
exports['msk_sounds']:PlayUrlPos(name, url, volume, pos, loop, options)
```

Plays a positional 3D sound.

#### `Destroy`

```lua
exports['msk_sounds']:Destroy(name)
```

Stops and destroys a sound.

#### `Pause`

```lua
exports['msk_sounds']:Pause(name)
```

Pauses a sound.

#### `Resume`

```lua
exports['msk_sounds']:Resume(name)
```

Resumes a paused sound.

#### `repeatSound`

```lua
exports['msk_sounds']:repeatSound(name)
```

Restarts a sound from the beginning.

#### `fadeIn`

```lua
exports['msk_sounds']:fadeIn(name, time, targetVol)
```

Fades the sound in over time.

#### `fadeOut`

```lua
exports['msk_sounds']:fadeOut(name, time)
```

Fades the sound out to zero.

#### `PlayWithinDistance`

```lua
exports['msk_sounds']:PlayWithinDistance(distance, soundFile, soundVolume)
```

Plays a local sound for nearby players with server validation.

***

### Property Exports

#### `setVolume`

```lua
exports['msk_sounds']:setVolume(name, vol)
```

Sets the current sound volume.

#### `setVolumeMax`

```lua
exports['msk_sounds']:setVolumeMax(name, vol)
```

Sets the maximum allowed volume.

#### `Distance`

```lua
exports['msk_sounds']:Distance(name, dist)
```

Sets the audible distance.

#### `Position`

```lua
exports['msk_sounds']:Position(name, pos)
```

Moves the sound to new world coordinates.

#### `setTimeStamp`

```lua
exports['msk_sounds']:setTimeStamp(name, ts)
```

Seeks to a specific timestamp.

#### `destroyOnFinish`

```lua
exports['msk_sounds']:destroyOnFinish(name, bool)
```

Enables or disables auto-destroy when playback ends.

#### `setSoundLoop`

```lua
exports['msk_sounds']:setSoundLoop(name, val)
```

Enables or disables looping.

#### `setSoundDynamic`

```lua
exports['msk_sounds']:setSoundDynamic(name, bool)
```

Enables or disables positional mode.

#### `setSoundURL`

```lua
exports['msk_sounds']:setSoundURL(name, url)
```

Changes the sound source URL.

#### `setStereo`

```lua
exports['msk_sounds']:setStereo(name, enabled)
```

Enables or disables stereo panning.

#### `setOcclusion`

```lua
exports['msk_sounds']:setOcclusion(name, enabled)
```

Enables or disables occlusion filtering.

***

### Query Exports

#### `soundExists`

```lua
local exists = exports['msk_sounds']:soundExists(name)
```

Returns whether a sound exists.

#### `isPlaying`

```lua
local playing = exports['msk_sounds']:isPlaying(name)
```

Returns whether a sound is playing.

#### `isPaused`

```lua
local paused = exports['msk_sounds']:isPaused(name)
```

Returns whether a sound is paused.

#### `getLink`

```lua
local url = exports['msk_sounds']:getLink(name)
```

Returns the current sound URL.

#### `getPosition`

```lua
local pos = exports['msk_sounds']:getPosition(name)
```

Returns the sound world position.

#### `isLooped`

```lua
local looped = exports['msk_sounds']:isLooped(name)
```

Returns whether looping is enabled.

#### `getInfo`

```lua
local info = exports['msk_sounds']:getInfo(name)
```

Returns the full sound object.

#### `getDistance`

```lua
local dist = exports['msk_sounds']:getDistance(name)
```

Returns the maximum audible distance.

#### `getVolume`

```lua
local vol = exports['msk_sounds']:getVolume(name)
```

Returns the current volume.

#### `isDynamic`

```lua
local dynamic = exports['msk_sounds']:isDynamic(name)
```

Returns whether the sound is positional.

#### `getTimeStamp`

```lua
local ts = exports['msk_sounds']:getTimeStamp(name)
```

Returns the current playback timestamp.

#### `getMaxDuration`

```lua
local duration = exports['msk_sounds']:getMaxDuration(name)
```

Returns the maximum playback duration.

#### `isPlayerInStreamerMode`

```lua
local streamer = exports['msk_sounds']:isPlayerInStreamerMode()
```

Returns whether streamer mode is enabled.

#### `getAllAudioInfo`

```lua
local sounds = exports['msk_sounds']:getAllAudioInfo()
```

Returns the full client sound registry.

#### `isPlayerCloseToAnySound`

```lua
local nearby = exports['msk_sounds']:isPlayerCloseToAnySound()
```

Returns whether the player is within range of any dynamic sound.

#### `isStereoEnabled`

```lua
local stereo = exports['msk_sounds']:isStereoEnabled(name)
```

Returns whether stereo is enabled.

#### `isOcclusionEnabled`

```lua
local occ = exports['msk_sounds']:isOcclusionEnabled(name)
```

Returns whether occlusion is enabled.

***

### Callback Exports

#### `onPlayStart`

```lua
exports['msk_sounds']:onPlayStart(name, function(sound)
end)
```

Runs when playback starts.

#### `onPlayEnd`

```lua
exports['msk_sounds']:onPlayEnd(name, function(sound)
end)
```

Runs when playback ends or the sound is destroyed.

#### `onLoading`

```lua
exports['msk_sounds']:onLoading(name, function(sound)
end)
```

Runs when the audio has loaded.

#### `onPlayPause`

```lua
exports['msk_sounds']:onPlayPause(name, function(sound)
end)
```

Runs when the sound is paused.

#### `onPlayResume`

```lua
exports['msk_sounds']:onPlayResume(name, function(sound)
end)
```

Runs when the sound is resumed.

#### `onPlayStartSilent`

```lua
exports['msk_sounds']:onPlayStartSilent(name, function(sound)
end)
```

Runs on every playback start, including silent respawns.

***

### Server Exports

#### `PlayUrl`

```lua
exports['msk_sounds']:PlayUrl(src, name, url, vol, loop)
```

Plays a 2D sound for a specific player.

#### `PlayUrlPos`

```lua
exports['msk_sounds']:PlayUrlPos(src, name, url, vol, pos, loop)
```

Plays a positional sound for a specific player.

#### `Destroy`

```lua
exports['msk_sounds']:Destroy(src, name)
```

Destroys a sound for a specific player.

#### `Pause`

```lua
exports['msk_sounds']:Pause(src, name)
```

Pauses a sound for a specific player.

#### `Resume`

```lua
exports['msk_sounds']:Resume(src, name)
```

Resumes a sound for a specific player.

#### `Position`

```lua
exports['msk_sounds']:Position(src, name, pos)
```

Updates a sound position for a specific player.

#### `Distance`

```lua
exports['msk_sounds']:Distance(src, name, dist)
```

Updates sound distance for a specific player.

#### `setVolume`

```lua
exports['msk_sounds']:setVolume(src, name, vol)
```

Sets sound volume for a specific player.

#### `setTimeStamp`

```lua
exports['msk_sounds']:setTimeStamp(src, name, time)
```

Seeks a sound for a specific player.

#### `destroyOnFinish`

```lua
exports['msk_sounds']:destroyOnFinish(src, name, bool)
```

Sets destroy-on-finish for a specific player.

***

### Events

#### `msk_sounds:state`

Server to client event used internally to dispatch sound actions.

#### `msk_sounds:finished`

Local client event fired when playback finishes.

#### `hud_streammode`

Client event used to toggle streamer mode.

When streamer mode is enabled, YouTube and SoundCloud sounds are destroyed and blocked.

#### `msk_sounds:playWithinDistance`

Client to server event used for validated nearby local sound playback.

***

### Audio Behavior

#### Distance Falloff

Positional sounds use distance-based volume falloff.

The closer the player is, the louder the sound becomes.

#### Stereo Panning

Stereo panning is calculated from the player heading and the sound direction.

This creates left and right spatial separation.

#### Occlusion

Occlusion uses vehicle state information such as:

* door state
* window state
* roof state
* whether the player is in a vehicle

This is applied through a lowpass audio filter.

#### Far-Away Cleanup

Far dynamic sounds can have their DUI destroyed automatically to save resources.

When the player comes back into range, the sound can respawn automatically.

***

### Notes

* Local file sounds use a shared DUI player
* YouTube and SoundCloud sounds use dedicated DUI players
* Streamer mode blocks embedded streaming sources
* Positional sounds support distance, stereo, and occlusion
* `PlayWithinDistance` is server validated and rate limited
* Sound names are validated on the server
* Non-looping sounds can destroy themselves automatically when they finish


---

# 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://mskscripts.gitbook.io/mskscripts/scripts/sounds-system/configuration.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.
