Skip to main content
Every add* export - addPoint, addSphere, addBox, addEntity, addModel, and the addGlobal* family - accepts the same data table: a handful of anchor-level fields plus an options array. This page is the reference for both. The geometry each export adds on top (coords, radius, size, entity, bone…) is documented with that export. Every export returns an anchor id on success, removable with exports.lation_interact:remove(id). An invalid spec prints a console error explaining what’s wrong and returns nil - the anchor is not registered.

Anchor Fields

string
What the anchor is called - the text that grows out of the grain at name range. Optional, and its presence decides the anatomy the component renders:
  • Titled - the label names the thing ('Cash Register'); options unfold beneath a header.
  • Chip - no label (or it just repeats the only option’s label) and a single option: renders as one actionable chip - label plus keycap, no unfold.
  • Headerless list - no label with multiple options: the first option is the header line, and the rest grow beneath it.
When given, label must be a non-empty string.
table
required
Array of option tables - see Option Fields below. At least one is required.
string
Explicit color for the header icon (any CSS color, e.g. '#8be9fd'). Without it, header icons are light - or the theme accent when Config.AccentIcons is on
string
FontAwesome solid icon name for the anchor itself (e.g. 'cash-register'). When omitted, a headerless anchor wears its promoted option’s icon; with no icon anywhere, the default dot.
table
Per-anchor distance overrides, in meters: { grain = ..., name = ..., reach = ... }. Defaults come from Config.Stages (8.0 / 4.5 / 2.4); any subset can be overridden.
Sphere and box zones derive their own stages from their size - reach is being inside the zone - unless you override them here. See How It Works.
string
default:"Config.ExpandMode"
How the stack opens once you’re in reach: 'auto' (always unfolds on its own), 'manual' (always waits for the confirm key), or 'smart' (single-option anchors unfold, multi-option anchors wait). The config default is 'smart' - see how lists open.
string
What renders before the anchor is focused: 'ambient' (a grain of light marks it from grain range) or 'focus' (nothing renders until attention lands on it). Points and zones default to 'ambient', entity, model, and global anchors to 'focus' (Config.Reveal) - see reveal modes.
boolean
default:"false"
Draw the physical interaction shape in-world: zones draw their volume, points and entity anchors the reach sphere at the anchor. Points and zones draw at any distance while the flag is set; entity anchors draw whenever their entity is around.
boolean
Hidden until the interact control is held - no grain, no label, no input - like a classic target. Defaults to Config.Passive, or true when the registering resource is listed in Config.PassiveResources. See passive mode.
boolean
Whether this anchor stays live while the player sits in a vehicle. Unset, it follows Config.InVehicle (entity anchors hide, points and zones stay). See in a vehicle.

Option Fields

Each entry in options describes one row of the stack.
string
required
The row’s text.
string
FontAwesome solid icon name for the row (e.g. 'credit-card').
string
Explicit color for this option’s row icon; overrides the theme’s icon color
string
Keyboard key that activates this option directly, by name: letters and digits ('E', 'T', '5'), F1-F24, NUMPAD0-NUMPAD9, and named keys like 'SPACE'. Case-insensitive. Omit to make the option cursor-only: it’s reached with the confirm key while highlighted, or with Left Alt + click in cursor mode.Option keys are live only while the stack is open - a closed stack opens on the confirm key alone, and while open, the game action sharing a bound key’s default bind is suppressed so one press never does both.
A key name that doesn’t exist fails validation - the whole registration is rejected with a console error.
number
default:"0"
Milliseconds the key (or mouse button) must be held - a ring fills while held and the option fires when it completes; releasing early cancels. Omit or 0 for instant activation.
boolean
default:"false"
Keep the list open after selecting this option, for repeatable actions. By default a manual stack folds back to the pill after a selection.
boolean
default:"false"
Keeps this option’s anchor live from inside a vehicle when Config.InVehicle would hide it - the flag vehicle-aware scripts set on drive-thru style options. Honored on bridged ox_target / qb-target options too.
any
Passed through untouched to the handler payload as data.args.

Condition Gates

Four per-option gates decide whether a row is visible to this player right now. An anchor whose every option is gated away disappears entirely - no grain, no focus - for players who can’t use any of it. Gates are evaluated off the frame path on a dedicated eval thread - every 50ms while the anchor is focused and roughly 5x/s while merely nearby. A slow canInteract - or one that waits inside - only delays its own anchor’s rows; the element keeps gliding and input stays live.
string | string[] | table
Framework group gate - matches jobs and gangs alike, whatever the framework reports as the player’s groups:
  • 'police' - the player has this group
  • { 'police', 'sheriff' } - the player has any of these
  • { police = 2 } - any listed group, at that minimum grade
Custom setups can adapt the group lookup in bridge/client.lua - it’s open code, made to be edited.
string | string[] | table
Inventory gate:
  • 'lockpick' - the player carries this item
  • { 'lockpick', 'screwdriver' } - the player carries all of these
  • { lockpick = 2 } - at those minimum counts
Supported inventories are detected automatically; custom setups can adapt the item lookup in bridge/client.lua.
string | table
Entity statebag gate:
  • 'trunkLocked' - visible while Entity(entity).state.trunkLocked is truthy
  • { key = 'trunkLocked', value = false } - visible while the statebag equals value
Statebags live on entities, so state only works on entity, model, and global anchors. On points and zones the option prints a warning and stays hidden.
function
Arbitrary predicate - return true to show the row. Receives one table:
Evaluated off the frame path, never per render frame - it’s safe to call exports or even wait inside, at the cost of your own rows updating later.
canInteract is not re-run at activation - whatever row is rendered can be selected. If an action must be re-validated at the moment it fires, validate in the handler (or server-side).

Handlers

When an option activates, its handlers fire - any combination of the three, in this order:
function
Called with the payload table below.
string
Client event triggered with the payload table.
string
Server event triggered with the payload table minus entity - entity handles are client-local, so the server receives id, index, args, netId, and coords.
All three receive the same payload:
Handlers dispatch from a spawned thread, so they can freely await - open an inventory, hit a server callback - without ever stalling the frame loop.

Full Example

A trunk anchor on a spawned mission vehicle, exercising most of the vocabulary - the statebag is set server-side when the vehicle spawns (Entity(vehicle).state:set('trunkLocked', true, true)):
While the trunk is locked, a passerby with no lockpick sees nothing at all - every option is gated, so the anchor is invisible to them. A player carrying a lockpick sees one row; an on-duty sergeant standing by an empty vehicle sees two. Once the statebag flips to false, Open Trunk appears for everyone and the lockpick row retires itself.