Skip to the content
Docs

Integration snippets — nametags and chat

On this page5

Ready-to-paste code for connecting 5code-recognition to an overhead-nametag or chat resource, so a name appears only for the players whose character actually recognises the speaker.

The rule these snippets implement

A name is shown only while the viewer has a live scene result of that player — i.e. they scanned them and it worked, in the last ~10 minutes (Config.Api.RecognitionSource = 'scene'). Never from a saved memory alone, never from a Lab ID (Config.Api.LabInNameApis = false), and never a real character name: our answer is the introduced name the target gave them, else the memory line ("Met him on Vinewood Blvd in the evening").

What you may call

SideExportSignature
serverIsRecognized(viewerSrc, targetSrc, minPct?, opts?) → boolean
serverGetRecognitionLabel(viewerSrc, targetSrc, minPct?, opts?) → string|nil
serverGetRecognition(viewerSrc, targetSrc, opts?) → nil|{pct, channel, live, label, introducedName, expiresAt, sceneEndsAt}
serverGetRecognizers(targetSrc, minPct?, opts?) → integer[]
serverHasRecognized(observerSrc, targetSrc, minPct?, opts?) → boolean ("may act", always counts a Lab ID)
serverGetReliability(observerSrc, targetSrc, opts?) → 0–100
serverIsFaceHidden(targetSrc) → boolean (viewer-independent)
serverGetConcealment(targetSrc) → {faceHidden, facePct, faceCategory, armsClass, torsoVisible, handsVisible, skinVisible}
clientIsRecognized(targetServerId, minPct?) → boolean
clientGetRecognitionLabel(targetServerId, minPct?) → string|nil
clientGetRecognition(targetServerId) → nil|RecognitionInfo
clientIsFaceHidden() → boolean (your own face)

Client event (local, any resource on the same client may listen):

lua
AddEventHandler('5code-recognition:client:onRecognitionChanged', function(targetServerId, info)
    -- info = nil, or {pct, channel, live, label, introducedName, sceneEndsAt}
end)

minPct defaults to Config.Scoring.ActThreshold (80).

Three rules you must not break

  1. Never poll an export per frame. Every cross-resource export call is serialized. Listen to onRecognitionChanged, keep a small local table, and read that table in your draw loop — see any-nametag.md.
  2. Always apply the threshold. A live scene also exists for a first look at a stranger, at whatever that scan was worth. Drawing info.label without checking info.pct would put a label over the head of somebody the character did not recognise, and the scan would stop meaning anything.
  3. Never copy our answers into a state bag, GlobalState or any shared table. That would publish who knows whom to every client on the server. Our own code writes none, ever. Keep the table local to the viewer's client, or send per-recipient messages from the server (GetRecognizers is server-only for this reason).

The files

FileFor
any-nametag.mdAny overhead-nametag resource (Thug, af-nametag, js5m-fwens, your own) — the push-cache pattern
cxc_gamertag.mdcxc_gamertag — the built-in mask driver plus the per-viewer name patch
zeno-rpchatid.mdzeno-rpchatid — Config.IsPlayerMasked
nobody-nametags.mdNobody NameTags — Config.CustomRequestScript
chat-default.mdThe default chat resource — a per-recipient /me
codem-supreme-chat.mdCodeM Supreme Chat — showPlayerData

Built-in drivers

Config.NametagSystem (client, config.lua) is 'none' by default — the link is off until you turn it on:

ValueWhat bridge/nametag_client.lua does
'none'nothing (default)
'cxc_gamertag'calls exports.cxc_gamertag:Mask(faceHidden) when your own face is covered or uncovered
'zeno-rpchatid'nothing: zeno asks us instead (see their file)
'custom'calls the driver you register with NametagBridge.SetDriver{…}

bridge/nametag_client.lua is open (escrow_ignore) — read it, it is short.