Setting up an in-game voice and radio system for a FiveM roleplay server shouldn't feel like guessing code in the dark. If you're running an ESX framework server, integrating a reliable radio script gives emergency services, criminal organizations, and civilian groups the secure, multi-frequency communication channels they need for immersive gameplay.
This guide walks you through installing, configuring, and tuning an ESX RP radio script from scratch. You'll learn how to set dependencies, adjust frequency ranges, configure job-locked channels, and troubleshoot common audio or synchronization bugs that frustrate players.
Core Prerequisites and Dependencies
Before touching any configuration files, verify that your server environment supports the script. Most modern ESX radio resources rely on specific voice management systems and framework versions to handle real-time streaming and distance-based audio checks.
- FiveM Server Artifacts: Ensure your server runs on a stable, up-to-date server artifact (recommendations usually point to artifact 5848 or higher).
- Voice System: You need a compatible voice plugin installed and running correctly, such as PMA-Voice or Salt-CB Radio. The radio script acts as an interface layer that communicates directly with your voice API.
- ESX Framework: A standard ESX legacy or core installation. Ensure your database tables for items are active so the radio item can be properly registered.
If your voice plugin fails to initialize or drops packets, players will experience static, muted channels, or voice bleed across restricted frequencies. Always test your voice resource independently before loading custom UI radio scripts.
Adding the Radio Item to Your Database
Players shouldn't just press a key to open a radio UI; they should possess a physical item in their inventory. This creates realistic roleplay scenarios where characters can have their radios confiscated, dropped, or stolen.
First, insert the radio item into your database. Depending on whether you use ox_inventory, qtarget, or standard esx_inventoryhud, the implementation varies slightly. For standard ESX systems using items, run an SQL insert statement:
INSERT INTO `items` (`name`, `label`, `weight`, `rare`, `can_remove`) VALUES
('radio', 'Radio', 1, 0, 1);
Next, configure your inventory script to register the item usage. In your server.lua or inventory configuration file, bind the item use event so that double-clicking or using the radio item triggers NUI focus:
ESX.RegisterUsableItem('radio', function(source)
local xPlayer = ESX.GetPlayerFromId(source)
TriggerClientEvent('esx_rp_radio:use', source)
end)
Configuring Frequencies and Job Restrictions
The heart of any good radio configuration lies in restricting specific channels to authorized factions, such as police, emergency medical services, and mechanics. Unrestricted open channels quickly turn into chaotic noise on busy servers.
Open your configuration file (config.lua) and locate the frequency limitation arrays. You want to map specific numeric ranges to specific job metadata checks provided by ESX.
- Civilian Frequencies: Generally set between 1.0 MHz and 99.9 MHz for open public use.
- Encrypted Frequencies: Reserved for emergency services, typically channels 100.0 MHz through 999.0 MHz.
Here is a clean example of how to structure job-locked frequencies in your configuration script:
Config = {}
Config.RestrictedChannels = {
[101] = { job = 'police', label = 'Dispatch Primary' },
[102] = { job = 'police', label = 'Tactical Channel' },
[201] = { job = 'ambulance', label = 'EMS Dispatch' },
[301] = { job = 'mechanic', label = 'Tow Service' }
}
Config.MaxFrequency = 999.9
Config.MinFrequency = 1.0
Config.DefaultVolume = 50
When a player attempts to tune into channel 101, the client script must verify their current job table. If their job doesn't match the required string, the script rejects the frequency change and plays an error beep.
Adjusting Client UI and Keybindings
User experience dictates whether players enjoy using the radio interface. Clunky UI layouts or conflicting keybinds lead to constant complaints. Most radio scripts use NUI (HTML/CSS/JS) overlays that slide onto the screen when the item is used.
Open the client.lua file to map your default open command and key mapping. Give players the ability to toggle the radio via a command or a dedicated keybind registered with FiveM's RegisterKeyMapping native:
RegisterKeyMapping('toggleradio', 'Toggle Radio Interface', 'keyboard', 'f5')
RegisterCommand('toggleradio', function()
ToggleRadioUI()
end, false)
If the NUI interface fails to appear or locks your mouse cursor permanently on the screen, check your JavaScript listener for window.addEventListener('message', ...) blocks. Ensure that focus is correctly released using SetNuiFocus(false, false) when the player closes the radio window.
Common Configuration Mistakes to Avoid
Administrators often run into avoidable roadblocks during initial setup. Keep these pitfalls in mind to save hours of debugging:
- Mismatched Voice Dependencies: Trying to run an older radio resource with a modern version of pma-voice will break native radio submixes. Always match your script versions to your voice resource documentation.
- Missing Item Icons: If the radio appears as a generic box or throws an error in your inventory, verify that your inventory image directory contains a
radio.pngfile matching the exact item name string. - Forgetting Client Cache: After making edits to HTML or JavaScript files within the resource folder, clear your server cache and restart the specific resource so the NUI assets reload correctly.
Frequently Asked Questions
Why can't players hear each other even on the same frequency?
This usually stems from a synchronization mismatch in pma-voice. Ensure that setr voice_enableRadioSubmix 1 is present in your server.cfg file and that all players have restarted their game clients after voice resource updates.
How do I add custom job grades to restricted channels?
Modify the channel check function in your server-side script to evaluate xPlayer.job.grade. Instead of checking just for police, you can set minimum grade requirements so only officers ranked Sergeant and above can access tactical command channels.
Can players use the radio while in handcuffs or dead?
Yes, by default, unless you add state checks. You should wrap your radio open command with conditional checks verifying that isDead is false and that the player isn't cuffed or detained by police scripts.
How do I change the volume levels for individual radio transmissions?
Most advanced configurations allow you to modify the volume multiplier inside the voice API event listeners. Look for audio filter settings in your voice resource config rather than the radio UI, as volume attenuation is handled directly by the voice engine.