Skip to content

Phone apps ​

The music app is the same page everywhere. It opens inside a phone, or in its own window with /tm:music.

The Phone setting picks which phone gets the app. Detect automatically (the default) uses lb-phone when it is installed, then NPWD. No phone app leaves only the window. Changing it needs a restart of tm_music.

lb-phone ​

Nothing to install. tm_music adds itself to lb-phone as a custom app that is already on every phone (App name setting, default Music). It registers again whenever lb-phone restarts. The app follows the phone's dark and light mode.

NPWD ​

NPWD loads external apps as React bundles, so it needs a small shell resource, npwd_tm_music, that shows tm_music's page in a frame. The source is in tm_music/integrations/npwd, with the steps to build it from NPWD's app template. After you add npwd_tm_music to the apps list in NPWD's config.json, tm_music handles the rest. NPWD cannot push messages into a frame, so the app checks for updates once a second while it is open.

The window ​

/tm:music always opens it, and so does the short /music (rename or turn it off with the Command setting, handy if another script already uses /music). It opens the player in the middle of the screen. Opening a booth or a vehicle radio uses the same window. Press Esc or the close button to leave. Scripts can use OpenPlayer, OpenBooth and OpenVehicleRadio (see Exports).

What the player does ​

  • Headphones or phone speaker. The two private outputs. Music on the phone speaker comes out of the character and is heard within the Phone speaker range. Switching keeps the track and position.
  • Play on. Lists the speakers within reach. Connect, ask for control, or add up to four more speakers to mirror the same music.
  • Favorites, playlists, radio. Add a song by searching or pasting a link.

Adding another phone ​

A phone adapter is one file. Copy templates/bridge/phone/client.lua to bridge/phone/custom/client.lua, fill in the marked lines (add the app to the phone, send it a message), set Phone to Custom adapter and restart tm_music. The files in bridge/phone are not encrypted, so they can also be adjusted when a phone changes its app API. An adapter returns { name, resource, pollOnly, isAvailable, register, unregister, send }: register(app) adds the music app (app is { name, description }), send(message) delivers a message to the page ({ source = 'tm_music', type, payload }, listed in ui/PROTOCOL.md), and an adapter that cannot push sets pollOnly = true so the page asks for its messages instead.