In this article, we'll explore methods to optimize your FiveM scripts for better performance and efficiency. We will also discuss some of the most common performace pitfalls and how to avoid them.
When using FiveM natives you should consider the following:
for k,v in pairs(something) do
local ped = PlayerPedId()
-- do something with ped
end
local ped = PlayerPedId()
for k,v in pairs(something) do
-- do something with ped
end
In the unoptimized code, PlayerPedId()
is called every iteration of the loop. By storing the result of PlayerPedId()
in a variable before the loop, you reduce the number of native calls, which enhances performance.
Many scripts use GetPlayerPed(-1)
. However, PlayerPedId()
serves the same purpose but is less costly in terms of performance.
local ped = PlayerPedId()
PlayerPedId()
is more efficient than GetPlayerPed(-1)
. Always prefer using PlayerPedId()
to reduce unnecessary performance overhead.
When checking a player's distance from a point, using Lua's vector mathematics is more efficient than native functions like Vdist
, Vdist2
, or GetDistanceBetweenCoords
.
local distance = Vdist(playerPos.x, playerPos.y, playerPos.z, point.x, point.y, point.z)
local pos1 = vector3(0.0, 10.0, 0.0)
local pos2 = vector3(0.0, 10.0, 10.0)
local dist = #(pos1 - pos2) -- Subtract the vectors and return the distance with #
Lua's built-in vector operations are more efficient and can reduce script execution time compared to the native distance functions.
Not all loops need to run every frame. Increasing the delay between iterations using Wait()
can greatly improve performance. It's also beneficial to separate loops based on their frequency of execution.
It might also be benificial to split up loops to make them more efficient.
Citizen.CreateThread(function()
while true do
local ped = PlayerPedId()
local coords = GetEntityCoords(ped)
local dist = #(markerCoords - coords) -- markerCoords should be vec3
if dist < 50.0 then -- Don't draw marker if far away
DrawMarker(someplace, markerRadius)
if dist < markerRadius then -- If inside the marker, do some stuff, like show a menu etc.
-- do something
end
end
Wait(0) -- Wait until next frame
end
end)
local markerInRange = false
-- Thread to check distance
Citizen.CreateThread(function()
while true do
local ped = PlayerPedId()
local coords = GetEntityCoords(ped)
local dist = #(markerCoords - coords) -- markerCoords should be vec3
if dist < 50.0 then
markerInRange = true
if dist < markerRadius then -- If inside the marker, do some stuff, like show a menu etc.
-- do something
end
else
markerInRange = false
end
Wait(500) -- Run this loop every 500 milliseconds
end
end)
-- Thread to draw the marker
Citizen.CreateThread(function()
while true do
if markerInRange then
DrawMarker(someplace, markerRadius)
Wait(0) -- Run every frame when marker is in range
else
Wait(500) -- Run this loop every 500 milliseconds when marker is out of range
end
end
end)
By separating the distance check from the marker drawing and adjusting the wait times appropriately, you can significantly reduce the load on your script, resulting in smoother performance. The distance check only needs to run twice per second, while the drawing function should run every frame when the marker is in range.
Implementing these optimizations will help you create more efficient and performant FiveM scripts. Reducing native calls, using efficient distance checks, and properly managing loop intervals are key practices for script optimization. By following these techniques, you can enhance the gameplay experience by reducing latency and improving overall performance.