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
| Side | Export | Signature |
|---|---|---|
| server | IsRecognized | (viewerSrc, targetSrc, minPct?, opts?) → boolean |
| server | GetRecognitionLabel | (viewerSrc, targetSrc, minPct?, opts?) → string|nil |
| server | GetRecognition | (viewerSrc, targetSrc, opts?) → nil|{pct, channel, live, label, introducedName, expiresAt, sceneEndsAt} |
| server | GetRecognizers | (targetSrc, minPct?, opts?) → integer[] |
| server | HasRecognized | (observerSrc, targetSrc, minPct?, opts?) → boolean ("may act", always counts a Lab ID) |
| server | GetReliability | (observerSrc, targetSrc, opts?) → 0–100 |
| server | IsFaceHidden | (targetSrc) → boolean (viewer-independent) |
| server | GetConcealment | (targetSrc) → {faceHidden, facePct, faceCategory, armsClass, torsoVisible, handsVisible, skinVisible} |
| client | IsRecognized | (targetServerId, minPct?) → boolean |
| client | GetRecognitionLabel | (targetServerId, minPct?) → string|nil |
| client | GetRecognition | (targetServerId) → nil|RecognitionInfo |
| client | IsFaceHidden | () → boolean (your own face) |
Client event (local, any resource on the same client may listen):
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
- 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 — seeany-nametag.md. - Always apply the threshold. A live scene also exists for a first look at
a stranger, at whatever that scan was worth. Drawing
info.labelwithout checkinginfo.pctwould put a label over the head of somebody the character did not recognise, and the scan would stop meaning anything. - Never copy our answers into a state bag,
GlobalStateor 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 (GetRecognizersis server-only for this reason).
The files
| File | For |
|---|---|
any-nametag.md | Any overhead-nametag resource (Thug, af-nametag, js5m-fwens, your own) — the push-cache pattern |
cxc_gamertag.md | cxc_gamertag — the built-in mask driver plus the per-viewer name patch |
zeno-rpchatid.md | zeno-rpchatid — Config.IsPlayerMasked |
nobody-nametags.md | Nobody NameTags — Config.CustomRequestScript |
chat-default.md | The default chat resource — a per-recipient /me |
codem-supreme-chat.md | CodeM Supreme Chat — showPlayerData |
Built-in drivers
Config.NametagSystem (client, config.lua) is 'none' by default — the
link is off until you turn it on:
| Value | What 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.