Exports and events
Call these with exports.tm_music:Name(...). Booths, speakers and vehicle radios are all called decks, and a deck is named: a booth by the name you gave it, a speaker speaker:<id>, a vehicle radio vehicle:<PLATE>.
Server
Booths
exports.tm_music:AddBooth(name, def) --> ok, err
exports.tm_music:RemoveBooth(name) --> booleanAddBooth makes a booth that lasts until the calling resource stops (it is not saved). def:
| Field | Meaning |
|---|---|
label | Name shown to players. Required. |
icon | A lucide: icon name. |
speakers | Required. Map of key to { label?, coords, distance? }. |
controls | List of { coords, radius? } control points. Leave out for a booth that only scripts open. |
volume | Starting volume, 0 to 100. |
groups | Job, gang or group filter ('police', { 'police', 'sheriff' }, { police = 2 }). |
bucket | Routing bucket the audio is confined to. |
connectRange | Overrides the Connect range setting. |
RemoveBooth also deletes a booth placed with /musicbooth.
Placed speakers
RegisterSpeaker(def), UpdateSpeaker(id, patch) and RemoveSpeaker(id). See Placed speakers.
Vehicle radios
exports.tm_music:AddVehicleRadio(netId, plate?, label?, owned?) --> ok, err
exports.tm_music:RemoveVehicleRadio(netId, plate?) --> booleanSee Vehicle radios.
Playing
| Export | Description |
|---|---|
GetDeck(name) | The state of a deck (name, label, kind, url, paused, volume, speakers...), or nil. |
PlayOn(name, url, volume?) | Plays a link on a booth, speaker or vehicle radio. |
StopOn(name) | Stops it. |
SetVolumeOn(name, volume) | 0 to 100. |
OpenFor(source, name?) | Opens the music window for a player, connected to the deck when you give a name (they must be in range). Returns ok, reason. |
GetStations() | The radio station list. |
Lending speakers to a source
For a TV or a DJ show that wants a booth's speakers. A source owns the deck while attached and is told when a player takes it back.
| Export | Description |
|---|---|
ListBoothsNear(coords, source?, range?, bucket?, withPoints?) | Booths whose speakers reach coords, nearest first: { name, label, icon, distance, owner?, playing, points? }. |
AttachSource(name, owner, data, coords?) | Plays the source's audio. data is { url, time?, volume?, label?, bucket?, paused? }. Returns ok, reason (missing, busy, range, invalid). |
UpdateSource(name, owner, data) | Follows the source: { paused?, time?, volume? }. |
DetachSource(name, owner) | Gives the deck back and stops it. |
HasSource(name, owner) | Is the owner still attached? |
owner is a stable string you choose, such as tv:123.
Server events
| Event | Arguments | When |
|---|---|---|
tm_music:sourceReleased | name, owner | A player took the deck back from a source. |
tm_music:vehicleRadioAdded | netId, plate | A vehicle radio was created. |
tm_music:vehicleRadioRemoved | netId, plate | A vehicle radio was removed. |
Client
| Export | Description |
|---|---|
OpenPlayer() / ClosePlayer() | Opens or closes the window with the player's own music. |
IsPlayerOpen() | Is the window open? |
OpenBooth(name) | Connects to a booth and opens the window. |
OpenVehicleRadio(netId?) | Connects to a vehicle's radio (the one you are in without a net id) and opens the window. |
Feature detection
The manifest lists the optional features it has, so a script written for a newer build can check before it calls an export an older one lacks (calling a missing export stalls the caller):
local features = GetResourceMetadata('tm_music', 'music_features', 0) or ''
local hasSources = features:find('sources', 1, true) ~= nilspeakers is RegisterSpeaker, UpdateSpeaker and RemoveSpeaker. sources is the source exports.