by Avenida Team ESX · QBCore · ox · vRP · Standalone

Interact system

3D interaction system + NPC dialogue engine, with zero dependency. Place an interaction anywhere on the map: on an entity, a free coordinate, or an NPC you spawn from the same call. No ox_lib, no framework, no server side setup.

Delivery Instant
Updates Free for life
Support Daily on Discord
01 · FEATURES

What it does

02 · SPECS

Technical
specifications

Framework All, auto-detected ESX · QBCore · Qbox · ox · vRP · Standalone · Custom
Dependencies None ox_lib optional, off by default
In-game locales 15 included ar · cs · de · en · es · fr · id · it · nl · pl · pt-br · ro · ru · th · tr
Source Tebex Escrow Configs and bridges open in production
Performance 0.00ms idle Measured with 100 interactions
03 · INCLUDED

Everything you
get

  • Fifteen locale files, shipped filled

    Your players read the script in their own language from the first start, and the files sit outside escrow so you can edit any line in production. Honest note: they are translated and reviewed by us, not proofread by native speakers of all fifteen. Tell us what reads wrong in yours and it gets fixed.

  • Everything tunable in config.lua

    Default label, key, distances, icon and color of a point, named colors, the key label to control index map, the ped used when an entry omits one, spawn range, and which HUD is hidden during a dialogue. All of it left escrow in 1.1.0.

  • Three working examples

    An ATM watcher registered by model hash with a two-key menu, an NPC with a full branching dialogue and a GPS waypoint, and a multi-bind dance point. Real files in `config/`, delete them once you have your own.

  • Discord support and lifetime updates

    Access to the support channel, and every future update at no extra cost. No premium tier, no paid add-on.

04 · DOCUMENTATION

Integration guide

01

Installation

  1. Drop the resource

    Grab the script from your Tebex account, then copy the avenida_interact/ folder into resources/[avenida]/ on your server.

  2. Enable in server.cfg

    Add ensure avenida_interact. Nothing has to load before it: since 1.1.0 the resource has no dependency, so load order does not matter.

  3. Set your defaults

    Open config/config.lua and tune what applies to every point: label, key, showIcon and canInteract distances, icon, color, named colors, ped spawn range, and Config.Hud to pick which HUD is hidden during a dialogue.

  4. Remove the demos

    The examples in config/entities/, config/peds/ and config/positions/ are live as long as their files are there. Delete the ones you do not want, the manifest globs those folders so there is nothing else to edit.

  5. Test the hot reload

    Start the server, then type /restart avenida_interact in game. Icons disappear and come back cleanly, and points registered by your own resources survive, without restarting your session.

02

Quickstart

Your first interaction point in 30 seconds

Create a `myscript/client.lua` in your own resource and paste this. A cyan marker appears at 30m, the "E - Hello" prompt unrolls at 2m. The only thing that has to be running is avenida_interact itself.

lua
-- myscript/client.lua
exports.avenida_interact:positionRegister({
    coords      = vec3(-265.0, -963.6, 31.2),
    showIcon    = 30.0,           -- marker fades in at 30m
    canInteract = 2.0,            -- label unrolls at 2m
    hintIcon    = 'interact',     -- see the icon list below
    hintColor   = '#22d3ee',      -- hex, or an alias from Config.Colors
    message     = 'Hello',
    bind        = 'E',
    onInteract  = function()
        TriggerEvent('chat:addMessage', { args = { 'Hello, world!' } })
    end,
})
03

API Reference

Public exports grouped by domain. Each row shows the call signature and what it does, not how it does it.

Interact Points

  • positionRegister
    exports.avenida_interact:positionRegister(cfg) --> id

    Registers a point on fixed coordinates. Takes every visual field (hintIcon, hintColor, showIcon, canInteract, offsetZ, blips) plus choices[] for several keys on the same point. canInteract accepts a number or a function, so you can gate the prompt on a job, an item or a cooldown. Returns an id.

  • pedRegister
    exports.avenida_interact:pedRegister(cfg) --> id

    Spawns a configured NPC (model, animDict and animName or a scenario, blip), attaches a point on it and returns its index. The ped is invincible, will not flee and will not ragdoll. It spawns and despawns around Config.PedSpawnRange, 50m by default. Set randomComponents = false on a named vendor, otherwise every player sees a different outfit.

  • pedRemove
    exports.avenida_interact:pedRemove(idx)

    Added in 1.1.0. Despawns a ped registered with pedRegister and drops its registration, so a temporary quest giver can leave when the quest is over.

  • entityRegister
    exports.avenida_interact:entityRegister(cfg) --> id

    Attaches a point onto one existing entity, passed as cfg.entity. Supports cfg.bone to hook the prompt on a bone instead of the entity center. Use it for something another script spawned: a vehicle, a placed prop, a dropped item.

  • entityRegisterByHash
    exports.avenida_interact:entityRegisterByHash(hash, cfg)

    Passive watcher: the config applies to every entity of that model, the ones already streamed and the ones that appear later. A single thread covers all registered hashes and sweeps every 5s. This is what you want for ATMs, vending machines and doors, rather than a coordinate list to maintain.

  • entityRemove
    exports.avenida_interact:entityRemove(idx)

    Detaches the point returned by entityRegister. The entity itself is left alone.

  • interactCreate
    exports.avenida_interact:interactCreate(cfg) --> id

    Runtime point, created and removed on demand. Use it when the point only exists for a while: a mission objective, a bag on the ground, a body to search.

  • interactRemove
    exports.avenida_interact:interactRemove(id)

    Removes a point created by interactCreate, and its blip if it declared one.

  • unlockLastInteract
    exports.avenida_interact:unlockLastInteract()

    A point locks itself once used, so a held key does not fire it twice. Call this at the end of your action to re-arm it. If the player is still in range the prompt comes straight back, otherwise it waits for them to walk in again.

Prompt API

  • HandleTextUI
    exports.avenida_interact:HandleTextUI(id, data) --> duiHandler

    Creates or updates a standalone 3D bubble, without any interaction point behind it. For when you want to drive visibility from your own thread. Returns the handler you pass to Draw3DSprite.

  • Draw3DSprite
    exports.avenida_interact:Draw3DSprite({ duiHandler, coords, maxDistance, hintOnly? })

    Draws the bubble in world space from a render thread, un-stretched against the screen aspect. With hintOnly = true only the marker is drawn, which is the long distance state of a normal point.

  • CloseTextUI
    exports.avenida_interact:CloseTextUI(id)

    Hides a bubble but keeps its DUI in memory, so reopening is instant.

  • RemoveTextUI
    exports.avenida_interact:RemoveTextUI(id)

    Removes a bubble for good and frees its DUI. Use it when you know it will not come back.

  • RemoveTextUIs
    exports.avenida_interact:RemoveTextUIs()

    Removes every active bubble. Called for you when the resource stops.

  • IsDuiVisible
    exports.avenida_interact:IsDuiVisible() --> boolean

    True while a prompt is on screen. Read it to keep your own prompts from stacking on top of an interaction.

Key handler

  • HandleHoldTextUI
    exports.avenida_interact:HandleHoldTextUI(id, data) --> duiHandler

    The layer the points are built on: it draws a prompt at Coords and watches its key from a 50ms manager thread. data takes BindToHold (control index), DistanceHold, Coords, ChoicesUI and ChoicesCtrl for a multi-key prompt, onCallback(id) and canInteract(id, dist). It fires on press with a 500ms debounce, and your callback runs in a pcall so an error on your side does not break the prompt.

  • CloseHoldTextUI
    exports.avenida_interact:CloseHoldTextUI(id)

    Hides the prompt without destroying the instance, for a clean exit when the player leaves the zone.

  • RemoveHoldTextUI
    exports.avenida_interact:RemoveHoldTextUI(id)

    Destroys one instance and frees its DUI.

  • RemoveHoldTextUIs
    exports.avenida_interact:RemoveHoldTextUIs()

    Destroys every active instance.

04

Recipes

Real-world copy-paste examples. Drop them into your own resource, tweak the values, ship.

The simplest case: a point on coordinates, with its blip declared in the same table. The marker shows at 30m, the label at 2m. Drop this in any client file of your own resource.

lua
exports.avenida_interact:positionRegister({
    coords      = vec3(149.5, -1040.4, 29.4),
    showIcon    = 30.0,
    canInteract = 2.0,
    hintIcon    = 'bank',
    hintColor   = 'blue',
    message     = 'Use the ATM',
    bind        = 'E',
    onInteract  = function()
        TriggerEvent('myserver-banking:openATM')
    end,
    blips = {
        sprite  = 277,
        color   = 2,
        scale   = 0.8,
        text    = 'ATM',
        display = 4,
    },
})
05

Troubleshooting

  • You do not. Since 1.1.0 `bridges/compat.lua` implements DUI creation, proximity points and the wait helpers on plain natives, and the `@ox_lib/init.lua` line is commented out in the manifest. If you would rather route that through ox_lib, set `Config.UseOxLib = true` and uncomment that line. Both paths are supported, the native one is the default.
REVIEWS

What buyers say

5.0 2 verified reviews

  • Revoria

    very good scriptwriters a reactive and competent listening team I recommend go there with your eyes closed!!

    View on Discord ↗
  • theara

    Best script, best support! Fast support and friendly!

    View on Discord ↗
Cart
Spirit RP
Discord