Kartik Scripts

Voice Dispatch

kartik-ers turns callouts into spoken dispatch lines:

WhenExample line
A callout is offered1-ADAM-12, dispatch. Got a 10-50, Traffic collision. Can you take it?
The unit accepts1-ADAM-12, respond to 10-50, Traffic collision, Vinewood Blvd.
The unit arrives1-ADAM-12 on scene, Vinewood Blvd.
The callout is completed1-ADAM-12, Traffic collision is clear. Back in service.

You can have them read out by ElevenLabs (built in), or by any other TTS / AI dispatch script through events. Settings are in bridge/voice/server/dispatch_voice.lua (open file).

ElevenLabs voices

  1. Add your ElevenLabs API key to server.cfg:

    set ers_elevenlabs_key "your-api-key"

    Use set, not setr, so the key stays on the server.

  2. In bridge/voice/server/dispatch_voice.lua:

    ElevenLabs = {
        Enabled = true,
        VoiceId = 'your-voice-id',        -- from your ElevenLabs voice library
        ModelId = 'eleven_turbo_v2_5',    -- or 'eleven_multilingual_v2' for best quality
        Stability = 0.45,
        SimilarityBoost = 0.75,
        Volume = 0.8,                     -- in game volume, 0.0 to 1.0
        CacheSize = 64,                   -- repeated lines are reused
    },
  3. Restart kartik-ers. The unit hears dispatch read out in game. Repeated lines are reused, so they do not cost extra ElevenLabs credits.

Editing the lines

Lines = {
    offer  = '{unit}, dispatch. Got a {code}, {label}. Can you take it?',
    assign = '{unit}, respond to {code}, {label}, {street}.',
    arrive = '{unit} on scene, {street}.',
    clear  = '{unit}, {label} is clear. Back in service.',
},
Kinds = { offer = true, assign = true, arrive = true, clear = true }, -- turn single line types off
PlaceholderBecomes
{unit}The unit's callsign (or DefaultUnit)
{code}The callout's 10-code
{label}The callout name
{street}The callout location

Set Enabled = false at the top of the file to turn voice dispatch off completely.

Using your own TTS or AI dispatch

Every line is raised as an event, whether ElevenLabs is on or not:

-- server
AddEventHandler('kartik-ers:dispatchVoice', function(source, data)
    -- data.kind: 'offer' | 'assign' | 'arrive' | 'clear'
    -- data.text: the line to speak
    -- data.unit: callsign
    -- data.callout: { label, code, priority, street, coords }
end)

-- client (the unit's own client)
AddEventHandler('kartik-ers:client:onDispatchVoice', function(data)
    -- same fields as above
end)

Speaking your own lines

exports['kartik-ers']:SpeakDispatch(source, 'All units, code 4 at the Pacific Standard.')

Returns true when the line was sent to that unit. It goes through the same events and ElevenLabs voice as the built-in lines.

On this page