Developer
Overview
Integration runs through two layers: editable handler files in open/ (called via pcall, fail-closed on error) and exports. Mutating server exports are allowlist-gated: ml_* resources are allowed automatically, anything else must be added to Config.AllowedExportResources in server/config_server.lua.
Server Exports
Broadcast
GetActiveBroadcast(frequency): Current broadcast data for a frequency, ornil.IsFrequencyBroadcasting(frequency):truewhile a station or autoplay is live on that frequency.CanTransmitOnFrequency(src, frequency): Whether the player may talk on that frequency.BootstrapAutoplay(stationId): Starts a station's autoplay playlist. Allowlist-gated.PauseAutoplay(stationId)/ResumeAutoplay(stationId): Suspend and resume autoplay. Allowlist-gated.
Antennas
GetFixedAntennas(): Table of fixed towers with their live state.DamageFixedAntenna(id, amount): Applies damage to a fixed tower. Allowlist-gated.GetDisruptors(): Table of active jammers.
Inventory
radio: Registered as theusingItemhook for ox_inventory; other inventories route throughml_bridgeitem binds.
Client Exports
Interface
OpenRadioUI()/CloseRadioUI(): Open or close the handset interface.OpenStereoMenu()/CloseStereoMenu(): Stereo control panel.GetActiveTheme(): Current interface theme name.
Signal
CalculateSignal(playerCoords): Current signal value for the local player.GetSignalQuality(value?): Quality tier for a signal value.IsSignalLost():truewhile the player has no usable reception.IsInsideDisruptor():trueinside an active jammer radius.
Broadcast Audio
IsBroadcastPlaying(frequency): Whether station audio is playing locally.SetBroadcastVolume(volume): Local station audio volume.StopAllBroadcasts(): Stops all locally playing station audio.IsInSpeakerZone():trueinside a configured speaker zone.
Battery
RechargeBattery(): Consumes a battery item to recharge the held radio.
Server Handlers
Located in open/server.lua. All handlers are called via pcall; an error counts as a deny.
OnChannelJoin
1function OpenServer.OnChannelJoin(src, frequency)
2 return true -- return false to block the join
3endFires before a player joins a frequency. Blocking keeps them off the channel.
OnChannelLeave
1function OpenServer.OnChannelLeave(src, frequency)
2endNotification only, fires after a player leaves a frequency.
CanHack
1function OpenServer.CanHack(src, antenna, isFixed)
2 return true -- or: return false, 'locale_key'
3endAuthorizes an antenna hack attempt, after the built-in item, distance and requireSkill checks. Return false plus a locale key to deny with a custom message.
OnHackStart
1function OpenServer.OnHackStart(src, antenna, isFixed, itemUsed)
2endFires when the server commits to the attempt, before the progress bar runs. Useful for attempt logs or stat counters.
OnHackSuccess
1function OpenServer.OnHackSuccess(src, antenna, isFixed, itemUsed)
2endFires after a successful hack: the item is consumed, the lockout and hack damage are applied, and clients are updated.
Examples
1function OpenServer.OnHackStart(src, antenna, isFixed, itemUsed)
2 exports.ml_skills:AddXp('personal', 5, src)
3end
4
5function OpenServer.OnHackSuccess(src, antenna, isFixed, itemUsed)
6 exports.ml_skills:AddXp('personal', 50, src)
7end1function OpenServer.CanHack(src, antenna, isFixed)
2 if not exports.ml_skills:HasUnlockedSkill(nil, 'signals_mastery_3', src) then
3 return false, 'hack_skill_missing'
4 end
5 return true
6end1-- from an ml_* resource, or one added to Config.AllowedExportResources
2exports.ml_radio:BootstrapAutoplay('radio_station')