JRS COREDocumentação
Links úteis

LUA Documentation

A practical Lua 5.4 reference for RedM scripting, with the Cfx.re extensions

Site oficial · www.lua.org ↗

RedM resources run on Lua 5.4 when the manifest has lua54 'yes'. This page covers the language as you use it in resources, plus what Cfx.re adds. The complete language manual is at lua.org/manual/5.4.

Values and types#

Lua has eight types: nil, boolean, number, string, table, function, thread (coroutine) and userdata.

lua
print(type(nil), type(true), type(10), type(1.5), type('x'), type({}), type(print))
-- nil boolean number number string table function
  • Only nil and false are false. 0 and '' are true.
  • Numbers are either integers or floats. 10 // 3 is integer division (3), 10 / 2 is always a float (5.0), math.type(5) returns 'integer'.
  • Strings are immutable byte sequences. Use .. to join and #s for the length in bytes.

Variables and scope#

lua
local count = 0              -- local to the block: always prefer this
globalVar = 1                -- global: shared by every file of the resource, avoid
local a, b = 1, 2            -- multiple assignment
a, b = b, a                  -- swap
local max <const> = 100      -- constant (5.4): assignment is an error

A local is visible until the end of the block (do ... end, function, loop body). Locals are faster than globals and cannot be overwritten by another script.

Operators#

Kind Operators
Arithmetic + - * / // % ^ (^ is power, always float)
Comparison == ~= < <= > >= (not equal is ~=, not !=)
Logic and or not (a and b or c is the usual ternary)
String .. concatenation, # length
Bitwise & \| ~ << >> ~ (~ is xor when binary, not when unary)
lua
local label = player and player.name or 'unknown'
local half = total // 2

Control flow#

lua
if hp <= 0 then
    die()
elseif hp < 30 then
    limp()
else
    walk()
end

for i = 1, 10 do end            -- 1..10
for i = 10, 1, -1 do end        -- counting down
for i, v in ipairs(list) do end -- array part, in order, stops at the first nil
for k, v in pairs(map) do end   -- every key, order not guaranteed
while cond do end
repeat until cond

break leaves a loop. goto continue with a label ::continue:: at the end of the loop body is the idiom for "next iteration".

Functions#

lua
local function add(a, b) return a + b end

local function stats(list)
    return #list, list[1]           -- several return values
end
local n, first = stats({4, 5, 6})

local function log(fmt, ...)       -- variable arguments
    print(string.format(fmt, ...))
end

local fn = function(x) return x * 2 end   -- anonymous function / closure

Functions are values and closures keep the locals they use. select('#', ...) counts the arguments, table.pack(...) collects them, table.unpack(t) spreads a table.

Tables#

The table is the only data structure: it is the array, the map, the object and the set.

lua
local list = { 'a', 'b', 'c' }          -- list[1] == 'a'  (Lua starts at 1)
local map = { name = 'Arthur', cash = 12.5 }
local set = { police = true, doctor = true }   -- fast membership test: set[job]

list[#list + 1] = 'd'                   -- append
table.insert(list, 'e')
table.insert(list, 1, 'first')          -- insert at position
table.remove(list, 1)                   -- remove at position
print(#list)                            -- length of the array part
Function Use
table.insert(t, [pos,] v) / table.remove(t [, pos]) Add or remove an element.
table.concat(t, sep) Join strings, much faster than .. in a loop.
table.sort(t [, cmp]) In place sort. The comparison must be a strict "less than".
table.unpack(t, i, j) / table.pack(...) Spread or collect values.
table.move(a, f, e, t [, a2]) Copy a range.
next(t) nil when the table is empty, cheaper than counting.

Gotchas: #t is only reliable on arrays without holes. Assigning nil removes a key. Tables are passed by reference: copy with a loop when you need an independent copy.

lua
local function deepCopy(v)
    if type(v) ~= 'table' then return v end
    local out = {}
    for k, x in pairs(v) do out[k] = deepCopy(x) end
    return out
end

Strings#

lua
local s = 'Hello'
print(s:upper(), s:lower(), s:len(), s:sub(2, 4), s:rep(2, '-'))
print(('%s has $%.2f'):format('Arthur', 12.5))
print(('a,b,c'):find(',', 1, true))      -- plain search: start, end
for word in ('one two'):gmatch('%a+') do print(word) end
print(('x=1'):gsub('%d', '9'))           -- replace, returns text and count

string.format specifiers: %s string, %d integer, %f / %.2f float, %x hex, %q quoted, %% a percent sign.

Patterns are not regular expressions:

Class Matches Quantifier Meaning
%a letter * 0 or more
%d digit + 1 or more
%s space - 0 or more, shortest
%w letter or digit ? 0 or 1
%p punctuation ^ / $ start / end of the string
. any character ( ) capture

Escape a magic character with %: %. is a literal dot.

Metatables#

A metatable changes how a table behaves. It is how classes are built.

lua
local Vec = {}
Vec.__index = Vec

function Vec.new(x, y) return setmetatable({ x = x, y = y }, Vec) end
function Vec:len() return math.sqrt(self.x ^ 2 + self.y ^ 2) end
Vec.__add = function(a, b) return Vec.new(a.x + b.x, a.y + b.y) end
Vec.__tostring = function(v) return ('(%s, %s)'):format(v.x, v.y) end

local v = Vec.new(3, 4) + Vec.new(0, 0)
print(v:len(), tostring(v))   -- 5.0  (3, 4)

Common metamethods: __index, __newindex, __call, __tostring, __len, __eq, __lt, __le, __concat, __close, and the arithmetic family (__add, __sub, __mul, __div, ...). obj:method(x) is shorthand for obj.method(obj, x).

Errors#

lua
local ok, err = pcall(function() error('boom') end)
if not ok then print('failed:', err) end

local ok2, res = xpcall(risky, debug.traceback)   -- keeps the stack trace
assert(type(x) == 'number', 'x must be a number')

Wrap code that may fail because of outside input (JSON, database results) in pcall; do not hide your own bugs with it.

Math#

math.floor, math.ceil, math.abs, math.min, math.max, math.sqrt, math.sin, math.cos, math.pi, math.huge, math.random(m, n), math.randomseed(x), math.tointeger(x), math.fmod(a, b).

lua
local function round(n, places)
    local m = 10 ^ (places or 0)
    return math.floor(n * m + 0.5) / m
end

Never use math.random for anything that must be fair or secret (rewards that matter, tokens): do the roll on the server and check it.

Coroutines#

lua
local co = coroutine.create(function(a)
    local b = coroutine.yield(a + 1)
    return b * 2
end)
print(coroutine.resume(co, 1))    -- true 2
print(coroutine.resume(co, 10))   -- true 20

In RedM you rarely create coroutines yourself: CreateThread and Wait do it for you.

What Cfx.re adds#

Feature Example
Hash literal `a_c_horse_arabian_white` gives the model hash
Vectors vector3(1.0, 2.0, 3.0), vec3, vector2, vector4; + - *, #v length, .x .y .z
json json.encode(t), json.decode(s)
Compound assignment n += 1, s ..= 'x' (Cfx only)
Safe navigation config?.blip?.sprite returns nil instead of an error
Threads CreateThread(fn), Wait(ms), SetTimeout(ms, fn)
Promises promise.new(), Citizen.Await(p)
Events RegisterNetEvent, AddEventHandler, TriggerEvent, TriggerServerEvent, TriggerClientEvent
Exports exports('Name', fn) and exports.resource:Name()
Msgpack msgpack.pack, msgpack.unpack

The Cfx extensions are not plain Lua: an editor or linter without Cfx support may flag them, and the code will not run outside the game.

Performance#

  • Keep hot loops free of table creation and string concatenation.
  • Cache PlayerPedId(), GetEntityCoords(ped) and similar natives once per loop turn.
  • Use a table as a set for membership tests (allowed[job]) instead of looping an array.
  • Build text with table.concat, not .. in a loop.
  • Sleep: Wait(1000) while idle, Wait(0) only while something visible needs every frame.
  • Avoid pairs on huge tables in frame loops; keep a precomputed list.

Common mistakes#

Mistake Fix
if x != 1 Use ~=
list[0] Lua arrays start at 1
Using a global by accident (coords = ...) Write local coords
string.sub with a 0 start Start at 1
Comparing a float to an integer with == for money Round to cents and compare integers
Waiting on a client value on the server Ask the client with a callback and validate the answer

Credits#

Lua is created by PUC-Rio and released under the MIT license. The authoritative text is the Lua 5.4 Reference Manual.

JRS Core · Framework RedM gratuito e de código aberto · feito pela JRS TEAM