Skip to content

nss_libs - Prompts ​

Create easy to use prompts for your REDM resource.

Example ​

Notes

  • The order of created prompts is the order of showing them (top to bottom).
  • If you show multiple groups at the same time then pages/tabs are created automatically.
  • If you use multiple keys per prompt then hold/hold complete modes are not supported.
  • Consider how many pages/tabs are able to shown at the same time by the client.
  • Consider how many prompts per page/tab are able to shown at the same time by the client.
  • If your resource stops or restarts all groups and prompts are automatically destroyed.
  • Per default prompt groups are not shown during the player is dead. You can change this with showOnDeath().
lua
---@type NssLibsPromptsApi
local prompts_api = exports.nss_libs:getPromptsApi(GetCurrentResourceName())
lua
---@type NssLibsPromptsGroupApi
local group = prompts_api.createGroup('GROUP_LABEL')
lua
local SPACEBAR = 0xD9D0E1C0

---@type NssLibsPromptsPromptApi
local prompt_spacebar = group.addJustPressedPrompt('PROMPT_LABEL', SPACEBAR, function() 
    print('Spacebar just pressed')
    -- DO YOUR STUFF HERE
end)
lua
local KEY_LEFT = 0xA65EBAB4
local KEY_RIGHT = 0xDEB34313

---@type NssLibsPromptsPromptApi
local prompt_left_right = group.addJustPressedPrompt('PROMPT_LABEL', KEY_LEFT, function()
    print('Left just pressed')
    -- DO YOUR STUFF HERE
end)

prompt_left_right:addKey(KEY_RIGHT, function() 
    print('Right just pressed')
    -- DO YOUR STUFF HERE
end)
lua
-- This example works only with addJustPressedPrompt, addPressedPrompt,
-- addStandardHoldPrompt, addStandardizedHoldPrompt and only safe for single key prompts.

local KEY_DOWN = 0x05CA7C52

local on_press = function()
    print('Down key pressed')
    -- DO YOUR STUFF HERE
end

local on_release = function()
    print('Down key released')
    -- DO YOUR STUFF HERE
end

---@type NssLibsPromptsPromptApi
local prompt_down = group.addJustPressedPrompt('PROMPT_LABEL', KEY_DOWN, on_press, on_release) 
lua
local KEY_E = 0xCEFD9220

---@type NssLibsPromptsPromptApi
local prompt_hold = group.addDuringPressedPrompt('HOLD ACTION', KEY_E, function() 
    -- Called every frame (or every interval_ms) while key is held
    print('Still holding...')
end, {
    on_press = function() print('Key pressed') end,
    on_release = function() print('Key released') end,
    interval_ms = 100, -- Fire every 100ms instead of every frame (0 = per frame)
})
lua
group.show()

Methods ​

exports.nss_libs:getPromptsApi(resource_name) ​

ParamTypeDefaultDescription
resource_namestring—The name of the resource that wants to use the API

Returns NssLibsPromptsApi — A prompts API for the given resource.

NssLibsPromptsApi ​

.createGroup(label) ​

ParamTypeDefaultDescription
labelstring—The label of the group

Returns NssLibsPromptsGroupApi — A group API.

.setLinkChunkModeNearest() ​

Affects only NssLibsPromptsGroupApi.linkToCoords.

Sets the reaction mode for chunk grid linked prompt groups to nearest. Only the nearest result will be shown.

Returns NssLibsPromptsApi

.setLinkChunkModeAll() ​

Affects only NssLibsPromptsGroupApi.linkToCoords.

Sets the reaction mode for chunk grid linked prompt groups to all. All results will be shown.

This is the default mode.

Returns NssLibsPromptsApi

colors (table) ​

Table of color functions. Each function has an optional str attribute. If str is not given only the color code will be returned.

  • colors.Red(str)
  • colors.Yellow(str)
  • colors.Orange(str)
  • colors.Grey(str)
  • colors.White(str)
  • colors.LightGrey(str)
  • colors.Black(str)
  • colors.Pink(str)
  • colors.Blue(str)
  • colors.Purple(str)
  • colors.LightBlue(str)
  • colors.Yellow(str)
  • colors.LightPink(str)
  • colors.Green(str)
  • colors.DarkBlue(str)
  • colors.LightRedIsh(str)

NssLibsPromptsGroupApi ​

.addJustPressedPrompt(label, key, callback, release_callback?) ​

Calls the callback if the key is just pressed.

ParamTypeDefaultDescription
labelstring—The label of the prompt
keynumber|string—The key of the prompt (see key names and hashes or named keys)
callbackfunction—The callback of the prompt
release_callbackfunction?—If set then callback fires on press and release_callback fires on release

Returns NssLibsPromptsPromptApi

.addJustReleasedPrompt(label, key, callback) ​

Like addJustPressedPrompt but executes the callback if the key is just released.

.addPressedPrompt(label, key, callback, release_callback?) ​

Like addJustPressedPrompt but executes the callback if the key is pressed.

.addReleasedPrompt(label, key, callback) ​

Like addJustPressedPrompt but executes the callback if the key is released.

.addStandardHoldPrompt(label, key, callback, release_callback?, hold_time_ms?) ​

Like addJustPressedPrompt, but callback fires once when the hold completes (the ring is filled). The next hold counts only after the key came up. release_callback, if given, fires when the key comes up. (Before 0.37.17 the callback repeated every frame while the ring stayed filled, and a release could fire while the key was still down.)

hold_time_ms (since 0.37.11) is handed to PromptSetHoldMode as the hold time. Without it the library passes 1, as it always did; what the game makes of 1 is not verified. prompt.setHoldTime(ms) changes it later.

Two prompts on one key

Inside one group every key has exactly one place. A second prompt on the same key never appears in the game, without any message. Since 0.37.11 addPrompt prints a warning when this happens, or throws with Config.Prompts.StrictKeys = true. Use one prompt and change its label (setLabel) instead.

A hold prompt is a press with a delay that prevents a press by mistake. The release_callback is optional; use it for the cleanup of whatever the hold started, see example:

lua
local SPACEBAR = 0xD9D0E1C0

local callback = function()
    print('Spacebar pressed after delay')
    -- DO YOUR STUFF HERE
end

local release_callback = function()
    -- Do nothing
end

---@type NssLibsPromptsPromptApi
local prompt_spacebar = group.addStandardHoldPrompt('PROMPT_LABEL', SPACEBAR, callback, release_callback)

WARNING

If you use multiple keys per prompt then "hold"/"hold complete" modes are not supported.

.addStandardizedHoldPrompt(label, key, callback, release_callback?) ​

Like addJustPressedPrompt but executes the callback if the key is standardized hold.

WARNING

If you use multiple keys per prompt then "hold"/"hold complete" modes are not supported.

.addDuringPressedPrompt(label, key, during_pressed_callback, options?) ​

Creates a prompt that repeatedly fires a callback while the key is held down. Useful for continuous actions like chopping, fishing, or filling progress bars.

ParamTypeDefaultDescription
labelstring—The label of the prompt
keynumber|string—The key of the prompt (see key names and hashes or named keys)
during_pressed_callbackfunction—Called repeatedly while the key is held
optionsNssLibsDuringPressedOptions?—Configuration table (see below)

Options (NssLibsDuringPressedOptions):

ParamTypeDefaultDescription
on_pressfunction?—Called once when the key is first pressed
on_releasefunction?—Called once when the key is released
interval_msnumber?0Interval in ms between during_pressed_callback calls. 0 means every frame

Returns NssLibsPromptsPromptApi

lua
local KEY_E = 0xCEFD9220

group.addDuringPressedPrompt('Fill', KEY_E, function()
    progress = progress + 1
end, {
    on_press = function()
        progress = 0
        print('Started filling')
    end,
    on_release = function()
        print('Stopped filling at ' .. tostring(progress))
    end,
})
lua
group.addDuringPressedPrompt('Reel In', KEY_E, function()
    reel_in_one_step()
end, {
    interval_ms = 200, 
    on_press = function()
        start_fishing_animation()
    end,
    on_release = function()
        stop_fishing_animation()
    end,
})

.setLabel(label) ​

Sets the label of the group.

ParamTypeDefaultDescription
labelstring—The label of the group

.show() ​

Shows the group.

If multiple groups are shown at the same time then pages/tabs are created automatically. The group that appeared last is the open page (since 0.37.10).

Idempotent since 0.37.11: calling it on a group that is already on screen does nothing. You do not need a latch around it.

.hide() ​

Hides the group. Idempotent since 0.37.11.

Prefer declaring over switching (since 0.37.11)

Every group that a resource switches by hand needs a path back to hide() for every way the situation can end (player dies, mounts up, gets teleported, the server never answers). Most of the stuck prompt pages on this server came from a missing path. Declare instead: linkTo* for the place, showWhile for the state, and the library takes the group off the screen by itself.

.showWhile(predicate, interval_ms?) ​

Shows the group while predicate() returns true, hides it otherwise. One thread polls every declared condition of every resource. The predicate has to answer at once: an error counts as false, and so does a predicate that waits (Citizen.Wait, a server round trip) instead of returning, both are reported, once per 30 seconds and predicate (0.37.17). A waiting predicate used to hang the thread of every condition of every resource.

Only true and 1 count as yes. A 0 from a native is false here, unlike in plain Lua.

Combines with the place linkers: with a linkToCoords/linkToEntity/linkToEntityModels on the same group the group is on screen only when the player is at the place and the predicate says yes.

Active right away, no activate() needed. One condition per group; a second call replaces the first.

ParamTypeDefaultDescription
predicatefunction—Returns true while the group should be visible
interval_msnumber?Config.Prompts.CONDITION_INTERVAL_IN_MS (250)Poll interval

Returns NssLibsPromptsLinkerGroupToCoordsApi (deactivate, activate, destroy)

lua
-- Lantern prompts: only while the lantern is in the hand, nothing to hide by hand.
local group = prompts_api.createGroup('Lantern')
group.addStandardHoldPrompt('Adjust light', 'R', function() ... end)

group.showWhile(function()
    local _, weapon = GetCurrentPedWeapon(PlayerPedId(), true)
    return weapon == `WEAPON_MELEE_LANTERN`
end)

-- Place AND state: at the still, and only with the job.
local still = prompts_api.createGroup('Still')
still.addJustPressedPrompt('Distill', 'E', function() ... end)
still.linkToEntityModels({ 'p_still01x' }, 1.5).activate()
still.showWhile(function() return LocalPlayer.state.Character.Job == 'moonshiner' end)

.disableUntilReleased(timeout_ms?) ​

Greys out every prompt of the group and returns a release function. Call it when the answer you were waiting for arrived. If nobody calls it within timeout_ms (default Config.Prompts.DISABLE_UNTIL_RELEASED_DEFAULT_MS, 10 s), the prompts are enabled again and a warning is printed, so a server that never answers cannot leave the group grey for the rest of the session. Only prompts that were enabled before are enabled again.

lua
local release = group.disableUntilReleased(5000)
TriggerServerEvent('my_resource:buy', item)

RegisterNetEvent('my_resource:bought', function()
    release()
end)

.isShowing() ​

Returns boolean — true if the group is on screen.

.destroy() ​

Destroys the group and all its prompts. This group is never usable again.

.showOnDeath() ​

Shows the group during the player is dead, too.

Reach is flat, height is separate (since 0.37.7)

Every linkTo* radius is measured in x/y only. The height difference between the player's centre (about a metre above the feet) and the target is checked on its own against height_tolerance, default NssLibsPromptsLinker.DEFAULT_HEIGHT_TOLERANCE (3.0 m). A 3D radius of 1.5 m used to leave about 1.1 m of flat reach beside a water pump. Pass a smaller tolerance where floors matter.

.linkToCoords(x, y, z, radius, height_tolerance?) ​

Add logic to show/hide prompt group if player reaches radius of given coords.

A group has one place (0.37.17): linkToCoords, linkToEntity, linkToEntityModels and linkToPlayer share it, the last call wins and destroys the previous link, with a warning. Two places on one group used to fight over the same declaration and the group vanished while the player stood at one of them.

ParamTypeDefaultDescription
xnumber—The x coordinate of the coords
ynumber—The y coordinate of the coords
znumber—The z coordinate of the coords
radiusnumber—The flat (x/y) reach around the coords
height_tolerancenumber?3.0Allowed height difference in meters

The linker's location chunk checks every 250 ms while the player stands in a grid cell that holds linked locations, and once a second everywhere else.

Returns NssLibsPromptsLinkerGroupToCoordsApi

lua
---@type NssLibsPromptsApi
local prompts_api = exports.nss_libs:getPromptsApi(GetCurrentResourceName())

---@type NssLibsPromptsGroupApi
local group = prompts_api.createGroup('GROUP_LABEL')

local SPACEBAR = 0xD9D0E1C0

---@type NssLibsPromptsPromptApi
local prompt_spacebar = group.addJustPressedPrompt('PROMPT_LABEL', SPACEBAR, function()
    print('Spacebar just pressed')
end)

local x, y, z, radius = 0.0, 0.0, 0.0, 2.0

---@type NssLibsPromptsLinkerGroupToCoordsApi
local linker_api = group.linkToCoords(x, y, z, radius)

linker_api.activate()

.linkToEntity(entity_id, radius, inject_entity_id_cb?, height_tolerance?) ​

Add logic to show/hide prompt group if player reaches radius of given entity.

ParamTypeDefaultDescription
entity_idnumber—The entity id of the entity
radiusnumber—The flat (x/y) reach around the entity origin
inject_entity_id_cbfunction?—A callback that injects/returns the entity id each time the script checks the distance
height_tolerancenumber?3.0Allowed height difference in meters

Links inside reach plus 5 m are checked every 100 ms, all others once a second.

Returns NssLibsPromptsLinkerGroupToCoordsApi

lua
---@type NssLibsPromptsApi
local prompts_api = exports.nss_libs:getPromptsApi(GetCurrentResourceName())

---@type NssLibsPromptsGroupApi
local group = prompts_api.createGroup('GROUP_LABEL')

local SPACEBAR = 0xD9D0E1C0

---@type NssLibsPromptsPromptApi
local prompt_spacebar = group.addJustPressedPrompt('PROMPT_LABEL', SPACEBAR, function()
    print('Spacebar just pressed')
end)

local entity_id = 12 -- Example entity
local radius = 2.0

-- Optional callback
-- Sometimes entity ids changes because entity was out of sight,
-- so this callback injects the current entity id.
local inject_entity_id_cb = function()
    return 14 -- Example of changed entity id
end

---@type NssLibsPromptsLinkerGroupToCoordsApi
local linker_api = group.linkToEntity(entity_id, radius, inject_entity_id_cb)

linker_api.activate()

.linkToEntityModels(model_names_or_hashes, radius, height_tolerance?) ​

Add logic to show/hide prompt group if player reaches radius of given entity.

ParamTypeDefaultDescription
model_names_or_hashesnumber|string|table<string|number>—The model name(s) or hash(es) of the entity/entities
radiusnumber—The flat (x/y) reach around the entity origin
height_tolerancenumber?3.0Allowed height difference in meters

Backed by an EntityInRange listener, see that module for the tick and the approach margin.

Returns NssLibsPromptsLinkerGroupToCoordsApi

lua
---@type NssLibsPromptsApi
local prompts_api = exports.nss_libs:getPromptsApi(GetCurrentResourceName())

---@type NssLibsPromptsGroupApi
local group = prompts_api.createGroup('GROUP_LABEL')

local SPACEBAR = 0xD9D0E1C0

---@type NssLibsPromptsPromptApi
local prompt_spacebar = group.addJustPressedPrompt('PROMPT_LABEL', SPACEBAR, function()
    print('Spacebar just pressed')
end)

local entity_herbs_model_hashes = { 477619010, 85102137, -1707502213 } -- Some bushes
local radius = 2.0

---@type NssLibsPromptsLinkerGroupToCoordsApi
local linker_api = group.linkToEntityModels(entity_herbs_model_hashes, radius)

linker_api.activate()

.linkToPlayer(player_server_id, radius, height_tolerance?) (not working currently) ​

Add logic to show/hide prompt group if player reaches radius of given player.

ParamTypeDefaultDescription
player_server_idnumber—The server id of the player
radiusnumber—The flat (x/y) reach around the player
height_tolerancenumber?3.0Allowed height difference in meters

Returns NssLibsPromptsLinkerGroupToCoordsApi

.disable() / .enable() ​

Disables/enables all prompts of the group.

Returns NssLibsPromptsGroupApi

.allowOnMount() / .forbidOnMount() ​

Allows/forbids all prompts of the group to be shown while player is mounted.

WARNING

This affects only existing prompts during the call. If you add new prompts after the call then the new prompts are not affected by this call.

Returns NssLibsPromptsGroupApi

.allowInWater() / .forbidInWater() ​

Allows/forbids all prompts of the group to be shown while player is in water.

WARNING

This affects only existing prompts during the call. If you add new prompts after the call then the new prompts are not affected by this call.

Returns NssLibsPromptsGroupApi

.allowInVehicle() / .forbidInVehicle() ​

Allows/forbids all prompts of the group to be shown while player is in vehicle.

WARNING

This affects only existing prompts during the call. If you add new prompts after the call then the new prompts are not affected by this call.

Returns NssLibsPromptsGroupApi

.allowOnFloor() / .forbidOnFloor() ​

Allows/forbids all prompts of the group to be shown while player is on floor.

WARNING

This affects only existing prompts during the call. If you add new prompts after the call then the new prompts are not affected by this call.

Returns NssLibsPromptsGroupApi

.allowInAir() / .forbidInAir() ​

Allows/forbids all prompts of the group to be shown while player is in air.

WARNING

This affects only existing prompts during the call. If you add new prompts after the call then the new prompts are not affected by this call.

Returns NssLibsPromptsGroupApi

.allowDuringDeath() / .forbidDuringDeath() ​

Allows/forbids all prompts of the group to be shown while player is dead.

WARNING

This affects only existing prompts during the call. If you add new prompts after the call then the new prompts are not affected by this call.

Returns NssLibsPromptsGroupApi

.allowDuringMovement() / .forbidDuringMovement() ​

Allows/forbids all prompts of the group to be shown while player is moving.

WARNING

This affects only existing prompts during the call. If you add new prompts after the call then the new prompts are not affected by this call.

Returns NssLibsPromptsGroupApi

.setMovementDetectionSensitivity(sensitivity_in_meters) ​

  • New since version 0.29.0
ParamTypeDefaultDescription
sensitivity_in_metersfloat0.005The sensitivity in meters for movement measuring

TIP

The sensitivity is measured in all axis (x, y, z). So if the player stands in water or floats in the water then it is possible that a movement is detected if the player goes up and down by the waves of the water. In this case set the sensitivity to a higher value.

WARNING

This affects all current and future prompts of the group.

Returns NssLibsPromptsGroupApi

lua
group.forbidDuringMovement() -- Enables the prompts only on stand still
group.setMovementDetectionSensitivity(0.5) -- Set sensitivity to 0.5 meters

.allowDuringHogtied() / .forbidDuringHogtied() ​

Allows/forbids all prompts of the group to be shown while player is hogtied.

WARNING

This affects only existing prompts during the call. If you add new prompts after the call then the new prompts are not affected by this call.

Returns NssLibsPromptsGroupApi

.setAllPromptsToStandardRestrictionsOnFoot() ​

Set standard restrictions for all prompts of the group while player is on foot.

WARNING

This affects only existing prompts during the call. If you add new prompts after the call then the new prompts are not affected by this call.

Returns NssLibsPromptsGroupApi

.showOnMovement() / .hideOnMovement() ​

  • New since version 0.30.0

Show (default) / hides the group if it is usually visible and the player moves.

TIP

This affects all current and future prompts of the group.

Returns NssLibsPromptsGroupApi

.isHideOnMovement() ​

  • New since version 0.30.0

Returns boolean — true if the group should be hidden if it is usually visible but the player moves.


NssLibsPromptsPromptApi ​

.addKey(key, callback, release_callback?) ​

Adds additional key to the prompt.

ParamTypeDefaultDescription
keynumber|string—The key of the prompt (see key names and hashes or named keys)
callbackfunction—The callback of the prompt
release_callbackfunction?—If set then callback fires on press and release_callback fires on release. Works only for specific prompt types

WARNING

If you use multiple keys per prompt then hold/hold complete modes are not supported.

Returns NssLibsPromptsPromptApi

.setLabel(label) ​

Sets the label of the prompt.

ParamTypeDefaultDescription
labelstring—The label of the prompt

Returns NssLibsPromptsPromptApi

.enable() ​

Enables the prompt. This is the default state.

Returns NssLibsPromptsPromptApi

.disable() ​

Disables the prompt.

Returns NssLibsPromptsPromptApi

.show() ​

Shows the prompt. This is the default state.

Returns NssLibsPromptsPromptApi

.hide() ​

Hides the prompt. Since 0.37.11 a hidden prompt never fires, so hide() alone is enough; before, a hidden but enabled prompt still reacted to its key.

.setHoldTime(hold_time_ms) ​

StandardHold prompts only: the hold time handed to the game, see addStandardHoldPrompt. nil restores the library default. Takes effect immediately if the prompt is on screen (the group re-registers it).

Returns NssLibsPromptsPromptApi

.destroy() ​

Destroys the prompt. This prompt is never usable again.

.consumeGroupFrame(consume) ​

Controls whether this prompt "consumes" the group frame when fulfilled. If true (default), no other prompts in the group are checked after this prompt fires. If false, other prompts in the same group can also fire in the same frame.

ParamTypeDefaultDescription
consumebooleantruetrue to consume, false to allow other prompts to fire

Returns NssLibsPromptsPromptApi

lua
-- Allow multiple prompts to fire in the same frame
prompt_a.consumeGroupFrame(false)
prompt_b.consumeGroupFrame(false)

.executeCallbackInThread(execute_in_thread) ​

Controls whether the prompt callback runs in a new Citizen.CreateThread (default) or synchronously in the current frame. Synchronous execution avoids the one-frame delay but blocks the main loop during callback execution.

ParamTypeDefaultDescription
execute_in_threadbooleantruetrue for threaded, false for synchronous

Returns NssLibsPromptsPromptApi

lua
-- Run callback synchronously (no frame delay)
prompt.executeCallbackInThread(false)

.allowOnMount() / .forbidOnMount() ​

Allows/forbids the prompt to be shown while player is mounted.

Returns NssLibsPromptsPromptApi

.allowInWater() / .forbidInWater() ​

Allows/forbids the prompt to be shown while player is in water.

Returns NssLibsPromptsPromptApi

.allowInVehicle() / .forbidInVehicle() ​

Allows/forbids the prompt to be shown while player is in vehicle.

Returns NssLibsPromptsPromptApi

.allowOnFloor() / .forbidOnFloor() ​

Allows/forbids the prompt to be shown while player is on floor.

Returns NssLibsPromptsPromptApi

.allowInAir() / .forbidInAir() ​

Allows/forbids the prompt to be shown while player is in air.

Returns NssLibsPromptsPromptApi

.allowDuringDeath() / .forbidDuringDeath() ​

Allows/forbids the prompt to be shown while player is dead.

Returns NssLibsPromptsPromptApi

.allowDuringMovement() / .forbidDuringMovement() ​

Allows/forbids the prompt to be shown while player is moving.

Returns NssLibsPromptsPromptApi

.allowDuringHogtied() / .forbidDuringHogtied() ​

Allows/forbids the prompt to be shown while player is hogtied.

Returns NssLibsPromptsPromptApi


NssLibsPromptsLinkerGroupToCoordsApi ​

.activate() ​

Activates the linker.

Returns NssLibsPromptsLinkerGroupToCoordsApi

.deactivate() ​

Deactivates the linker. This is the default state.

Returns NssLibsPromptsLinkerGroupToCoordsApi

.isActive() ​

Returns boolean — true if the linker is active.

.destroy() ​

Destroy (removes) the link between group and coords.


Named keys ​

Instead of key hashes you can use key names since version v0.26.1 of nss_libs. The following key names are available:

  • All alphabetical characters except K, Y, Ü, Ö, Ä, and ß (N and T since 0.37.11)
  • 1, 2, 3, 4, 5, 6, 7, 8
  • RIGHTBRACKET, LEFTBRACKET
  • MOUSE1, MOUSE2, MOUSE3, MWUP
  • CTRL, TAB, SHIFT, LALT
  • SPACEBAR, ENTER, BACKSPACE, DEL
  • PGUP, PGDN
  • F1, F4, F6
  • DOWN, UP, LEFT, RIGHT

TIP

Sometimes keys not working as expected. This is a limitation of the game. In other cases the keys are used by other resources.


Dev notes

UiPromptHasHoldModeCompleted is currently tricky. It fires during the hold mode is fulfilled. But this is not so good if we have to check if the hold mode is fulfilled and when it was released after hold. So two callbacks, one for "hold started" and one for "hold stopped", are good.


NIGHTSHIFT STUDIO Documentation