
rep-talkNPC
A versatile and customizable NPC Dialogue system for FiveM servers, offering fresh UI designs and highly configurable elements for a richer gaming experience. Built for the QBCore and ESX frameworks.
INSTALLATION
Download a release HERE or build the source code from LINK.
git clone https://github.com/BahnMiFPS/rep-talkNPC.git cd rep-talkNPC/web pnpm i pnpm build
Drag and drop the folder into your project and ensure it in your FiveM server.cfg.
UI Changes
Navigate to the
/web
folder to start modifying the UI.Run
pnpm start
in your terminal to launch the UI in your local web environment.Post modifications, execute
pnpm build
followed by a script restart in-game to see your changes.
Script Usage
Examples
Refer to
cl_ex.lua
where we've set up a/testnpc
command enabling you to spawn a sample NPC on your server.We have also included the code snippet that we used in the feature video for your future reference.

Exports (Client Side)
exports['rep-talkNPC']:CreateNPC(npc, elements)
npc:
table
(object
)npc:
string
coords:
vector4
animName, animDist / animScenario:
string
tag:
string
color:
string
startMSG:
string
elements:
table
label:
string
shouldClose:
boolean
action:
function
canInteract:
function
exports['rep-talkNPC']:changeDialog(label, elements)
label:
string
elements:
table
label:
string
shouldClose:
boolean
action:
function
canInteract:
function
exports['rep-talkNPC']:updateMessage(label)
label:
string
TRIGGERS
TriggerEvent('rep-talkNPC:client:close')
TriggerClientEvent('rep-talkNPC:client:close', source)
This event is used to shut down the dialogue.
EXAMPLE : rep-sanitation
function talkNPC()
bossNpc = exports['rep-talkNPC']:CreateNPC({
npc = "s_m_y_garbage",
coords = vector4(-351.44, -1566.37, 24.22, 314.22),
name = 'Brook Stream',
animScenario = 'WORLD_HUMAN_CLIPBOARD',
tag ="Sanitation Employees",
color = "#73583e",
startMSG = 'Hello, how can I assist you?',
}, {
[1] = {
label ="How does this job work?",
shouldClose = false,
action = function()
exports['rep-talkNPC']:changeDialog("Hello, new here? Let me explain \n \n First, you need a tablet, then apply for a job here. \n \n You can work faster if you work with your friends. You can go 4 and move 2 points at a time. \n \n Oh, little tip, the food at Owo Cafe can help you stay awake to get more tips.",
{
[1] = {
label = "I want to start working",
shouldClose = false,
action = function()
if onDuty == false then
if LocalPlayer.state.nghe == nil or LocalPlayer.state.nghe == "sani" then
exports['rep-talkNPC']:updateMessage(Lang.bossNpc.button1[4])
Wait(1000)
TriggerEvent('rep-talkNPC:client:close')
TriggerEvent('rep-sanitation:client:onDuty')
else
Framework.Notification(Lang.error.own_job.label, Lang.error.own_job.type, Lang.error.own_job.time)
end
else
exports['rep-talkNPC']:updateMessage("You already have this job")
end
end
},
[2] = {
label = "Oh, it doesn't seem to suit me",
shouldClose = true,
action = function()
end
}
}
)
end
},
[2] = {
label = "I want to take the job",
shouldClose = false,
action = function()
if LocalPlayer.state.nghe == nil or LocalPlayer.state.nghe == "sani" then
exports['rep-talkNPC']:updateMessage("Now turn on your tablet to find or create a group for yourself!",)
TriggerEvent('rep-sanitation:client:onDuty')
Wait(2000)
TriggerEvent('rep-talkNPC:client:close')
else
Framework.Notification(Lang.error.own_job.label, Lang.error.own_job.type, Lang.error.own_job.time)
end
end,
canInteract = function ()
if onDuty then
return false
end
return true
end
},
[3] = {
label = "I want quit the job",
shouldClose = false,
action = function()
TriggerEvent('rep-sanitation:client:offDuty')
exports['rep-talkNPC']:updateMessage("It's sad to say goodbye to you")
Wait(2000)
TriggerEvent('rep-talkNPC:client:close')
end,
canInteract = function ()
if not onDuty then
return false
end
return true
end
},
[4] = {
label = "I want rent a vehicle",
shouldClose = true,
action = function()
if not IsPositionOccupied(Config.Vehicle.spawnpos.x, Config.Vehicle.spawnpos.y, Config.Vehicle.spawnpos.z, 3, false, true, true, false, false, 0, false) then
vehSpawnicle()
else
Framework.Notification(Lang.error.occupied.label, Lang.error.occupied.type, Lang.error.occupied.time)
end
end,
canInteract = function()
local IsGroupLeader = exports['rep-tablet']:IsGroupLeader()
if onJob and not vehSpawn and IsGroupLeader then
return true
end
return false
end
},
[5] = {
label = "I want turn in vehicle",,
shouldClose = true,
action = function()
returnVehicle()
end,
canInteract = function()
local IsGroupLeader = exports['rep-tablet']:IsGroupLeader()
return doneJob and IsGroupLeader and onJob
end
},
[6] = {
label = "I want to exchange materials",
shouldClose = true,
action = function()
exchangeSystem()
end,
canInteract = function()
return Config.Exchange.status
end
},
[7] = {
label = "I'm just passing through here",
shouldClose = true,
action = function()
end
}
})
end
Last updated