Exports & Integration
ARS CarPlay does not register traditional exports['ars_carplay'] functions. Its integration surface is exposed through ox_lib callbacks and client events that other resources can call/trigger. This page documents the stable, intentional interfaces.
Note: Internal NUI callbacks (
musicAction,vehicleAction,navigationAction,radioAction,radioFetchStations,saveSettings,getInitialState,uiReady,closeUI) are for the Preact UI only. They are not guaranteed stable for external use.
Server Callbacks (lib.callback)
Section titled “Server Callbacks (lib.callback)”Call these from any server script via lib.callback.await('ars_carplay:<name>', source, payload).
ars_carplay:getSettings
Section titled “ars_carplay:getSettings”Retrieve the persisted settings blob for a player/vehicle.
local res = lib.callback.await('ars_carplay:getSettings', source, { scope = 'plate', -- 'plate' | 'player' (matches Config.CarPlay.settingsScope) plate = 'ABC123' -- required when scope = 'plate'})-- res = { ok = true, settings = { lastApp = 'music', layout = 'cluster', ... }, persistable = true }- Side: Server
- Scope: Matches
Config.CarPlay.settingsScope(plate= per-vehicle,player= per-character). - Persistable:
trueif the vehicle is owned (or scope isplayer),falsefor NPC/unowned vehicles (memory-only).
ars_carplay:saveSettings
Section titled “ars_carplay:saveSettings”Persist a partial settings patch (merged onto existing blob).
local ok = lib.callback.await('ars_carplay:saveSettings', source, { scope = 'plate', plate = 'ABC123', data = { layout = 'desktop', lastApp = 'navigation' }})-- ok = true | false- Side: Server
- Data: Any subset of
CarPlaySettings(layout, lastApp, speedUnit, tablet.position,music.{station,volume}).
ars_carplay:audio:command
Section titled “ars_carplay:audio:command”Unified audio control for Music and Internet Radio. Routes to xsound server exports.
local res = lib.callback.await('ars_carplay:audio:command', source, { app = 'music', -- 'music' | 'radio' cmd = 'play', -- 'play' | 'pause' | 'resume' | 'stop' | 'setVolume' | 'seek' | 'position' url = 'https://...', -- required for 'play' volume = 0.5, -- 0.0 - 1.0 coords = vector3(x,y,z), -- required for positional play loop = false, -- 'play' only distance = 25.0, -- positional only seconds = 30.0 -- 'seek' only})-- res = { ok = true, name = 'carplay_ABC123' }- Side: Server (called from client via
lib.callback.await) - Positional vs Local: If
coordsprovided →PlayUrlPoswithsource = -1(broadcast to all, 3D proximity). Otherwise →PlayUrlwithsource = player(local only). - Sound ID: Derived from the vehicle plate (
carplay_<PLATE>for music,carplay_radio_<PLATE>for radio). All players in the same vehicle share the handle.
ars_carplay:fetchStations
Section titled “ars_carplay:fetchStations”Search/browse internet radio stations via the Radio Browser API.
local res = lib.callback.await('ars_carplay:fetchStations', source, { tag = 'rock', -- Radio Browser tag (bytagexact) -- OR search = 'jazz fm' -- free-text search})-- res = { ok = true, stations = { { name, url, favicon, tags, codec, bitrate }, ... }, disabled = false }- Side: Server
- Cache: Results cached for
Config.Radio.browser.cacheSeconds(default 300s). - Disabled: Returns
{ ok = true, stations = {}, disabled = true }ifConfig.Radio.browser.enabled = false.
Client Events
Section titled “Client Events”Trigger these from any client script to control the UI.
ars_carplay:client:openUI
Section titled “ars_carplay:client:openUI”Force-open the CarPlay dashboard (respects vehicle/driver/class gates).
TriggerEvent('ars_carplay:client:openUI')-- Internally calls Client.CanUseCarPlay() → shows error notification if not allowedars_carplay:client:closeUI
Section titled “ars_carplay:client:closeUI”Force-close the CarPlay dashboard.
TriggerEvent('ars_carplay:client:closeUI')Framework Bridge (Internal)
Section titled “Framework Bridge (Internal)”The Bridge global is not an export — it’s a shared table populated by the active framework’s guarded files (frameworks/<fw>/shared.lua, client.lua, server.lua). Other resources should not depend on Bridge directly; use your framework’s native exports instead.
If you need to check vehicle ownership from another script, replicate the logic in frameworks/<fw>/server.lua → Bridge.IsVehicleOwned (soft oxmysql query with fallback).
Integration Patterns
Section titled “Integration Patterns”Open CarPlay from a Key Item / Command
Section titled “Open CarPlay from a Key Item / Command”-- server/main.lua (example)RegisterCommand('givecarplay', function(source) TriggerClientEvent('ars_carplay:client:openUI', source)end)Read Player’s Saved Layout from Another Script
Section titled “Read Player’s Saved Layout from Another Script”-- server/main.lualocal res = lib.callback.await('ars_carplay:getSettings', source, { scope = 'plate', plate = GetVehicleNumberPlateText(GetVehiclePedIsIn(GetPlayerPed(source)))})if res.ok and res.settings.layout then print('Player prefers layout:', res.settings.layout)endPlay a Track via Server Script (e.g., DJ Job)
Section titled “Play a Track via Server Script (e.g., DJ Job)”-- server/dj.lualib.callback.await('ars_carplay:audio:command', playerSrc, { app = 'music', cmd = 'play', url = 'https://example.com/track.mp3', volume = 0.7, coords = GetEntityCoords(GetVehiclePedIsIn(GetPlayerPed(playerSrc))), distance = 30.0})Add Custom Internet Radio Stations
Section titled “Add Custom Internet Radio Stations”Edit Config.Radio.stations in config.lua (escrow-ignored). Each entry:
{ name = 'My Station', url = 'https://stream.example.com/live.mp3', genre = 'Electronic', bitrate = 128 }URLs must be direct stream links (.mp3, .aac, .m3u8), not playlist pages.
Note: This guide is written by a third party. If you find any incorrect or outdated information, please contact us on Discord so we can update it for you.