INSTALLATION GUIDE

Installing Interactions

Quick install — the short version

Everything below, without the walkthrough. Scroll past it if this is your first time.

Or let the page write the line for you

Paste one of the three files below. The patched version comes back with the block already in the right place, correctly indented, ready to save over the original.

NOTHING LEAVES YOUR BROWSER — CHECK THE NETWORK TAB
RECOGNISED FILES ox_lib / resource / interface / client / textui.lua ak47_target / client / main.lua ox_target / client / main.lua qb-target / client.lua
OR PASTE IT
Waiting for a file.

When something does not work

The things that actually go wrong, and what each one means.

A prompt appears and never goes away
The ox_lib patch is half applied — the show line is in, the hide line is not. Both go in the same file, in two different functions. Your server console says this in as many words: ox_lib text UI is HALF installed (1 of 2 lines found). Add the second line from the block above.
Prompts appear twice — ours and the original
Another prompt or text-UI script is patched into the same place. Only one thing can own the render. Remove the other script’s patch, or set the matching Config.Intercept… to false so we stay out of its way.
Nothing appears at all
Three causes, in the order worth checking:
  • The block is in the wrong file. It has to go in the file that defines the function, not one that calls it.
  • Interactions starts before ox_lib or your target system. Move ensure dispersia_interactions below them in server.cfg.
  • That interceptor is switched off in open/config.lua.
Run /interactions_test in game. It draws three sample rows first, so you can see the panel itself is alive, then reports every integration point — read from the real file on the server, not guessed from what the prompt looks like.
Can it replace my target system's option list?
Partly, and honestly: not yet in a way we would tell you to switch on. We can draw the list. We cannot yet own the click — selecting an option happens inside the target system's own NUI. Suppress its list and the player can aim but has nothing left to click.

So Config.InterceptAk47, InterceptOxTarget and InterceptQbTarget ship false. The blocks are documented and the code is there; the native interaction mode, which owns selection as well, is what makes them worth turning on.

The aiming reticle is never touched either way — we answer false for every reticle message.
Target options show but never clear
The wrapper went somewhere that only sees part of the traffic. In ox_target it must replace the existing local SendNuiMessage = SendNuiMessage line in client/main.lua. In qb-target it must be at the very top of client.lua, above anything that could cache the original.
Prompts reverted to the old style after an update
The update overwrote the file and took the block with it. Every vendor has this problem. The difference is that your console says so on the next boot — it tells “never installed” apart from “was active before, missing now”. Paste the block again.
ak47_target does nothing
ak47_target is a provider that runs on top of qb-target or ox_target, not a target system of its own. Patch whichever of those two it sits on — that is where the options actually go out.
Syntax error / the file looks corrupted
Use WinSCP for FTP uploads. FileZilla can corrupt files in transfer, and a half-written Lua file fails with a syntax error that looks like a bug in the script. Re-upload with WinSCP before reporting anything.
The resource will not start
Almost always a renamed folder. The resource name is baked into the escrow build, so dispersia_interactions has to stay exactly that — no version suffix, no copy marker. Also confirm the folder sits directly inside resources.
ox_lib behaves strangely after patching
Check for a leftover copy of textui.lua in the same folder — something like textui - backup.lua. ox_lib loads resource/**/client/*.lua as a glob, so a spare copy is loaded too and redefines the same functions. Delete it; do not just rename it.
How do I download what I bought?
From the Cfx.re portal: portal.cfx.re/assets/granted-assets. Make sure you are signed in with the same Cfx.re account you used at checkout — assets are granted to that account, not to your email.
The asset is missing from my Keymaster
Contact Tebex directly — we have no control over asset grants, and Tebex can resend it to your portal: tebex.io/support-customer.
Before you open a ticket
Restart the resource in game and check F8 (client) and the server console. If there is an error, send a screenshot of it — the full line, not a crop. Set Config.Debug = true in open/config.lua and every row carries a [source] tag showing which interceptor produced it, which usually identifies the problem in one screenshot.

Still stuck?Open a ticket in Discord. Include your framework, the console error, and what you already tried.

OPEN A TICKET

API reference

Most servers never open this. If you patched ox_lib and your target system, every prompt on your server already draws in one style — there is nothing to call.

THE ONLY LINE MOST SERVERS EVER NEED

Showing a prompt from your own script:

anywhere in your client code
exports['dispersia_interactions']:Show('E', 'Open shop')

Each resource owns its own row and cannot overwrite another’s. Hide() clears the one you registered. Everything below is for the rare case where that is not enough.

Full reference — exports, events, config, limits

CLIENT EXPORTS

exports['dispersia_interactions']:Show(key, text, ctx?) Show a keyed row. ctx is optional: pass { ctx = 'shop' } when one resource needs several rows at once. Without it the row is keyed by the calling resource.
exports['dispersia_interactions']:Hide(ctx?) Clear the row this resource registered, or the one under that ctx.
exports['dispersia_interactions']:HideAll() Clear every row immediately, whoever registered it. For death, a menu opening, a cutscene.
exports['dispersia_interactions']:ShowPrompt(key, label, coords?) A prompt for scripts with no target system. Pass coords and it hides itself once the player walks past Config.HideDistance.
exports['dispersia_interactions']:HidePrompt() Hide it by hand — from onExit, or when the action stops being valid for a reason distance cannot see.
exports['dispersia_interactions']:SetTheme(opts) Restyle at runtime, no restart. Every key optional — pass only what changes.

THE INTEGRATION SURFACE

exports['dispersia_interactions']:Intercept(kind, ...) The one export every inserted line calls. kind is 'textui', 'textuihide', 'ak47', 'oxtarget' or 'qbtarget'. Returns true when we drew it and false when we did not — so the caller knows whether to continue.
returns false when… the message is an aiming reticle, the kind is unknown, that interception is switched off in the config, or anything inside us threw. In every one of those cases the original renders exactly as it always did.
text parsing 'textui' receives the raw ox_lib string and splits it into rows — including several keys in one string.

THEME KEYS — SetTheme(opts)

blurBackdrop blur in px. Default 0 — a blurred layer costs GPU on every frame it is visible, so it ships off.
keyBgL · keyBgRKey box gradient, left and right.
keyBorderKey box right edge — the strongest line in the shape.
tailStart · tailMidThe fading tail behind the label.
textColorLabel colour. Default '#ffffff'.
tailWidthMaximum tail width as CSS. Default '300px'.

TEXT PARSING — ACCEPTED SHAPES

'[E] - Open shop'The common one.
'[E] - Open  [H] - Rob'Several keys in one string — becomes two rows.
'[E] - Open\n[H] - Rob'Same, on separate lines. Literal \n from locale files is handled too.
'E - Open shop'No brackets. Keys up to 6 characters.
anything elseDrawn as-is with key E, rather than dropped.

CONFIG — open/config.lua

Config.MaxRowsRows on screen at once. Default 6; the oldest is dropped first.
Config.TargetKeyKey label on rows from a target system. Default 'LMB' — targets are aimed and clicked, not pressed, so there is no keyboard key to report.
Config.InterceptOxLibox_lib text UI. Needs both lines in textui.lua.
Config.InterceptAk47ak47_target. Option list replaced, reticle untouched.
Config.InterceptOxTargetox_target, and with it all of QBox.
Config.InterceptQbTargetqb-target.
Config.HideDistanceAuto-hide distance for a coords-bound prompt. Default 3.5.
Config.DistanceCheckIntervalHow often that check runs, in ms. Default 250.
Config.DebugAdds a [source] tag to every row. Leave false on a live server.

COMMANDS & COST

/interactions_testDraws three sample rows, then reports every integration point. The verdict is read from the real file on the server, never guessed from what the prompt looks like.
Idle cost0.00 ms. No Wait(0) loops anywhere in the resource.
Distance watcherOne thread, alive only while a coords-bound prompt is on screen, waking every 250 ms. Nothing runs otherwise.
Resource cleanupWhen a resource stops, its rows go with it — automatically, without that resource having to remember.