Skip to main content
A point is the simplest anchor: a stack of options pinned to a world coordinate. Register one with addPoint, keep the returned id if you ever want to remove it, and the layer handles the rest - the reveal stages, focus, and input all come for free. Everything a resource registers is cleaned up automatically when that resource stops.
Points are indexed in a spatial grid, and the frame loop only ever looks at the player’s neighborhood - so thousands of registered points cost nothing at idle. Register your whole map up front; there’s no need to create and destroy points as players move around.

Quick Start

Walking up to it: a grain of light marks the point from 8.0m, the label grows out of the grain at 4.5m, and within 2.4m the stack is live. The defaults come from Config.Stages and can be overridden per point with stages - see How It Works for the full attention model.

Functions

Register a static interaction point.
Parameters:Returns:
  • id (number) - The point’s anchor id, for remove - or nil if the data was invalid (the reason is printed to the client console)
Remove an anchor by id. removePoint is an alias - both accept the id returned by any add* export, whatever its kind.
Parameters:
  • id (number) - The id returned at registration
Manual removal is only needed for points that stop making sense mid-session. Everything your resource registered is removed automatically when it stops or restarts.

Configuration

Point Options

vector3
required
World position of the point. A vector4 or a plain { x, y, z } table (JSON, database rows) is accepted too
string
Header line of the stack
Optional - without one (or when it just repeats the first option’s label) the stack renders headerless: the header line is the first option. Ideal for single-action points.
string
FontAwesome solid icon name for the anchor (e.g. 'credit-card') - omit for the default dot
table
required
Array of one or more option tables (see Option Fields)
table
Per-point overrides of the reveal distances, in meters: { grain = 8.0, name = 4.5, reach = 2.4 }Any key you omit keeps its Config.Stages default
string
default:"smart"
How the stack opens once the player is in reachAvailable options: 'smart', 'auto', 'manual''smart' unfolds single-option points on their own and holds multi-option points as a pill until the confirm key opens the list; 'auto' always unfolds; 'manual' always waits for the confirm key. The default comes from Config.ExpandMode
string
default:"ambient"
What renders before the point is focusedAvailable options: 'ambient', 'focus''ambient' marks the point with a grain of light from the grain stage onward; 'focus' renders nothing until attention lands on it. Points default to 'ambient' (Config.Reveal.point)
boolean
default:"false"
Draw the point’s reach sphere in-world, at any distance - useful while placing coordinates
boolean
Hidden until the interact control is held - see passive mode. Defaults to Config.Passive, or true when your resource is listed in Config.PassiveResources
boolean
Whether the point stays live while the player sits in a vehicle. Unset, it follows Config.InVehicle.points (true)

Option Fields

Each entry in options describes one row of the stack:
string
required
Row label
string
FontAwesome solid icon name (e.g. 'money-bill')
string
Keyboard key this option binds to, by name ('E', 'T', '5', 'F2', 'SPACE', …) - pressing it while the stack is open activates the option directly
Omit to leave the option unbound: the confirm key (E by default) activates it while it’s the highlighted row, and the cursor (hold Left Alt and click - then hover, click) reaches it anywhere in the list. Binding a key name that doesn’t exist fails the registration with a console error.
number
Milliseconds the key 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 (repeatable actions) - 'manual' lists fold back to the pill after a selection by default
string | string[] | table
Job/gang gate: 'police', { 'police', 'sheriff' } (any of), or { police = 2 } (any of, at that minimum grade)Matches whatever your framework reports as the player’s groups - jobs and gangs alike. Custom setups can adapt the check in bridge/client.lua
string | string[] | table
Inventory gate: 'lockpick', { 'lockpick', 'screwdriver' } (all of), or { lockpick = 2 } (required counts)Supported inventories are detected automatically; custom setups can adapt the check in bridge/client.lua
function
Predicate deciding whether the row is currently visible - return true to show it:
Evaluated off the frame path on a dedicated thread every 50ms while the point is focused (and about 5x/s while merely nearby) - a slow predicate only delays its own rows, never the element or input. It is not re-run at activation
function
Handler called when the option activates, with a single payload table:
Handlers dispatch from their own thread, so it’s safe to Wait, open UIs, or await server callbacks inside
string
Client event triggered on activation with the same payload table as onSelect
string
Server event triggered on activation with { id, index, args, netId, coords } (netId is nil for points)
any
Passed through to canInteract and every handler
onSelect, event, and serverEvent are not exclusive - an option may set any combination, and all of them fire.
The state statebag gate applies to entity anchors only. A point has no statebag, so a state-gated option on a point prints a warning at registration and stays hidden.

Gated Options and Visibility

Rows gated by groups, items, or canInteract simply don’t render for players who fail the gate - the stack shows only what the player can actually use. If every option on a point is gated away, the point disappears entirely: no grain, no focus, nothing to see.
A grade-2 officer sees the first row, a burglar carrying a lockpick sees the second, and everyone else walks past a locker that never lights up.