ktoxktox docs
Setup

Notifications

Routing every message through your own notification system.

Out of the download every message goes through ox_lib.

Config.UI = {
    name = "ox_lib",
}

Your own system

Set the name to custom and fill in public/ui.lua. The file returns a table, and only notify is required. This is what the shipped file looks like:

return {
    ---@param message string
    ---@param kind 'success'|'error'|'info'|'warning'
    ---@param title string
    ---@param durationMs integer
    ---@return nil
    notify = function(message, kind, title, durationMs)
    end,
}

Four positional arguments, not one table of options. The table has to be returned, and notify has to be a function in it. A file that returns nothing stops the start in ktx_cases, ktx_fishing and ktx_dispatch; ktx_garages prints a line and keeps sending through ox_lib.

Client and server

ktx_garagesnotifications are sent from both sides. On the server, one without a target goes to every player.
the other threethe UI file is a client script. The server sends the text to one player, the client hands it to your file.

The hint on screen

ktx_fishing asks the same file for the prompt at a spot and at the market:

    showHint = function(message)
    end,

    hideHint = function()
    end,

Both are optional. Left out, they become empty functions and the screen edge stays empty. ktx_cases and ktx_dispatch accept the same two without ever calling them.

ktx_garages is the exception. The prompt at the impound goes through ox_lib whatever Config.UI.name says, and its public/ui.lua has no hint to fill in.

Beyond that nothing changes. The resource keeps deciding what to say and when, your file decides how it looks.