Onex
Onex
Home
Products
Documentation
Changelog
Login with FiveM
  • 👋 Welcome
  • Claim Purchase
  • Translations
    • Weaponmeta
    • Voice Interaction
      Integrations
      Installation
      Configuration
      Features
      Action
      Events
      Layers
      Npc
      Speech
Artifacts Tracker
  1. Onex Scripts
  2. Scripts_guides / Api Reference
Ctrl K

API REFERENCE#

All exports are client-side only — call them from client scripts in your resource. For same-resource callbacks, use RegisterAction({...}) (global) instead of the export; Lua function closures do not survive across export boundaries.

Action System#

registerAction(def)#

Register a new voice action.

Syntax
exports['onex-voiceInteraction']:registerAction(def)
NameTypeRequiredDescription
namestring✅Unique action identifier
phrasesstring[]✅Spoken phrases; use {var} for variable slots
triggertable✅What fires on match — see Trigger types
layerstring—Layer to assign: "ambient", "context", "global", or custom
groupstring—Batch enable/disable group name
tagsstring[]—Filter tags for queryActions
descriptionstring—Max 200 chars; used by LLM tier matching
minSimilaritynumber—Match confidence threshold (0.0–1.0, default 0.7)
conditionfunction—function(data) return boolean — pre-execution gate
variableAliasestable—Synonym map { amount = "sum" }
variableTypestable—Type coercion { amount = "number" }
variableDefaultstable—Fallback values { size = "large" }
numberNormalizationboolean—Enable automatic word-to-number parsing (e.g. "five" → 5)

Returns: { success = true, data = { name = "action_name" } }

Your Script
exports['onex-voiceInteraction']:registerAction({ name = "buy_water", phrases = { "buy water", "give me water" }, trigger = { event = { name = "myres:buyItem", type = "server", params = { item = "water" } } }, group = "voice_shop_1", minSimilarity = 0.7 })

unregisterAction(target)#

Unregister one action, all from a resource, or all from the calling resource.

Syntax
exports['onex-voiceInteraction']:unregisterAction(target)
NameTypeDescription
targetstringAction name, "@resource_name" for all from a resource, or omit for calling resource

Returns: { success = true, data = { count = 1 } }

Your Script
exports['onex-voiceInteraction']:unregisterAction("buy_water") exports['onex-voiceInteraction']:unregisterAction("@my-resource") exports['onex-voiceInteraction']:unregisterAction() -- all from calling resource

queryActions(filter)#

Query registered actions with optional filters.

Syntax
exports['onex-voiceInteraction']:queryActions(filter)
NameTypeDescription
filter.namestringMatch by exact action name
filter.groupstringMatch by group name
filter.tagstringMatch by tag
filter.enabledbooleanMatch by enabled state
filter.resourcestringMatch by source resource name

Returns: { success = true, data = { actions = { ... }, count = 5 } }

Your Script
local result = exports['onex-voiceInteraction']:queryActions({ group = "voice_shop_1", enabled = true }) print("Active shop actions:", result.data.count)

setActionEnabled(target, enabled)#

Enable or disable a single action, a named group, or all actions.

Syntax
exports['onex-voiceInteraction']:setActionEnabled(target, enabled)
NameTypeDescription
targetstringAction name, "#group_name" for a group, "*" for all
enabledbooleantrue to enable, false to disable

Returns: { success = true, data = { affected = 1 } }

Your Script
exports['onex-voiceInteraction']:setActionEnabled("buy_water", false) exports['onex-voiceInteraction']:setActionEnabled("#voice_shop_1", false) exports['onex-voiceInteraction']:setActionEnabled("*", true)

getActionEnabled(target)#

Get the enabled state of an action or group.

Syntax
exports['onex-voiceInteraction']:getActionEnabled(target)
NameTypeDescription
targetstringAction name, "#group_name", or omit for full disabled state

Returns (action/group): { success = true, data = { enabled = true } } Returns (nil target): { success = true, data = { disabledActions = { ... }, disabledGroups = { ... } } }

Your Script
local r = exports['onex-voiceInteraction']:getActionEnabled("buy_water") print(r.data.enabled) -- true or false

Layer System#

registerLayer(config)#

Register a custom layer for voice context management.

Syntax
exports['onex-voiceInteraction']:registerLayer(config)
NameTypeDescription
config.namestringUnique layer identifier
config.prioritynumberConflict resolution priority (default 50)
config.exclusivebooleanOnly one group active at a time (default true)
config.disableAmbientbooleanDisable ambient layer when active (default true)
config.disableLayersstring[]Other layers to disable when entered
config.promptHintsstring[]STT vocabulary hints for improved recognition
config.proximityPrioritybooleanEnable proximity-based layer yielding — closer entity wins conflicts

Returns: { success = true, data = { name = "shop" } }

Your Script
exports['onex-voiceInteraction']:registerLayer({ name = "shop", priority = 60, exclusive = true, disableAmbient = true, disableLayers = { "npc_interact" }, promptHints = { "buy", "sell", "price" } })

enterLayer(layerName, groupName, options)#

Activate a layer with a specific action group.

Syntax
exports['onex-voiceInteraction']:enterLayer(layerName, groupName, options)
NameTypeDescription
layerNamestringRegistered layer name
groupNamestringGroup name to activate (matches group on registered actions)
options.promptHintsstring[]Override STT hints for this session
options.customHintstableBypass automatic hint collection with explicit hint objects

Returns: { success = true, data = { layer = "shop", group = "voice_shop_1" } }

Your Script
exports['onex-voiceInteraction']:enterLayer("shop", "voice_shop_liquor_1")

exitLayer(layerName)#

Deactivate a layer and restore previous state.

Syntax
exports['onex-voiceInteraction']:exitLayer(layerName)
NameTypeDescription
layerNamestringLayer name to exit

Returns: { success = true, data = { layer = "shop" } }

Your Script
exports['onex-voiceInteraction']:exitLayer("shop")

setLayerGroup(layerName, groupName)#

Switch to a different action group within an already-active layer.

Syntax
exports['onex-voiceInteraction']:setLayerGroup(layerName, groupName)
NameTypeDescription
layerNamestringActive layer name
groupNamestringNew group to activate

Returns: { success = true, data = { layer = "banking", group = "voice_bank_confirm" } }

Your Script
exports['onex-voiceInteraction']:setLayerGroup("banking", "voice_bank_confirm")

setLayerEnabled(layerName, enabled)#

Enable or disable a layer globally.

Syntax
exports['onex-voiceInteraction']:setLayerEnabled(layerName, enabled)
NameTypeDescription
layerNamestringLayer name
enabledbooleanEnable or disable

Returns: { success = true, data = { layer = "npc_interact", enabled = false } }

Your Script
exports['onex-voiceInteraction']:setLayerEnabled("npc_interact", false)

setLayerConfig(layerName, config)#

Update a layer's priority or conflict rules at runtime.

Syntax
exports['onex-voiceInteraction']:setLayerConfig(layerName, config)
NameTypeDescription
layerNamestringLayer name
config.prioritynumberNew priority value
config.disableAmbientbooleanUpdate ambient disable rule
config.disableLayersstring[]Replace conflicting layers list

Returns: { success = true, data = { layer = "shop" } }

Your Script
exports['onex-voiceInteraction']:setLayerConfig("shop", { priority = 70 })

setLayerHints(layerName, hints)#

Override the visible voice hints for the current session of an active layer.

Syntax
exports['onex-voiceInteraction']:setLayerHints(layerName, hints)
NameTypeDescription
layerNamestringActive layer name
hintstable[]Array of { name, phrase, layer? } hint objects

Returns: { success = true, data = { layer = "shop", count = 2 } }

Your Script
exports['onex-voiceInteraction']:setLayerHints("shop", { { name = "buy_item", phrase = "buy water", layer = "shop" }, { name = "check_price", phrase = "how much", layer = "shop" } })

setLayerProximity(layerName, distance)#

Update the proximity distance for a layer registered with proximityPriority. The layer with the smallest distance wins conflicts.

Syntax
exports['onex-voiceInteraction']:setLayerProximity(layerName, distance)
NameTypeDescription
layerNamestringLayer name
distancenumber | nilDistance to nearest target, or nil to clear proximity

Returns: { success = true, data = { layer = "npc_interact" } }

Your Script
local dist = #(GetEntityCoords(PlayerPedId()) - npcCoords) exports['onex-voiceInteraction']:setLayerProximity("npc_interact", dist) -- Clear when done exports['onex-voiceInteraction']:setLayerProximity("npc_interact", nil)

shouldLayerYield(layerName)#

Check whether a layer should yield to a closer proximity competitor. Returns true if another active layer with proximityPriority has a smaller distance.

Syntax
exports['onex-voiceInteraction']:shouldLayerYield(layerName)
NameTypeDescription
layerNamestringLayer name to check

Returns: boolean

Your Script
if exports['onex-voiceInteraction']:shouldLayerYield("npc_interact") then return -- another NPC is closer, skip activation end exports['onex-voiceInteraction']:enterLayer("npc_interact", "voice_npc_1")

getCurrentLayer()#

Get the currently active custom layer and group.

Syntax
exports['onex-voiceInteraction']:getCurrentLayer()

Returns: { success = true, data = { layer = "shop", group = "voice_shop_1" } } — data is nil if no custom layer is active.

Your Script
local r = exports['onex-voiceInteraction']:getCurrentLayer() if r.data then print("In layer:", r.data.layer, "group:", r.data.group) end

getLayerState(layerName)#

Get the current state of a specific layer.

Syntax
exports['onex-voiceInteraction']:getLayerState(layerName)
NameTypeDescription
layerNamestringLayer name to inspect

Returns: { success = true, data = { enabled, activeGroup, priority, exclusive, disableAmbient, disableLayers } }

Your Script
local r = exports['onex-voiceInteraction']:getLayerState("shop") print("shop priority:", r.data.priority)

getLayers()#

Get all registered layers and their current state.

Syntax
exports['onex-voiceInteraction']:getLayers()

Returns: { success = true, data = { layers = { [name] = { enabled, activeGroup, priority, ... } } } }

Your Script
local r = exports['onex-voiceInteraction']:getLayers() for name, layer in pairs(r.data.layers) do print(name, layer.priority, layer.enabled) end

Speech & TTS#

speak(text, options)#

Synthesize and play TTS audio — global or 3D positioned.

Syntax
exports['onex-voiceInteraction']:speak(text, options)
NameTypeDescription
textstringText to speak
options.voicestring | tableVoice name string, or { name, rate, pitch, volume, stability, similarityBoost } object
options.ratenumberSpeech rate shorthand (default 1.0) — overridden by voice.rate if both set
options.pitchnumberPitch shift shorthand (default 1.0) — overridden by voice.pitch if both set
options.volumenumberVolume level shorthand (default 1.0) — overridden by voice.volume if both set
options.entitynumberPed entity handle for 3D positioned audio
options.maxDistancenumberHearing range for 3D audio (default 30.0)
options.animationtable | falsefalse to disable all animation, or { lipSync, gesture, gestureDict, gestureAnim, returnToIdle, idleScenario }
options.showSubtitlebooleanDisplay subtitle synced to TTS duration
options.immediateSubtitlebooleanDisplay subtitle immediately without waiting for TTS timing
options.npcNamestringDisplay name shown in subtitles
options.networkedbooleanBroadcast speech to other players via state bags

Returns: { success = true, data = { soundId = "sound_12345_6789", is3D = true } }

Your Script
-- Global TTS exports['onex-voiceInteraction']:speak("Hello world", { voice = { name = "en-US-GuyNeural", rate = 1.0, pitch = 1.0 } }) -- 3D NPC speech(voice auto-detected from NPC config) exports['onex-voiceInteraction']:speak("Hey there!", { entity = pedHandle, maxDistance = 30.0 }) -- Custom animation with subtitle exports['onex-voiceInteraction']:speak("Step right up!", { entity = pedHandle, animation = { lipSync = true, gesture = true, gestureDict = "gestures@m@standing@casual", gestureAnim = "gesture_hand_up" }, showSubtitle = true, npcName = "Vendor" })

stopSpeech(soundId)#

Stop TTS playback — all sounds or a specific one.

Syntax
exports['onex-voiceInteraction']:stopSpeech(soundId)
NameTypeDescription
soundIdstringSpecific 3D sound ID to stop, or omit to stop everything

Returns: { success = true, data = { stopped = 1 } }

Your Script
exports['onex-voiceInteraction']:stopSpeech() -- stop all exports['onex-voiceInteraction']:stopSpeech("sound_12345_6789") -- stop one

getVoices(callback, timeout)#

Retrieve the available TTS voice list from the browser engine.

Syntax
exports['onex-voiceInteraction']:getVoices(callback, timeout)
NameTypeDescription
callbackfunctionfunction(result) called with { success, data = { voices } }
timeoutnumberTimeout in milliseconds (default 5000)

Without callback: returns { success = true, data = { pending = true, listenEvent = "onex-voiceInteraction:tts:voices" } }

Your Script
exports['onex-voiceInteraction']:getVoices(function(result) if result.success then for _, voice in ipairs(result.data.voices) do print(voice.name) end end end, 5000)

getVoiceForPed(entity)#

Get the configured or auto-detected TTS voice for a ped.

Syntax
exports['onex-voiceInteraction']:getVoiceForPed(entity)
NameTypeDescription
entitynumberPed entity handle

Returns: { success = true, data = { voice = "en-US-GuyNeural", gender = "male", stability = 0.5, similarityBoost = 0.75, cached = false, isDefault = false } }

Your Script
local r = exports['onex-voiceInteraction']:getVoiceForPed(pedHandle) if r.success then print("Voice:", r.data.voice, "Gender:", r.data.gender) end

clearVoiceCache(entity)#

Clear the voice assignment cache for a specific ped or all peds.

Syntax
exports['onex-voiceInteraction']:clearVoiceCache(entity)
NameTypeDescription
entitynumberPed entity handle, or omit to clear all

Returns: { success = true, data = { cleared = 1 } }

Your Script
exports['onex-voiceInteraction']:clearVoiceCache(pedHandle) -- one ped exports['onex-voiceInteraction']:clearVoiceCache() -- all

NPC System#

getNPCInfo(target)#

Get complete NPC configuration and defaults for an entity or model name.

Syntax
exports['onex-voiceInteraction']:getNPCInfo(target)
NameTypeDescription
targetnumber | stringPed entity handle or model name string (e.g. "mp_m_freemode_01")

Returns: { success = true, data = { config, voice, animation, audio, personality, traits, gender, isDefault } }

Your Script
local r = exports['onex-voiceInteraction']:getNPCInfo(pedHandle) if r.success then print("Voice:", r.data.voice.voice) print("Is default config:", r.data.isDefault) end

checkNPCTraits(entity, traitIds)#

Check whether an NPC has specific traits. Optional traits are probability-rolled and cached.

Syntax
exports['onex-voiceInteraction']:checkNPCTraits(entity, traitIds)
NameTypeDescription
entitynumberPed entity handle
traitIdsstring | string[]Single trait ID or array of trait IDs

Returns: { success = true, data = { [traitId] = { hasTrait, isRequired, probability, rolledProbability, cached } } }

FieldTypeDescription
hasTraitbooleanWhether the NPC has this trait
isRequiredbooleanWhether the trait is required (not probability-based)
probabilitynumberConfigured probability (0.0–1.0)
rolledProbabilitynumberActual rolled value used to determine hasTrait
cachedbooleanWhether this result came from the roll cache
Your Script
local r = exports['onex-voiceInteraction']:checkNPCTraits(pedHandle, { "drug_addict", "aggressive" }) if r.data.drug_addict.hasTrait then -- respond accordingly end

queryNPCTraits(query)#

Query traits by entity, tag, or definition name.

Syntax
exports['onex-voiceInteraction']:queryNPCTraits(query)
NameTypeDescription
query.entitynumberGet all traits for a specific ped
query.tagstringFilter by trait tag (combinable with entity)
query.definitionstring | trueGet a specific trait definition, or true for all
Your Script
-- All traits on one NPC local r = exports['onex-voiceInteraction']:queryNPCTraits({ entity = pedHandle }) -- NPCs with "criminal" tagged traits local r = exports['onex-voiceInteraction']:queryNPCTraits({ tag = "criminal" }) -- Single trait definition local r = exports['onex-voiceInteraction']:queryNPCTraits({ definition = "drug_addict" })

clearTraitCache(entity)#

Clear cached trait roll results for a ped, forcing a re-roll on the next checkNPCTraits call.

Syntax
exports['onex-voiceInteraction']:clearTraitCache(entity)
NameTypeDescription
entitynumberPed entity handle — required, clears only this ped

Returns: { success = true, data = { cleared = 1 } }

Your Script
exports['onex-voiceInteraction']:clearTraitCache(pedHandle)

NPC Interaction#

startNPCInteraction(config)#

High-level convenience export that combines layer registration, action registration, and greeting speech into a single call.

Syntax
exports['onex-voiceInteraction']:startNPCInteraction(config)
NameTypeRequiredDescription
config.idstring✅Unique interaction identifier
config.entitynumber✅Ped entity handle
config.npcNamestring—Display name for subtitles
config.greetingstring—TTS greeting spoken on start
config.greetingOptionstable—Options passed to speak() for the greeting
config.layertable—Layer config { priority, exclusive, disableAmbient }
config.groupstring—Action group name
config.actionstable[]—Array of action definitions to register
config.autoCleanupboolean—Auto-cleanup when player moves away

Returns: { success = true, data = { interactionId, layerName, groupName, registeredActions, actionErrors? } }

Your Script
exports['onex-voiceInteraction']:startNPCInteraction({ id = "vendor_john", entity = pedHandle, npcName = "John", greeting = "Hello! How can I help you today?", layer = { priority = 50, exclusive = true, disableAmbient = true }, group = "shopping", actions = { { name = "buy_water", phrases = { "give me water", "water please" }, trigger = { event = { name = "myres:buy", type = "server", params = { item = "water" } } }, minSimilarity = 0.7 } }, autoCleanup = true, })

stopNPCInteraction(id, options)#

Stop an active NPC interaction, cleaning up actions and exiting the layer.

Syntax
exports['onex-voiceInteraction']:stopNPCInteraction(id, options)
NameTypeDescription
idstringInteraction identifier from startNPCInteraction
options.stopSpeechbooleanAlso stop any active TTS playback

Returns: { success = true, data = { interactionId, actionsRemoved, layerExited } }

Your Script
exports['onex-voiceInteraction']:stopNPCInteraction("vendor_john") exports['onex-voiceInteraction']:stopNPCInteraction("vendor_john", { stopSpeech = true })

Session Context#

setContext(group, key, value)#

Store a key-value pair scoped to an action group.

Syntax
exports['onex-voiceInteraction']:setContext(group, key, value)
NameTypeDescription
groupstringGroup name scope
keystringContext key
valueanyValue to store
Your Script
exports['onex-voiceInteraction']:setContext("voice_shop_1", "selectedItem", "water")

getContext(group, key)#

Retrieve a stored context value.

Syntax
exports['onex-voiceInteraction']:getContext(group, key)

getAllContext(group)#

Get all key-value pairs for a group.

Syntax
exports['onex-voiceInteraction']:getAllContext(group)

hasContext(group, key)#

Check if a context key exists.

Syntax
exports['onex-voiceInteraction']:hasContext(group, key)

removeContext(group, key)#

Remove a specific context key.

Syntax
exports['onex-voiceInteraction']:removeContext(group, key)

clearContext(group)#

Clear all context for a group.

Syntax
exports['onex-voiceInteraction']:clearContext(group)

clearAllContext()#

Clear all context across all groups.

Syntax
exports['onex-voiceInteraction']:clearAllContext()

updateContext(group, key, data)#

Merge a table into an existing context value.

Syntax
exports['onex-voiceInteraction']:updateContext(group, key, data)

incrementContext(group, key, amount)#

Increment a numeric context value.

Syntax
exports['onex-voiceInteraction']:incrementContext(group, key, amount)

pushContext(group, key, value)#

Push a value onto a context array.

Syntax
exports['onex-voiceInteraction']:pushContext(group, key, value)

setContextAutoClear(group, enabled)#

Enable or disable automatic context clearing when exiting a layer.

Syntax
exports['onex-voiceInteraction']:setContextAutoClear(group, enabled)

getContextStats()#

Get context usage statistics.

Syntax
exports['onex-voiceInteraction']:getContextStats()

Returns: { success = true, data = { groups, totalKeys, totalSize } }

Action System
Layer System
Speech & TTS
NPC System
NPC Interaction
Session Context
Events

Last updated 3 months ago

Quick Links

All DocumentationOur Products