Kahibaro
Discord Login Register

2.2.3 Functions

Why Functions Matter in Your Scripts

When you start writing longer scripts in Lua, you will often repeat the same kind of logic in multiple places. You might also have pieces of code that feel like they belong together as a single action, such as giving a player coins or resetting a level. Functions give you a way to group related code, give that group a name, and run it whenever you want, without copying and pasting.

A function is a named block of code that runs only when you call it. Functions help keep your scripts shorter, easier to read, and easier to change. If you fix a bug inside a function, every place that uses that function gets the fix automatically.

In Roblox Lua, you will use functions all the time, both the ones you write yourself and the ones provided by Roblox APIs, such as print, wait, or math.random.

Defining a Simple Function

To create a function in Lua you use the function keyword, give it a name, write its body, and then end it with end.

Here is the basic structure:

function FunctionName()
    -- code that runs when the function is called
end

This does not run immediately when the script starts. It only defines the function so that you can call it later.

For example:

function greetPlayer()
    print("Hello, player!")
end

At this point greetPlayer exists, but nothing has printed yet. To actually run the code inside the function you must call it.

Calling a Function

Calling a function means telling Lua to execute the code inside it. You do this by writing the function name followed by parentheses.

Using the previous example:

function greetPlayer()
    print("Hello, player!")
end
greetPlayer()
greetPlayer()

This prints:

Hello, player!
Hello, player!

The same function code runs every time you call greetPlayer. You can call a function from anywhere in your script, as long as the function has been defined before that point in the code. How definition order interacts with visibility will be covered more deeply when you learn about scope, but for now, define simple functions before you use them.

Functions With Parameters

Sometimes a function needs information to do its job. Parameters are variables listed inside the function definition parentheses. They act like placeholders for values you pass in when you call the function.

Here is the structure:

function FunctionName(parameter1, parameter2)
    -- use parameter1 and parameter2 inside
end

For example:

function greetPlayer(playerName)
    print("Hello, " .. playerName .. "!")
end
greetPlayer("Alex")
greetPlayer("Jordan")

This prints:

Hello, Alex!
Hello, Jordan!

Inside the function, playerName behaves like a local variable that holds whatever value you passed in for that call. You can have more than one parameter:

function addCoins(playerName, amount)
    print(playerName .. " received " .. amount .. " coins.")
end
addCoins("Alex", 10)
addCoins("Jordan", 25)

You do not declare parameter types in Lua. You only give them names, and it is your responsibility to pass in the right kinds of values when you call the function.

Default-Like Behavior With `nil` Parameters

Lua does not support default parameter values directly in the function definition, but you can simulate defaults by checking if parameters are nil inside the function body and assigning your own value.

For example:

function greetPlayer(playerName)
    if playerName == nil then
        playerName = "Player"
    end
    print("Hello, " .. playerName .. "!")
end
greetPlayer("Alex")   -- uses "Alex"
greetPlayer()         -- uses "Player"

This is a common pattern when you want your function to behave reasonably even when a caller leaves out some values.

Returning Values From Functions

Functions can send a result back to the place where they were called. This is called returning a value. You use the return keyword to do this.

The general pattern is:

function FunctionName(parameters)
    -- do some work
    return someResult
end

Here is a simple math example:

function add(a, b)
    local sum = a + b
    return sum
end
local result = add(3, 5)
print(result)  -- prints 8

When add(3, 5) runs, it calculates sum, then return sum sends the value 8 back. The caller stores this in result.

You can also return expressions directly:

function multiply(a, b)
    return a * b
end

The return statement also stops the function immediately. Any code after return in the same function will not run.

Multiple Return Values

Lua functions can return more than one value at a time. You separate them with commas after return.

For example:

function divideAndRemainder(a, b)
    local quotient = a // b
    local remainder = a % b
    return quotient, remainder
end
local q, r = divideAndRemainder(10, 3)
print(q)  -- 3
print(r)  -- 1

The first returned value is assigned to q and the second to r. If you assign to only one variable, extra return values are ignored.

This feature becomes very useful when you want a function to provide several related results without using tables.

Local Functions vs Global Functions

In Lua, a function is just a value stored in a variable. When you write:

function greet()
    print("Hi")
end

Lua actually creates a global variable named greet that holds the function. A global function can be called from any script that can access that global name, which can lead to name conflicts and surprises in larger projects.

You can instead define functions as local. A local function is only visible within the chunk or block where it is defined. This is safer and is the usual style for functions inside one script.

A local function looks like this:

local function greet()
    print("Hi")
end
greet()

Since greet is local, other scripts cannot see it. You will learn more about what counts as a scope when you study scope in its own chapter, but for now remember that you should prefer local function unless you have a good reason to make a function global.

Important rule:
Prefer local function for functions that are only used inside one script. This reduces bugs and name conflicts.

Anonymous Functions and Using Functions as Values

Because functions are values, you can store them in variables, pass them as arguments to other functions, or even define them without giving them a name. A function without a name is called an anonymous function.

Here is an anonymous function stored in a variable:

local greeter = function(name)
    print("Hello, " .. name)
end
greeter("Alex")

Roblox APIs often expect you to pass a function as a callback, especially when dealing with events. For example, you might write:

someEvent:Connect(function()
    print("The event happened!")
end)

You will learn more about connecting functions to events when you reach the Roblox specific scripting chapters. For now, it is enough to understand that functions can be created inline and passed around like any other value in Lua.

Early Returns and Guard Clauses

Often, a function should stop running if some condition is not met. For example, maybe a player is not allowed to buy an item if they do not have enough coins. Instead of wrapping the whole function body inside an if block, you can use an early return.

A typical pattern looks like this:

local function buyItem(playerCoins, price)
    if playerCoins < price then
        print("Not enough coins.")
        return
    end
    print("Purchase successful.")
    -- more purchase code here
end

The return inside the if block exits the function immediately if the condition fails. This keeps the rest of the function less indented and easier to read.

This style of writing checks early and returning is sometimes called using guard clauses. It is especially helpful in longer functions that have several reasons to stop early.

Organizing Your Code With Functions

Functions are not just about reusing code. They are also about organizing your script into clear steps. For example, you might have a script that wants to:

  1. Setup the game.
  2. Wait for players to join.
  3. Start the round.
  4. End the round and give rewards.

Instead of writing one very long block of code, you can split it into separate functions, such as setupGame, waitForPlayers, startRound, and endRound. Then your main script can call these functions in order. This makes it much easier to read and later modify.

Functions can also help you give your code meaningful names. If you see a call like givePlayerReward(player), you already understand its purpose without reading its implementation. This will matter even more when you start writing more complex game systems.

Common Mistakes With Functions

Beginners often make a few predictable mistakes when learning functions.

One common mistake is forgetting the parentheses when calling a function. Writing greet instead of greet() does not call the function. It just refers to the function value. This is useful when you pass the function to another function, but not when you intend to run it.

Another mistake is expecting a function to return a value when it does not. If you call a function that has no return statement and assign it to a variable, that variable becomes nil. For example:

function sayHi()
    print("Hi")
end
local result = sayHi()  -- prints "Hi"
print(result)           -- prints nil

If you need a value from a function, you must explicitly use return.

A third common issue is mixing up printing and returning. print is only for showing information in the Output window. It does not send a value back to the caller. A function that uses print but does not return anything cannot be used for calculations.

Key distinction:
print shows information.
return sends information back to the caller.
They are not the same.

Functions in Roblox Scripts

Although this chapter is about general Lua functions, it is worth understanding how they appear in Roblox scripts.

You will often write functions that respond to game events, like a part being touched or a button being clicked. In these cases, Python style thinking does not apply. Instead, you prepare a function and then let Roblox call it when the event happens.

For example, your function might handle when a player character hits a checkpoint or picks up a coin. You will connect that function to an event using Roblox specific APIs. The function definition itself uses the same Lua rules you have seen in this chapter.

Later, when you work with events and RemoteEvents, you will see that nearly every interaction involves defining a function with parameters that Roblox fills, and then wiring that function to some event. The skills you practice here will carry directly into those topics.

Summary

Functions in Lua let you group code under a name, reuse it, and control how information flows in and out. You define functions with the function keyword and end, call them with parentheses, pass information in through parameters, and send results back with return. You can make them local to keep your code safe from conflicts, and you can use them as values to build more flexible patterns.

In the next chapter on scope you will see how the places where you define functions and variables affect where you can use them. That will give you more control over how you structure your scripts as they grow larger and your Roblox games become more complex.

Views: 19

Comments

Please login to add a comment.

Don't have an account? Register now!