Every docs URL answers with Markdown when you add .md. Site map: llms.txt
Code optimisation
Writing FiveM Lua that stays fast and readable: scope, functions, tables, loops, natives, events, exports and error handling, with the reason behind each rule.
Ta dokumentacja jest na razie po angielsku.
Two resources can do the same job and cost wildly different amounts. One sits at 0.01 ms in resmon and the other burns 0.80 ms every frame doing nothing. The difference is almost never a clever trick. It is a handful of habits: what runs in a loop, what crosses the network, what crosses a resource boundary, and how much work each line asks for.
This section is those habits, with the reason behind each one. Most of it also makes the code easier to read, which is the part that pays off six months later when you have to change it.
Where this comes from
The structure and most of the ideas here follow Effective FiveM Lua by manason, a short handbook on writing better Lua for FiveM. It is worth reading in full, and it covers the same ground from the author’s own angle.
The text on these pages is ours, the examples are ours, and where a claim was checkable we checked it against the Cfx docs and the CitizenFX and Lua sources before repeating it. A few points are stated differently here because the underlying detail turned out to be different from the common version of it. Where that happens, the page says so.
What these pages assume
- Your scripts run on CfxLua, the modified Lua 5.4 that FiveM ships. That matters for a few of the notes below.
- Client code shares the game frame. At 60 FPS you have about 16 ms per frame for GTA and every resource together. A client resource that takes 1 ms per frame is eating 6% of that on its own.
- Server code shares one tick. Long running Lua on the server delays everything behind it, including sync.
The order the wins come in
Work down this list, not up it. The top items are worth hundreds of times what the bottom ones are worth.
- Does it run at all? A loop that wakes 60 times a second to check a distance you could have checked once a second is the single most common cost in FiveM resources.
- How much does one pass do? Forty distance checks per frame, a table built per frame, a string concatenated per frame.
- What crosses a boundary? Events over the network and export calls into other resources both pack and unpack your data. Big payloads and chatty calls cost real time.
- What does one line cost?
table.insertagainstt[#t + 1], a global lookup against a local. These are real, and they are small. Write the cheap form when you write the line, do not rewrite working code for them.
Tip
Start with Measure before you optimise. Guessing which resource is heavy is how people spend an afternoon micro tuning a loop that runs twice a day.
Pages in this section
| Page | What it covers |
|---|---|
| Measure before you optimise | resmon, the profiler, and what the numbers actually mean. |
| Scope, files and layout | Local by default, the visibility ladder, file and resource naming, manifest order. |
| Functions that stay small | One job per function, naming, parameters, closures in hot paths, annotations. |
| Variables, constants and enums | Naming, where to declare, locals against globals, states that are not booleans. |
| Conditionals and early returns | Guard clauses, or defaults and their trap, positive conditions. |
| Tables and loops | Array building, pairs against numeric for, cached lookups, garbage. |
| Cheap native calls | Backtick hashes, joaat, vector distance, caching handles, per frame natives. |
| Events that stay cheap and safe | Naming, local against net events, callbacks, payload size, source. |
| Exports and resource boundaries | What an export call really does, keeping payloads small, shared files. |
| Error handling | Assertions, preconditions, failing loudly against returning an error. |
For the wider context, the Development section covers threads and performance, natives, state bags and debugging.
