Skip to the content
Docs

Any overhead-nametag resource — the push cache

On this page5

Works with Thug Nametags V2, af-nametag, js5m-fwens, "Nametag Script" by graze, and anything you wrote yourself. None of them has an "is this person known to that viewer?" hook today, so you add ~15 lines to their client file.

We do not ship or modify their code. Paste this into the third-party resource yourself, or keep it in a small resource of your own that draws the tags.

1. The cache (paste once, client side)

lua
-- === 5code-recognition link ===========================================
-- Names this viewer's character may use right now. Filled by a push from
-- 5code-recognition; never polled, never replicated, never shared.
local recogKnown = {}

-- The % a character needs before a result may carry a name.
-- Keep this equal to Config.Scoring.ActThreshold in 5code-recognition/config.lua.
local RECOG_MIN_PCT = 80

AddEventHandler('5code-recognition:client:onRecognitionChanged', function(sid, info)
    -- A live scene also exists for a FIRST look at a stranger, worth whatever
    -- that scan was worth, so the threshold is not optional: without it you
    -- would draw a label over somebody the character never recognised.
    if info and (tonumber(info.pct) or 0) >= RECOG_MIN_PCT then
        recogKnown[sid] = info.introducedName or info.label
    else
        recogKnown[sid] = nil
    end
end)

-- If the recognition resource restarts, forget everything it told us.
AddEventHandler('onResourceStop', function(res)
    if res == '5code-recognition' then recogKnown = {} end
end)
-- === end 5code-recognition link =======================================

2. The draw loop (one line)

Inside the loop you already have, replace the name you were drawing:

lua
local sid  = GetPlayerServerId(player)
local text = recogKnown[sid] or 'Stranger'

That is one table lookup per player per frame — no export call, no server round trip. Do not call exports['5code-recognition']:GetRecognitionLabel(sid) from a draw loop: every cross-resource call is serialized and you would pay for it on every frame, for every player on screen.

Occasional calls are fine — a command, a menu, one chat line:

lua
if exports['5code-recognition']:IsRecognized(sid) then
    print(exports['5code-recognition']:GetRecognitionLabel(sid))
end

3. Hiding the tag of a masked player (optional)

Viewer-independent, so it is safe to use anywhere — everybody can see a mask:

lua
-- your own face, client side
if exports['5code-recognition']:IsFaceHidden() then
    -- e.g. tell your nametag script to show nothing above your head
end

Server side, for any player:

lua
local hidden = exports['5code-recognition']:IsFaceHidden(targetSrc)
local look   = exports['5code-recognition']:GetConcealment(targetSrc)
-- look = {faceHidden, facePct, faceCategory, armsClass, torsoVisible, handsVisible, skinVisible}

4. A complete minimal example

If you have no nametag script at all and just want to see the link working, put this in a small resource of your own (not in 5code-recognition):

lua
CreateThread(function()
    while true do
        Wait(0)
        local me = PlayerPedId()
        local myCoords = GetEntityCoords(me)

        for _, player in ipairs(GetActivePlayers()) do
            local ped = GetPlayerPed(player)
            if ped ~= me and DoesEntityExist(ped) then
                local coords = GetEntityCoords(ped)
                local dist = #(coords - myCoords)
                if dist < 12.0 then
                    local text = recogKnown[GetPlayerServerId(player)]
                    if text then
                        SetDrawOrigin(coords.x, coords.y, coords.z + 1.05, 0)
                        SetTextScale(0.34, 0.34)
                        SetTextFont(4)
                        SetTextCentre(true)
                        SetTextColour(255, 255, 255, 215)
                        SetTextOutline()
                        BeginTextCommandDisplayText('STRING')
                        AddTextComponentSubstringPlayerName(text)
                        EndTextCommandDisplayText(0.0, 0.0)
                        ClearDrawOrigin()
                    end
                end
            end
        end
    end
end)

5. Driver code inside this resource (Config.NametagSystem = 'custom')

If you would rather keep the glue in 5code-recognition itself, add a client file of your own to fxmanifest.lua and register a driver. It is called with text already filtered by the threshold. Re-add your file to fxmanifest.lua after every update of the script.

lua
-- your own client file, listed after bridge/nametag_client.lua
NametagBridge.SetDriver({
    onSelfConcealment = function(state)
        -- state = {faceHidden = bool, facePct = 0..100}
        exports['my_nametags']:SetMasked(state.faceHidden)
    end,

    onRecognitionChanged = function(sid, text, info)
        -- text = the name to draw, or nil to clear this player
        exports['my_nametags']:SetKnownName(sid, text)
    end,

    onClear = function()
        exports['my_nametags']:ClearKnownNames()
    end,
})

Set Config.NametagSystem = 'custom' or the driver is never called. Everything it receives stays on this client: never put text in a state bag, in GlobalState, or in a net event.