Skip to content
Tutorial
Best Coding Practices

Best Coding Practices

This section will cover the best coding practices for Fivem and the ESX Legacy Framework.

Programming style

It is important to follow a consistent programming style when writing code. This makes it easier for you and others to read and understand your code. This section displays some general guidelines you should follow when writing code.

Naming conventions

There are different naming conventions for different programming languages and for Lua camelCase is used. This means that the first letter of the first word is lowercase and the first letter of each subsequent word is uppercase. For example, myVariableName. But this changes slightly with global functions and global variables which will additionally will start with a uppercase. For example, MyGlobalVariableName.

Constants

Use constants to highlight things that should not be modified / Constants are variables that are not supposed to change while the script is running.

Constants should be written in uppercase and separated by underscores. For example, MY_CONSTANT. If you have Lua 5.4 enabled you can also use the const keyword to define constants. Example:

local MY_CONSTANT <const> = 42
MY_CONSTANT = 43 -- This will throw an error

Indentation

Indentation is important for readability. It is recommended to use 2 spaces for indentation.

DRY

DRY stands for “Don’t Repeat Yourself”. It is a software development principle that states that you should avoid duplicating code. Instead, you should write reusable code that can be used in multiple places.

Comments

Comments are important for explaining what your code does. It is recommended to use comments to explain what your code does and why you wrote it that way.

For more information check the Annotations section.

Globalization and Localization

MyGlobalVariable = 42 -- This is a global variable
local myLocalVariable = 42 -- This is a local variable

Globals

Minimize the use of global variables and functions. They can be accessed throughout your entire script, leading to unpredictable behavior, increased memory usage, and access overhead. Favor local variables for their scope limitation.

Local

Use local variables and functions whenever possible. Local variables are faster to access than global variables and are only accessible within the scope/file they are defined in.

Loops

When using loops, it is important to use the correct loop for the task at hand. For example, use a for loop when you know the number of iterations you need, and use a while loop when you need to loop until a condition is met.

⚠️

When using a while loop make sure it has a Wait in it. Otherwise, it will crash the server.

Infinite loops

Make sure to avoid infinite loops. Infinite loops can cause your script to use more resources and lag your server and players. If possible make sure to have a condition that will eventually be false.

Example for don’t do

CreateThread(function()
    while true do
        Wait(0)
        if ESX.PlayerData.job.name == 'police' then
            if IsControlJustPressed(0, 38) then
                -- Do something
            end
        end
    end
end)

Example for do

AddEventHandler('esx:setJob', function(job)
    if job.name == 'police' then
        startPoliceThread()
    end
end)
 
local function startPoliceThread()
    CreateThread(function()
        while ESX.PlayerData.job.name == 'police' do
            Wait(0)
            if IsControlJustPressed(0, 38) then
                -- Do something
            end
        end
    end)
end
 
if ESX.PlayerData.job.name == 'police' then
    startPoliceThread()
end

Wait times

When using loops, it is important to have a Wait time. It is necessery to have atleast a Wait(0) or the server/client will crash. The Wait function is used to pause the execution of the script for a specified amount of time.

So when you are using a loop think about how often you need your thread to run and adjust the Wait time accordingly.

Caches

Caching is a technique used to store data that is frequently accessed. This can help improve performance by reducing the number of times data needs to be fetched from the database, calculated or get using ressource intensive natives.

⚠️

Make sure to only cache what you need and how much you need.

Example

local localPlayerId = PlayerId()
local serverId = GetPlayerServerId(localPlayerId)
local ped = PlayerPedId() -- Important to listen to if the player ped changes.
 
AddEventHandler('esx:playerPedChanged', function(newPed)
    ped = newPed
end)

General Optimization

Optimization is important for performance. It is important to optimize your code to make it run as fast as possible. This section will cover some general optimization techniques you can use to improve the performance of your scripts.

Avoid unnecessary or reconcurrent calculations

Avoid unnecessary or reconcurrent calculations. If you have a calculation that is done multiple times, consider caching the result and reusing it.

Tables

Tables are a powerful data structure in Lua, but it is resource intensive. It is important to use tables wisely and avoid creating unnecessary tables. And only have the data you still need in the table. Once data is not needed anymore remove it from the table.

Use newest methods

Lua, FiveM and ESX are constantly being updated with new features and improvements and new more efficient ways are often found. Make sure to keep up to date with the latest changes and use the newest methods available.

Popular outdated or replaced functions

  • GetPlayerPedId(-1) -> PlayerPedId() Getting the player Ped.
  • GetDistanceBetweenCoords(x1, y1, z1, x2, y2, z2, true) -> #(vector3(x1, y1, z1) - vector3(x2, y2, z2)) Getting the distance between two points.
  • GetHashKey('adder') -> joaat('adder') Getting the hash of a string/model.
  • table.insert(table, value) -> table[#table + 1] = value Inserting a value into a table.
  • table.remove(table, index) -> table[index] = nil Removing a value from a table.

Lua 5.4

Lua 5.4 is the latest version of Lua and it comes with some new features and improvements. If you have Lua 5.4 enabled you can also use it’s features in your fivem script.

Features

  • const & close keyword for defining constants and making sure memory is freed safely.
  • goto statement.
  • Generational GC (Garbage Collector).
  • Overall faster
  • Compound assignment operators (+=, -=, *=, /=, %=, ^=, ..=, &=, |=, <<=, >>=, >>>=).
  • And much more.