Overview
About nCore Chat
Someone types in IC and only the people within 8 meters see it. When somebody calls 911, the on-duty cops get a card with the street on it and a Respond button.
nCore Chat replaces the stock FiveM chat. It provides chat, so scripts that call chat:addMessage, templates or suggestions still end up in it. Scripts that use addMode/registerMode or updateMessage need a small change. You can use it without a framework, or with QBox, QBCore, ESX, ox_core or ND_Core. It comes as an Escrow edition and a Full source edition.
Talking in character
Distance is checked on the server, so nobody gets a line they are out of range for. Normal speech reaches 8 meters, and a chip in the input switches to whisper, low or shout. People in the same car always hear each other.
IC is not kept on the server. Someone who joins late can't scroll back and read it.
/me and /do post a line and also draw it above your head. Messages show as phone-style bubbles with a headshot of the character, or as classic colored lines if a player prefers that.
Send a wave emoji in IC and your ped waves. The handshake, hug and high five ask the nearest player first with an Accept or Decline card. Emotes skip while you're dead, cuffed or swimming, and players can turn them off. Which emoji plays which animation is set in a config file.
911 and the other channels
/911 opens a numbered incident card for on-duty responders. Respond puts you on the call and tells the caller who's coming. If you run ps-dispatch or cd_dispatch, calls go there as well.
On-duty and department channels need a framework that provides job and duty. On standalone you get the proximity chat, OOC and private messages, and names show as "Unknown".
You also get Local and Global OOC, radio by frequency and department channels like /pd and /ems. Chirp and Darknet are off until you turn them on. The rest is in README.md.
A channel of your own is one table in config/channels.lua. The file has a taxi example in it, uncomment it and on-duty cab drivers get their own rail icon and a /taxi command.
Staff tools
Every line goes through the mutes and the word filter on the server before anyone sees it. Staff can right-click a line to delete it or mute the player.
/report drops a numbered card in the staff channel, and whoever claims it gets a private thread with the reporter.
Webhook URLs are read from server convars, so players never receive them. From the server console, lrc_export prints a player's lines from today's log and lrc_forget deletes their saved data.
Settings and languages
Players pick one of five themes, and there is a streamer mode that hides OOC and blurs avatars. For accessibility there's reduced motion and a color-blind palette, among others. The interface is in English, German, Spanish, French, Hungarian and Brazilian Portuguese, and you can add a language as a JSON file.
Ranges, prices, cooldowns, the 911 responder jobs, departments and the word lists are in config/config.lua and config/channels.lua. Config.lockedSettings fixes a player setting for everyone, the theme for example.
The full feature list is in README.md, which ships with the script and is also on intelnpc.com.
Trying it
On a test server, set Config.demoMode = true and run /lrcdemo as staff. Ten scripted characters stand around you in three groups and talk, so you can walk between them and hear the ranges work with nobody else online. Only you see them.
Requirements
- FXServer build 6116 or newer with OneSync on
- Remove the stock
chatresource - No ox_lib needed
- Optional: a framework for names, jobs, money and items
- Optional: oxmysql, with
Config.logs.database = true, for saving (archive, Chirp, mutes across restarts) - Optional: screenshot-basic and an upload URL for /photo, pma-voice or ncore_hud for the voice features
Log files are on by default and record every message, private messages included.
What you get
The ncore_chat resource with README.md, INSTALLATION.md and CHANGELOG.md, four config files, six language files and the SQL file. Fonts and icons are inside the resource, nothing loads from the internet.
Editions
In the Escrow edition the Lua code is protected by Cfx.re escrow. The config files, bridges, locales, SQL and web/css/tokens.css stay open to edit. The Full source edition has every file readable. Both get the same features and the same updates.
Updates don't install themselves. Download the new version, keep your config/ folder and copy the other files over. New versions are announced on intelnpc.com.
Support is on intelnpc.com and I reply within 72 hours. Payments and refunds are handled by Tebex under their terms.
nCore Chat is made by nCore Development.
Not approved, sponsored or endorsed by Rockstar Games.
What you get
Config open, core escrowed
Docs
Read it before you buy
The same docs that ship with the script, updated with every release.
Roleplay chat for FiveM that takes the place of the stock chat resource. Standalone, ESX, QBCore, QBox, ND_Core and ox_core.
nCore Development · intelnpc.com · Resource: ncore_chat · Version: see fxmanifest.lua
What it is#
nCore Chat replaces the stock chat with one made for roleplay. Speech goes by distance, /me and /do show above your head, private messages are threads, and a 911 call is a card the cops can answer.
It provides chat, so scripts that send lines to the stock chat still land in it. The server decides who hears what. A framework is optional, and oxmysql only adds saving.
Features#
Replacing the stock chat#
- Provides
chat- the manifest hasprovide 'chat', and calls toexports['chat']are answered on client and server. Remove the stockchatresource first. - Stock messages -
chat:addMessage,chat:addTemplate,chat:addSuggestion(s),chat:removeSuggestionandchat:clearwork. Color codes^0to^9are read. Template HTML is cut down to<b>,<i>,<br>and colored spans, so nothing unsafe gets in. - Cancellable chatMessage - the server fires
chatMessagefor every line before it goes out, and other scripts can cancel it. - Unknown commands - a
/commandno resource handles shows a short translated toast instead of vanishing. - What doesn't carry over - stock-style
chat:addMode/registerModetables are not turned into channels and stockupdateMessagerewrites from hooks don't apply. Scripts that rely on those need a small change.
The panel#
- Open the chat - T (key mapping
lrc_open, rebindable in the game's Key Bindings). Lands in IC, or in the last channel withConfig.keybinds.openTo = 'last'. It won't open while the screen is faded out or the pause menu is up. - Open straight to Global OOC - key mapping
lrc_ooc, unbound by default (Config.keybinds.oocOpen). - Tabs and rail - IC, Local OOC and Global OOC are tabs on top. Every other channel is an icon on the left rail, grouped Duty, Apps and Staff, with its own color and a short label. Order comes from
orderinconfig/channels.lua. - Unread badges - count badges on tabs and rail icons (99+ cap). 911 always uses the alert style.
- Rail tooltip - hover an icon to see its name, Alt+N hotkey, reach, price and a short description.
- "Sending to" strip - above the input: the channel, how far it reaches, the speech-mode pills in IC, chips for read-only, slowmode and advert price, and up to 4 quick command buttons for the built-in channels.
- Bubbles or classic lines - phone-style bubbles with avatars by default.
Config.messageStyle = 'plain'makes colored "Name: message" lines the server default, and players can switch in Settings > Appearance. - Mode styling - me, do, OOC, radio, shout, whisper, low, staff, department and announcement lines each have their own look and a small chip.
- Distance fade - IC and Local OOC lines get fainter in three steps the closer the speaker was to the edge of range.
- Big emoji - a message of up to 3 emoji alone shows large.
- Grouping -
Config.identity.nameEveryMessage = falsegroups lines from the same author and mode within 60 s under one name. On by default (every line has a name). - Day separators and time chips - a time chip every 5 minutes. Players pick off, 12h or 24h.
- Repeat counter - the same line from the same player in the same channel within 30 s is posted with an xN counter.
- Instant send - your line shows at once as "sending", and turns "failed" if the server refuses it or nothing comes back in 10 s.
- Jump to new - scroll up and new lines don't pull you down. A button shows how many are waiting.
- Empty channels - a short explainer with buttons for the channel's commands.
- Search - Ctrl+F or the magnifier. This channel or all channels, live results grouped by channel with highlighted snippets and times, Enter opens the first hit. It searches the lines your client has loaded, up to
Config.search.maxResults(200). - Jump to a message - click a search hit or a pin: the chat switches channel, scrolls to it and flashes it.
- Drag and place - drag the header to move the panel. Nine position presets, an optional 8x5 snap grid, widths S / M / L (460 / 540 / 640 px), a UI scale slider (0.85 to 1.6) on top of an automatic scale for big screens, and a reset button. All in Settings > Window.
Config.window.draggable = falselocks it. - Mouse look - off by default.
Config.window.cameraLook = 'drag'turns the camera while the right mouse button is held,'free'whenever the mouse is off the panel. Speed iscameraLookSensitivity. - Close after send - the chat closes after each line you send. Players can turn that off in Settings > Chat.
- Keyboard - while typing: Tab / Shift+Tab cycle the tabs, Alt+1 to 9 jump by rail order, Alt+Up / Down change speech mode, Up / Down walk your input history, Enter sends (empty Enter closes), Shift+Enter adds a new line, Esc closes. Ctrl+, opens settings. A keyboard button under the input lists the shortcuts.
- Block players -
/block [id],/unblock [id]or right-click a line. Their lines are hidden on your screen only. Staff, 911 and System channels are never hidden. The list with Unblock buttons is in Settings > Privacy. - Clear your window -
/clearchatempties your own panel.
Typing and sending#
- Command palette - type
/in an empty input. Fuzzy ranked, with translated help for nCore commands, suggestions other scripts added, and the server and client commands you have access to. Up / Down to move, Tab or Enter to fill. - Parameter chips - after a command word, its parameters show as chips. The one under the cursor is highlighted, filled ones get a tick, and the help line follows.
- @ autocomplete - type
@for the last authors in the channel, with their avatars. Picking one inserts the full name, and that player gets a mention badge and the notification pill. - Emoji shortcodes -
:plus a few letters completes about 90 shortcodes. - Emoji picker - the smile button. 8 categories, search and a tab of emoji that make your character move, marked with a small star.
- Attach menu - the
+button: share location (/loc), roll a die (/roll 6) or take a photo (/photo). - Speech mode chip - in IC, a chip in the input. Click cycles whisper, low, say and shout, right-click opens a menu, and the pills above show each range in meters. The server checks the mode.
- Drafts and history - each channel keeps its unsent text while you switch. Up / Down recalls your last 50 lines per channel. Both live until you reconnect.
- Counter and slowmode - a character counter under the input (
Config.window.maxLength, 500), and a countdown ring on the send button when a channel has slowmode. - Typing dots - while you type in IC or Local OOC, dots show above your head for players near you (
Config.typing.world3d). They're hidden while you aim. In PMs, radio, report and staff threads the other side sees an "is typing" row. Players can stop sharing it in Settings > Immersion.
Speech and roleplay verbs#
- Proximity IC - the server routes IC by distance: whisper 2.5 m (
/w,/whisper), low 4 m (/low), say 8 m (/sayor just type), shout 30 m (/s,/shout) with a 5 s cooldown for non-staff. Ranges areConfig.modes.<mode>.radius. - Vehicles and buckets - people in the same vehicle always hear each other. Players in another routing bucket never do.
- No proximity backlog - IC and Local OOC have no history on the server, so someone who joins late can't scroll back through what was said before they arrived.
- /me and /do - post an action or a scene line in IC and show it as 3D text above the speaker.
Config.channels.autoFormatVerbscapitalizes the first letter and adds a full stop. - /try - a card that says success or fail, rolled on the server. Odds are
Config.modes.try.successChance(0.5). - /roll and /coin -
/rollrolls 1 to 6,/roll 20rolls 1 to 20, capped atmaxSides(1000)./coinflips a coin. Both post a card.
Text above heads#
- 3D /me and /do - shown above the speaker for players within range (8 m). Text scales with distance, fades near the edge and at the end of its life, and stacks up to 3 per player. A /me stays up longer when it's longer.
- Speech bubbles - IC lines also pop up above heads for 5 s, 2 per player. Shouts are in capitals, whispers are dimmed.
Config.speechBubbles.enabled. - Two renderers -
Config.me3d.renderer = 'nui'(HTML bubbles with avatars, default) or'native'(GTA draw-text). - Behind walls -
Config.me3d.occlusionhides text from a speaker you can't see, checked twice a second per text. - Pinned /do - off by default.
Config.do3d.anchors = truekeeps a /do at the spot it was written forlifeMinutes(2), for the players who were in range./undo_dotakes yours down for players still nearby. - Player toggles - Settings > Immersion: see other players' 3D text, show my own, speech bubbles above heads.
- Cap -
Config.performance.max3dTexts(24) is the most texts drawn at once.
Avatars and names#
- Headshot avatars - every message shows the author's face, taken from their ped. Nearby players are generated locally, no extra resource needed.
- Your avatar stays current - it's retaken when your ped model changes, and after outfit events from illenium-appearance, fivem-appearance, esx_skin / skinchanger, qb-clothing, ncore_inventory and ncore_character.
/mugshotretakes it by hand (60 s cooldown). - Blank pictures - a blank or black headshot is detected and retried up to 3 times, then a fallback icon is used.
- Far away players - with
loaf_headshot_base64orMugShotBase64running, players far away still see your avatar. With the database on, it's also stored. - Fallback icon - masked, anonymous and system authors get an icon. Players can turn all avatars off, or only their own.
- Character names - names come from the framework character, never the FiveM account name. Until a character loads, and on standalone, the name is "Unknown".
- Badges - department members get a colored badge. Staff get a shield outside IC.
- Masks - a mask on the ped makes your lines show as "Masked #742", with no job, badge or avatar. The real character is still logged. The player's own client reports the mask, so a modified client can claim one it doesn't wear.
Config.identity.maskItemmakes the server also check for an item (ESX, QBCore, QBox and ox_core).Config.identity.maskDetectionswitches it. - [id] in OOC -
Config.identity.showIdInOOCputs the server ID in front of names in OOC and Local OOC.
Emoji that move your character#
- Emoji emotes - send an emoji alone (up to 3) or at the end of an IC line and your character plays a matching GTA animation. The server picks it from a pool and avoids repeating the last one.
- Moods - face emoji like 😄 🙂 😢 😡 😮 😴 only change the face for about 10 s.
- Cooldowns - 6 s per player and 10 s per emoji family, on the server (
playerCooldown,perEmojiCooldown). A toast tells you the time left. - When it skips - dead, cuffed, ragdolled, swimming, or in a vehicle. Seat-safe ones like 👋 👍 🤷 still play in a car.
- Handshake, hug, high five - 🤝 🤗 ✋ send an Accept / Decline card to the nearest player within 2 m. It lands in their System channel. If they accept within 10 s, both turn to face each other and play their side.
Config.emojiEmotes.pairedConsent = falseturns paired emotes off. - Opt out - "Emoji trigger my character" in Settings > Immersion.
Config.emojiEmotes.allowRude = falsedrops the 🖕 pool (on by default). - Text emoticons -
:D,xD,:),<3and the rest ofConfig.emoticons.mapturn into emoji when typed as a separate word. - Your own map - which emoji plays which animation is in
config/emoji_emotes.lua. - Turn it off -
Config.emojiEmotes.enabled = false.
Channels#
- Built in - IC, Local OOC, Global OOC, Radio, Adverts, Chirp, Darknet, 911 Dispatch, Staff, Announcements and System. Chirp and Darknet are off by default.
- Local OOC -
/bor/looc, 20 m (Config.channels.oocLocal.radius). - Global OOC -
/ooc, server wide, 2 messages per 10 s per player (Config.moderation.rate.oocGlobal).Config.channels.oocGlobal.schedule = { start = 22, stop = 8 }opens it only between those hours, overnight works. - Radio -
/radio 445.5tunes in and adds a MHz entry to the rail,/radio [message]transmits,/radio off(orleave) tunes out. Frequencies are rounded to 2 decimals, and you can tune to a new one every 3 s (Config.channels.radio.joinCooldown). When the last player leaves a frequency, its rail entry and history are gone. With pma-voice the chat also tunes to your voice radio channel. - Departments -
/pd,/ems,/dojfor the jobs inConfig.channels.departments, on duty only by default. Each has its own badge color and icon. Add more in the same table. Needs a framework that gives job and duty. - Adverts -
/ador/advertposts a business card. Costs 250 and has a 120 s cooldown for non-staff (Config.channels.adverts). Paid through the framework. On standalone it's free and the console says so at start. - Chirp -
/chirp, a city social feed. With the database on, the newest posts come back after a restart. - Darknet -
/anon, posts under a random handle like viper_4821 that changes every restart. Players can't see who wrote it. Lines show blacked out until clicked.requireItem(defaultcryptostick) works on ESX, QBCore, QBox and ox_core. Set it to''on other setups. - 911 and 311 -
/911opens a numbered incident,/311a non-emergency tip. On-duty responders (LRCDispatchJobs: police, sheriff, ambulance) get a live card with call number, priority, New / Responding timeline, caller, street, elapsed timer and attached units. Buttons: Respond (Acknowledge on 311), waypoint and a map blip that removes itself. The caller is told who's responding. A call nobody answered shows CLOSED afterexpirySeconds(600). - Dispatch forwarding - with
forwardResource = 'auto'each call also goes to ps-dispatch or cd_dispatch when one runs. - Staff -
/staffor/aposts to the staff-only channel. Staff is the framework admin group or the ACElrc.staff. - Announcements -
/announce [text], optionally with--countdown=Nfor a live countdown card. Staff, the ACElrc.announceor the server console (announce [text]). Staff can also type straight into the Announcements channel. - System - join and leave lines are off (
Config.channels.systemJoinLeave, or the stockchat_showJoinsconvar). - Your own channels - add a table to
config/channels.lua: reach (proximity, global, jobs, staff), jobs and duty, commands, cost, cooldown, read-only, ACE, icon, color and rail position. Players never see a channel they can't read.
Private messages#
- Threads -
/pm [id] [message]opens a thread with its own rail entry,/ranswers the last one. - Receipts - your bubbles show Queued, Delivered or Read. Players can stop sending read receipts in Settings > Privacy, and
Config.pm.receipts = falseturns them off for everyone. - Quick reply - Page Down (
lrc_reply) opens a small box to answer the newest PM without opening the panel, for 300 s after it arrived (Config.pm.quickReplySeconds).
Cards#
- Polls - staff run
/poll "question" option1 option2 ...(up to 6). Players vote and can change their vote, bars update live, and it closes afterConfig.channels.pollMinutes(10) or with/pollclose. - Location -
/locposts your street and area into the current proximity channel. Readers see distance and direction from where they were when it arrived, plus waypoint and map blip buttons. - Photos -
/photo [caption]takes a screenshot with a shutter flash, uploads it and posts a photo card with a lightbox to players within 8 m. Needs screenshot-basic and an upload URL in thelrc:photoWebhookconvar. The endpoint has to answer with the image URL (JSONurlorattachments[1].url, or a plain link). 30 s cooldown, quality and size inConfig.photos. - Pins - staff, or players with the ACE
lrc.pin, pin from the right-click menu. Up to 3 per channel, the bar shows who pinned and a 1/N counter, click to jump. - Card buttons - each button carries a token that works once, for that player, until it expires. Forged or replayed clicks are dropped.
Moderation and staff#
- Send checks - every line goes through mute, slowmode, cooldowns and a rate limit on the server, then cleaning: control characters and reversed-text marks are removed, ALL CAPS is toned down, and the word filter runs.
- Rate limit -
Config.moderation.ratesets it per class:icfor proximity channels,oocGlobal,pm, anddefaultfor every other channel. The Staff channel has none. - Word filter - three lists in
Config.moderation.extraWords:blockrefuses the line and counts a strike,maskturns the word into asterisks,flagonly writes it to the log. Whole words only, and leetspeak is decoded before matching, so write your words in plain letters. - Soft mutes - three violations within 60 s give an automatic mute of 10 s, then 60 s, then 300 s (
Config.moderation.softMuteSteps). - Mutes -
/lrcmute [id] [seconds] [channel]and/lrcunmute [id]. A muted player sees a chip with a countdown. With the database on, mutes survive rejoin and restart. - Slowmode and lock -
/slowmode [seconds] [channel](0 clears) and/lockchannel [channel]. They reset at restart. - Wipe -
/lrcclear [channel]clears a channel, or all of them, for everyone and drops the server history. - Right-click tools - staff right-click any line: delete (leaves a "removed by staff" placeholder), mute 15 minutes, unmute, warn with a reason, the player's last messages, and copy IDs.
- Reports -
/report [id] [reason]posts a numbered card in Staff. Claim opens a private Report #N thread (the button works for 5 minutes after the card arrives)./reportclose [id]closes it. A player can send one report every 60 s (Config.moderation.reportCooldown). - Staff exemptions - staff skip slowmode, the shout and advert cooldowns, and can post in a locked channel.
- Staff toasts - with ncore_hud running,
/report,/lrcmuteand/lrcunmutealso pop a toast for staff. - Edit and unsend - right-click your own line within 120 s (
Config.messageEdit.windowSeconds). Edits go through the word filter again and show "edited". Unsend leaves a placeholder. IC and 911 can't be edited or unsent (permanentChannels).
Closed chat and notifications#
- Mini chat - with the panel closed, recent lines fade in and out where the panel sits. 15 s and 8 lines by default (
Config.window.ghostLifeSeconds,ghostMaxLines), players set 4 to 60 s and 3 to 14 lines. - /hidechat - cycles the mini chat through all, important only (staff, 911, announcements) and hidden.
- Notification pill - a small pill at the top center for PMs, mentions, 911 and staff lines while the chat is closed. Avatar, name and a preview, a red outline for 911, click opens the channel.
Config.notifications.island. - Do Not Disturb - hides the pill for everything except 911 and staff.
- Channel mute - the bell button, or right-click a tab or rail icon, keeps that channel out of the mini chat and marks it with a bell.
- Game feed - System and announcement lines also go to the GTA feed above the minimap (
Config.notifications.gameFeed). - Pause menu - the mini chat, pill, quick reply and 3D text (NUI renderer) hide while the pause menu is open.
- Sounds - send, receive, mention, 911, staff, open, close and error. GTA frontend sounds by default (
Config.notifications.soundEngine = 'native', remap them innativeSounds),'ui'for soft tones,'off'for none. With native sounds the player's volume slider works as on and off.
Settings and looks#
- Settings sheet - the gear or Ctrl+, opens 7 tabs: Roleplay, Window, Appearance, Chat, Immersion, Notifications and Privacy. Saved per player on their PC.
- Five themes - Afterglow (default), Sunset, Dusk, Midnight and Daylight.
Config.theme.defaultsets the default,allowPlayerChoice = falsehides the picker. - Locked settings - put pref keys in
Config.lockedSettings(for example{ 'theme' }) and every player gets your default. The row shows as "Server managed". - Accessibility - text scale 0.85 to 1.4, compact density, animation speed, reduced motion (the OS setting is honored too), a solid panel option, a color-blind accent palette and dyslexia-friendly spacing.
- Streamer mode - Settings > Privacy. Removes the OOC, Local OOC and Chirp tabs and rail entries, blurs avatars in the feed, mini chat, pill and quick reply, and turns off the talking ring.
- Fonts and icons - bundled with the resource, nothing loads from the internet.
- Colors - theme palettes are CSS variables in
web/css/tokens.css. - Reset - Settings > Privacy > Reset all settings goes back to defaults, block list and window position included.
Profiles#
- RP mode -
/chatmode text|voice|hybridor the Roleplay tab. Each mode sets how long and how many lines the mini chat keeps (Config.rpModes).Config.rpModeDefaultsets the default, and'rpMode'inConfig.lockedSettingslocks it. - Server profile -
Config.profile = 'text'widens the ranges (say 12, whisper 3, low 5, shout 40 m), keeps 250 lines per channel instead of 150 and makes the mini chat stay longer.'hybrid'keeps the voice ranges.'voice'is the default. A player who hasn't picked an RP mode starts in the one the profile names, unlessConfig.rpModeDefaultis set. The overrides per profile are inConfig.profilesat the bottom ofconfig/config.lua.
Voice and HUD#
- ncore_hud - with ncore_hud running, RP mode is shared with the HUD both ways and the HUD can lock it.
- Speech mode sets mic range - with ncore_hud or pma-voice, picking whisper, say or shout in the chat also sets your voice range, and a range change elsewhere moves the chat mode back (
Config.integrations.voiceRange). - Talking ring - in bubble style, avatars of players within 20 m who are talking pulse while the chat is open. Needs a voice resource where the game's talking check works, like pma-voice.
Config.presence.voiceRing.
Localization#
- Six languages - English, German, Spanish, French, Hungarian and Brazilian Portuguese.
Config.locale = 'auto'reads the usual locale convars (lr:locale,locale,ox:locale,esx:locale,txAdmin-locale). On the client it falls back to the game language, on the server to English. - Add a language - copy
locales/en.jsontolocales/<code>.jsonand translate it. Missing keys fall back to English. - Not in the locale files - channel and department labels are in
config/channels.luaandconfig/config.lua, so you rename those there.
Database and logs#
- Database - off by default.
Config.logs.database = truewith oxmysql creates 7 tables fromsql/ncore_chat.sqlat start. Adds: message archive (write only), saved Chirp, report numbers that keep counting, mutes that survive restarts and stored avatars. - Log files -
Config.logs.file(on) writes every message and staff action tologs/lrc-YYYY-MM-DD.jsonlin the resource folder, a new part every 2000 lines, and keeps going after a restart. Message lines have author, license, the position on proximity channels and the street on 911 and location cards. This includes private messages. Nothing is deleted on its own,retentionDays(30) only prints a reminder at start. - Webhook logs - set the convars
lrc:logWebhook(all channels, private messages included),lrc:logWebhookStaff(staff channel and staff actions) andlrc:logWebhook911. Lines are batched, up to 10 per request every 5 s (Config.logs.webhookBatchSeconds). - Secrets stay on the server - webhook URLs are read from convars in
config/config_server.lua, which only the server loads. A URL left inconfig/config.luastill works and prints a warning. - Export and forget - in the server console,
lrc_export <license>prints that player's lines from today's log.lrc_forget <license> [charId ...]deletes their saved settings, archived messages, Chirp posts, avatar and queued PMs from the database, and their lines from today's log file. When today's log has more than one part, export only sees the newest part plus the last 500 lines before it, and forget only cleans the newest part. Files from earlier days stay as they are, delete those by hand. - Hidden character IDs - clients never get a player's license or real character ID. Each character gets a random ID like
c_3f9a1c0e7b2d4a61, kept in the resource KVP so it stays the same after a restart. Copy IDs in the staff menu gives you that ID, andlrc_forgettakes it too. The database and the log files keep the real ID. - No phone home - the only outbound requests are your own webhooks and the
/photoupload.
For developers#
- Server exports -
Send,SendCard(up to 3 buttons that fire server events),RegisterChannel,RemoveChannel,RegisterCommandChannel,Mute,Unmute,ClearFor(pass a table of server IDs, or nil for everyone),SetSlowmode,OnMessage(rewrite or cancel a line, returns a hook ID),RemoveHook,GetHistory. - Client exports -
Open(channelId),Close(),IsOpen(),GetActiveChannel(),Notify(text or {kind, text}),PedSpeech(ped, text, kind, info)(a bubble over any ped, NPCs too),ClearPedSpeech(ped),GetChatRpMode(),SetChatRpMode(mode). - Events - client
lrc:onOpened,lrc:onClosed,lrc:onChannelChanged,lrc:onCardAction.lrc:advertContacton server and client. - State bags -
lrc_typingandlrc_maskedon the player, for other resources to read. - Shared focus - NUI focus and background blur are coordinated with ncore_hud, ncore_vibehud and ncore_devkit through the state bags
lrNuiOwnerandlrBlurDepth.
Requirements#
- FXServer build 6116 or newer.
- OneSync on.
- Optional: a framework (QBox, QBCore, ESX, ox_core or ND_Core) started before ncore_chat. Without one it runs standalone.
- Optional: oxmysql with
Config.logs.database = true(MySQL 5.7.8+ or MariaDB 10.2.7+). - Optional: screenshot-basic for
/photo, pma-voice or ncore_hud for voice features, ps-dispatch or cd_dispatch for forwarding,loaf_headshot_base64orMugShotBase64for avatars of far away players. - No ox_lib needed.
Keys and commands#
| What | Default |
|---|---|
| Open chat | T (lrc_open) |
| Open to Global OOC | unbound (lrc_ooc) |
| Quick reply to the newest PM | Page Down (lrc_reply) |
| Search / Settings | Ctrl+F / Ctrl+, |
| Cycle tabs / jump to channel | Tab, Shift+Tab / Alt+1 to 9 |
| Speech mode | Alt+Up / Alt+Down |
| Who | Commands |
|---|---|
| Everyone | /say /w /whisper /low /s /shout /me /do /undo_do /try /roll [max] /coin /b /looc /ooc /radio /ad /advert /911 /311 /loc /photo /pm [id] /r /report [id] [reason] /block [id] /unblock [id] /mugshot /hidechat /clearchat /chatmode |
| When the channel is on | /chirp, /anon |
| Department jobs | /pd /ems /doj |
| Staff | /staff /a /announce /poll /pollclose /slowmode /lockchannel /lrcmute /lrcunmute /lrcclear /reportclose |
| Server console | announce [text] lrc_export <license> lrc_forget <license> [charId ...] |
Staff, only with Config.demoMode = true |
/lrcdemo /lrcshowcase |
| F8 console | lrcmug checks why your avatar isn't taken and retakes it |
Configuration reference#
| File | What's in it |
|---|---|
config/config.lua |
Every setting: theme, window, keys, ranges, channels, 3D text, PMs, pins, moderation, staff, sounds, logs, languages, profiles. Start here. |
config/channels.lua |
The channel list, your own channels, the command list and the 911 responder jobs. |
config/emoji_emotes.lua |
Which emoji plays which animation, paired emote time and range. |
config/config_server.lua |
Reads the webhook and photo convars. Server only. |
bridge/*.lua |
One file per framework, if you run a custom one. |
locales/*.json |
All interface text, one file per language. |
web/css/tokens.css |
Theme colors and fonts. |
sql/ncore_chat.sql |
The database tables, created on their own. |
Every key in config/config.lua has a comment next to it. This is what each block covers:
| Block | What you change there |
|---|---|
Config.locale, Config.profile |
The language ('auto' or a code like 'de') and the server profile (see Profiles above). |
Config.theme, Config.messageStyle |
The default theme, whether players may pick their own, and bubbles or plain lines as the default. |
Config.window |
Start position, width (S, M and L are 460, 540 and 640 px), dragging, mini chat time and lines, the 500 character limit and mouse look. |
Config.keybinds |
Open key (T), open to IC or the last channel, the Global OOC key and the quick reply key (Page Down). |
Config.blockICWhileDead |
On by default. A dead or dying character can't send IC lines, /me, /do or the other roleplay verbs. The check runs on the player's client. |
Config.modes |
Range in meters for each speech mode, the shout cooldown, the /try odds and the /roll sides. |
Config.channels |
Local OOC range, Global OOC hours, advert price and cooldown, poll length, Chirp and Darknet on or off, radio limits, departments and the 911 settings. In the 911 block maskCaller = true shows responders "Caller #347" instead of the caller's name. |
Config.photos |
/photo on or off, cooldown, picture quality and the size cap. |
Config.me3d, Config.do3d, Config.typing, Config.speechBubbles |
3D text renderer, range, size and how long it stays, pinned /do, typing dots and speech bubbles. |
Config.pm, Config.search, Config.pins, Config.messageEdit |
PM typing and read receipts, quick reply time, search result cap, pins per channel and the pin ACE, and the edit and unsend window. |
Config.emoticons, Config.emojiEmotes |
Text smileys, emoji emotes, their cooldowns, paired consent and the rude pool. |
Config.identity, Config.presence |
Avatars, masks and the mask item, [id] in OOC, badges, a name on every line, the talking ring. newCharDays (7) gives a character a NEW badge for its first week. |
Config.suggestions |
Whether the / palette also lists every command registered on the server, and which prefixes it hides. |
Config.notifications |
Pill, previews, sounds and the GTA sound for each event, the game feed and staff toasts. |
Config.moderation |
Filter level and word lists, links, caps and emoji limits, rate limits, soft mutes, the mute length /lrcmute uses without a time (900 s), the longest mute the right-click menu accepts (24 h) and the report cooldown. Links are removed in every channel except Staff, where they stay, and Global OOC, where only the sites in linkAllowlist stay. Local OOC counts as a proximity channel, so links are removed there too. |
Config.staff |
The staff ACE, the announce ACE and which framework groups count as staff. |
Config.economy, Config.logs |
The ox_core money item adverts are paid from. Log files, the database, the retention reminder and webhook batching. |
Config.performance |
Lines kept per channel, the 3D text cap and the avatar cache. |
Config.lockedSettings |
Player settings you fix for everyone. The valid keys are in the comment above it. |
Config.integrations |
voiceRange (speech mode sets the mic range) and mugshotB64 (avatars of far away players). The voice, phone and screenshots keys in this block aren't read in this version, so changing them does nothing. |
Config.demoMode, Config.showcase |
The test scene (ships off, see below) and the recording setup it uses. |
Config.profiles, Config.rpModes, Config.rpModeDefault |
What each server profile and each RP mode changes. |
Trying it on a test server#
Config.demoMode ships false. Set it to true on a test server and restart, then run /lrcdemo as staff (or lrcdemo <id> from the console). Ten scripted characters stand around you in three groups, 6, 12 and 18 m away, and talk to each other while every channel gets some traffic. Walk from one group to the next and you hear the ranges work. Only you see them and nothing goes into the real history or the logs. /lrcdemo stop removes them, and a scene nobody stops ends after 30 minutes.
/lrcshowcase is the cut I record videos with. It changes your ped model, your framework job, the time and the weather while it runs, so keep it to a test server. Set Config.demoMode back to false before you go live.
Troubleshooting#
| What you see | What to check |
|---|---|
| The old chat still opens, or two chats show | The stock chat resource is still running. Delete its folder and its ensure chat line. |
| Every name is "Unknown" | The console line [lrc] framework bridge: shows what was detected. If it says standalone, start your framework above ncore_chat, or force it with set lrc:framework. A player who hasn't loaded a character yet is "Unknown" too. |
| /pd, /ems or 911 cards reach nobody | They need a framework that gives job and duty. Department channels only take players who are on duty by default, and 911 goes to the jobs in LRCDispatchJobs in config/channels.lua. |
| /photo says photos are not set up | Set the lrc:photoWebhook convar and run screenshot-basic. The endpoint has to answer with the image URL. |
| An avatar stays on the icon | Type lrcmug in F8. It prints which check blocks the headshot and takes a new one. A player who sees only icons has "Use character photo" off in Settings. |
| Everyone has a NEW badge | The week of newCharDays counts from the first time ncore_chat sees a character, so right after you install it every character is new. It goes away on its own, or lower Config.identity.newCharDays. |
| The console warns about webhook settings in the shared config | A URL in config/config.lua was sent to every client. Make a new URL and put it in the lrc: convar with set (a setr convar reaches every client too). |
| A script's chat mode or message rewrite does nothing | Stock addMode / registerMode tables and updateMessage rewrites don't carry over. That script needs a small change. |
| You need more detail for a bug report | setr lrc:debug true prints extra timing lines. |
Docs#
- INSTALLATION.md - setup step by step.
- CHANGELOG.md - what changed in each version. Updates don't install themselves: download the new version, keep your
config/folder and copy the other files over. The changelog lists new settings so you can copy them into your config.
Support#
Support is on intelnpc.com and I reply within 72 hours. It covers installing, configuring and bugs in the script as shipped. Send your framework, server build, the console error and your Tebex transaction ID.
nCore Chat is made by nCore Development. It is not approved, sponsored or endorsed by Rockstar Games.
Requirements#
- FXServer build 6116 or newer. The manifest asks for it, older builds refuse to start the resource.
- OneSync on (
set onesync onin server.cfg, or the OneSync setting in txAdmin). The server reads player positions to route IC speech. - A framework is optional: QBox, QBCore, ESX, ox_core or ND_Core. It gives character names, jobs and duty (departments, 911 cards), money (paid adverts) and items (mask and Darknet item checks). Without one the chat runs standalone: names show as "Unknown", adverts are free, and the department and 911 channels have nobody in them.
- oxmysql is optional. It's only used when you set
Config.logs.database = true(see Database). - No ox_lib and no build step are needed.
Optional resources the chat picks up by itself when they run:
| Resource | What it adds |
|---|---|
| screenshot-basic | /photo (also needs an upload URL, see step 5) |
| pma-voice | radio auto-tune, speech mode sets your mic range, talking ring on avatars |
| ncore_hud | RP mode shared with the HUD, voice range sync, staff toasts for reports and mutes |
| ps-dispatch or cd_dispatch | 911 and 311 calls are forwarded to it as well |
| loaf_headshot_base64 or MugShotBase64 | avatars of players who are far away |
| illenium-appearance, fivem-appearance, esx_skin, qb-clothing, ncore_inventory, ncore_character | your avatar is retaken after an outfit change |
Steps#
-
Copy the
ncore_chatfolder intoresources/[ncore](create the[ncore]folder if you do not have one yet). Do not rename it. -
Remove the stock
chatresource: delete its folder (in the default server data it'sresources/[gameplay]/chat) and removeensure chatfrom server.cfg. ncore_chat provideschat, so resources that listchatas a dependency still start. -
Add ncore_chat to server.cfg. The framework is detected once, at start, so your framework (and oxmysql) go above it. Put it before your other scripts so their chat suggestions arrive.
Standalone
server.cfgensure ncore_chatQBCore
server.cfgensure oxmysql ensure qb-core ensure ncore_chat # your qb- resources after this lineQBox
server.cfgensure ox_lib ensure oxmysql ensure qbx_core ensure ncore_chatESX
server.cfgensure oxmysql ensure es_extended ensure ncore_chat # your esx_ resources after this lineox_core
server.cfgensure oxmysql ensure ox_lib ensure ox_core ensure ox_inventory ensure ncore_chatND_Core
server.cfgensure oxmysql ensure ND_Core ensure ncore_chatOptional resources from the table above can go before or after ncore_chat. screenshot-basic has to be running when a player uses
/photo.If the detection picks the wrong framework, force it above the
ensureline:server.cfgset lrc:framework "qb" # auto | esx | qb | qbx | ox | nd | standaloneOnly force a framework that is really running.
-
Give your staff the staff permission. Framework admins already count as staff (QBCore
adminandgod, QBoxadminandqbx.admin, ox_coreadminandstaffgroups, ND_Coreadmin, ESX every group exceptuser, set inConfig.staff). On any setup, the ACE works too:server.cfgadd_ace group.admin lrc.staff allow add_principal identifier.license:<license> group.adminTwo smaller ACEs let someone do one thing without being staff:
lrc.announcefor/announceandlrc.pinfor pinning messages. -
Optional webhooks. Set these above the
ensureline. They stay on the server and are never sent to players.server.cfgset lrc:logWebhook "https://..." # every channel, private messages included set lrc:logWebhookStaff "https://..." # staff channel and staff actions set lrc:logWebhook911 "https://..." # 911 and 311 set lrc:photoWebhook "https://..." # where /photo uploads go set lrc:photoWebhookField "files[]" # the multipart field name of the uploadThe photo endpoint has to answer with the image URL: JSON with
urlorattachments[1].url, or a plain link in the reply. Withoutlrc:photoWebhook,/phototells the player photos are not set up.Keep the URLs in convars, not in
config/config.lua. A URL in config.lua still works, but that file is also sent to every client, and the console warns you at start. Usesetfor these. Asetrconvar is sent to every client, which would give the URL away again. -
Config.demoModeinconfig/config.luashipsfalse, leave it that way on a live server. On a test server you can set it totrueto try the chat with nobody online: staff get/lrcdemo, which puts ten scripted characters around you in three groups so you can hear the ranges work, and/lrcshowcase, which I use to record videos. The showcase changes the staff member's model, framework job, time and weather while it runs. README.md has the details under "Trying it on a test server". -
Restart the server. The console prints the language and the framework it picked, for example
[lrc] framework bridge: qbx.
Database#
The database is off by default. To turn it on:
- Run oxmysql and start it above ncore_chat.
- Set
Config.logs.database = trueinconfig/config.lua. - Restart. The 7 tables in
sql/ncore_chat.sqlare created at start. Your database user needs CREATE rights, and the JSON columns need MySQL 5.7.8+ or MariaDB 10.2.7+. You can also import the file by hand.
With the database on you get a message archive, saved Chirp posts, report numbers that keep counting after a restart, mutes that survive a restart, and stored avatars.
Logs#
Config.logs.file = true (the default) writes daily files to logs/ inside the resource folder. They hold message text, private messages included, with license and position. Nothing is deleted on its own. Delete old files by hand, or set Config.logs.file = false. Don't zip and share the resource folder with that logs/ folder in it.
lrc_forget <license> in the server console removes a player from the database and from today's log file. Older log files are not touched. README.md has the details.
Good to know#
- Do not run the stock
chatresource next to ncore_chat. - Players' settings are saved on their own PC.
setr lrc:debug trueprints extra timing lines while you look for a problem.- Scripts that use stock
chat:addMode/registerModetables need a small change. Everything else written for the stock chat keeps sending to it.
Updates don't install themselves. When a new version is out, download it again (escrow from your Cfx.re account, full source from Tebex), keep your own config/ folder, and copy every other file over the old ones. Settings added in a new version are listed under that version, so you can copy them into your config. New versions are announced on intelnpc.com.
1.0.9#
First public release. Everything the script does is listed in README.md.
€19.99
Ready when you are
Instant delivery, checkout right here on the site, and a Discord full of people who will answer before you pay.

