START HERE·LUA FROM ZERO·Verified June 2026 · Lua 5.4 · ox_lib 3.x
Learning with an AI assistant?
Copies this whole lesson - every step, code block, and the exact console errors - plus 2026 ground rules (no lua54 'yes', Cfx.re Portal, correct callback signatures) as a ready-to-paste mentor prompt.
Start Here · Lua from zero

Functions: write it once, run it anywhere

Up to now you have written code that runs top to bottom, once. A function changes that. It is a named block of code you write one time and then run whenever you want, as many times as you want, just by saying its name. Every real FiveM resource is built out of functions, so this is the lesson where your code stops being a script and starts being a tool.

You'll learn
How to define a function, pass values into it with parameters, get a result back with return, and why local functions are the safer default.
Time
~10 minutes
Difficulty
Beginner
You need
Nothing to install. You will run plain Lua right here in your browser. If you skipped the loops lesson, do that first.
BEFORE YOU START

What a function is

Imagine you have three lines of code that print a welcome message. If you need that welcome in five different places, you could copy those three lines five times. Now you have fifteen lines, and the day you want to change the wording you have to find and fix all five copies. That is how bugs are born.

A function solves this. You write the steps once, give that block a name, and from then on you just say the name to run all of it again.

Here is the shape of a function in Lua:

lua
function name(parameters)
  -- the code that runs goes here
end

Read it left to right. The word function tells Lua "a block of reusable code starts here". name is the label you choose so you can find it again later. The parentheses () hold the values the function expects to receive. Everything between the opening line and end is the body: the actual steps. The word end marks where the function stops, the same way it does for a loop.

Writing the function does not run it. Lua just reads it and remembers it, like saving a recipe in a drawer. To actually run the steps, you call the function by writing its name followed by parentheses:

lua
name()

That is the whole idea: define once, call many times.

Vocabulary

function
A named block of code you write once and run whenever you want by calling its name.
parameter
A named slot in the function definition that stands in for a value you will pass in later. It lives inside the parentheses.
argument
The actual value you hand to the function when you call it. It fills the parameter slot.
return value
A result the function hands back to whoever called it, using the return keyword.
call
To run a function by writing its name followed by parentheses, like greet().

Parameters and arguments

A function gets much more useful when you can feed it different values each time you run it. That is what the parentheses are for.

When you define a function, the names you write inside the parentheses are parameters. Think of a parameter as an empty box with a label on it, waiting to be filled.

lua
function greet(name)
  print("Welcome, " .. name)
end

Here name is a parameter. Inside the body it acts like a normal variable, but its value is whatever the caller decides. The .. is Lua's way of gluing two pieces of text together, so "Welcome, " .. name becomes one string.

When you call the function, the value you actually put inside the parentheses is an argument. The argument fills the parameter box.

lua
greet("Quasar")

Here "Quasar" is the argument. Lua takes it, drops it into the name box, and runs the body, so it prints Welcome, Quasar.

The distinction is gentle but worth getting right once: the parameter is the name in the definition (the empty box), and the argument is the value you pass at the call (what goes in the box). Same slot, two moments. You write parameters when you build the function; you supply arguments when you run it.

A quick way to remember it: Parameter is the Placeholder, Argument is the Actual value. Both start with the same letter as the word that describes them.

See it run

Theory is enough. Press RUN below to execute this on real Lua, right in your browser. There is no FiveM here, just plain Lua, so the same print you would use on a server works exactly the same way.

sandbox.luaLUA 5.4
OUTPUT
Press RUN to execute.

Look at what happened. You defined greet once. Then you called it twice with two different arguments, and it ran the same body both times, producing a different line each time. That is the payoff: one block of logic, reused with whatever value you hand it.

Returning a value

Printing is one job, but most functions do not print. They calculate something and hand the result back so the rest of your code can use it. The keyword for handing a result back is return.

When Lua hits a return, it stops the function immediately and sends that value back to wherever the function was called. You usually catch the returned value by storing it in a variable.

lua
local function double(n)
  return n * 2
end
 
local result = double(5)
print(result)

Walk through it. You call double(5), so the argument 5 fills the parameter n. Inside, n * 2 works out to 10, and return sends 10 back. The call double(5) effectively becomes the value 10, which gets stored in result. Then print(result) shows it.

Try it:

sandbox.luaLUA 5.4
OUTPUT
Press RUN to execute.

A function without a return still does its work, but when you try to store its result you get nil, which is Lua's word for "no value". If you ever expect a number and get nil, a missing return is the first thing to check.

local vs global functions

You may have noticed the word local in front of the last few functions. That single word matters more than it looks.

When you write local function double(...), the function exists only inside the current file. Nothing outside that file can see it or accidentally collide with it. When you leave local off and write just function double(...), you create a global function: one that is visible everywhere, across every script running on the server.

A FiveM server runs many resources at once, and they all share one global space. If two different resources both define a global function called setup, the one that loads last silently overwrites the other, and now something breaks for a reason that is almost impossible to trace. Keeping your functions local walls them off inside your own file, so they cannot clash with anyone else's. Make local your default. Only drop it when you genuinely need other files to reach the function.

This is a habit, not a one-off rule. Start it now on plain Lua and it will already be second nature by the time you write your first real resource.

Common beginner mistakes

SymptomFix
attempt to call a nil value (global 'greet')The function is defined after it is called, or the name is misspelled. Lua reads top to bottom, so define the function before you call it, and check the spelling exactly. Lua is case sensitive, so greet and Greet are two different names.
the function prints fine but you get nil when you store its resultYou forgot to return a value. Printing inside a function does not hand anything back. Add a return line so the function actually returns the result you want to store.
What is the difference between a parameter and an argument?

A parameter is the name you write inside the parentheses when you define the function. It is an empty slot waiting for a value. An argument is the actual value you put inside the parentheses when you call the function. The argument fills the parameter. In function greet(name) the word name is the parameter, and in greet("Quasar") the text "Quasar" is the argument.

Try it yourself

What you can do now

  • Define a function with function name(...) ... end and call it by writing its name followed by parentheses.
  • Tell a parameter (the name in the definition) apart from an argument (the value you pass at the call).
  • Pass different arguments to reuse the same function with different values.
  • Hand a result back to the caller with return, and store it in a variable.
  • Default to local functions so your code never collides with other resources on a shared server.

Functions give your code a vocabulary: named actions you can reuse anywhere. The missing piece now is a way to hold lots of related values together, because real FiveM data, a player, a vehicle, a config, is never just one number. That structure is the table, and almost everything in FiveM is built on it. Next up: "Tables: Lua's everything box".