Common mistakes in roblox scripting

Hey there. In this post I will be sharing a few common mistakes in roblox scripting.

This list isn’t in any order.

LocalPlayer and server scripts

One of if not the most common mistake. People will try to get the local player via the Players.LocalPlayer property but get an error about attempting to index a nil value.

Think of it like this: if you told your teacher to get the local student your teacher would be very confused because who is the local student??? A player can’t be picked at random either. Code cannot read your mind. That’s why you need to type specific stuff to follow the syntax of the language.

So if you wanted to create a part in the workspace with colour red you don’t do this:

make a part in the workspace with the colour red

There are multiple ways to get the player, but in this example I’ll go over how from a Touched event listener.

    local player = Players:GetPlayerFromCharacter(other.Parent);

    if (player) then
        -- do something with player because it's a player!!!!! :)

:FireServer, :InvokeServer, .OnClientEvent, .OnClientInvoke; no player


Lots of people assume that a reference to the local player must be passed through :FireServer/:InvokeServer first since that’s what is included as the first argument to your .OnServerEvent/.OnServerInvoke callback functions. You don’t do this since roblox does it implicitly. It wouldn’t make sense to have to do it manually either, as it could be a security issue, exploiters could fire a remote event/invoke a remote function on behalf of another player.

Changing StarterGui over PlayerGui

You may want to make a change for all players, or for a single player. It is a common mistake to change the contents of StarterGui over PlayerGui. When you (re) spawn, the contents of the StarterGui service are cloned into your PlayerGui located under your Player instance. The local scripts running and the UIs that you see are all the ones in PlayerGui.

Say this was your code:

game.StarterGui.ScreenGui.Frame.TextLabel.Text = "Yes hi"

This change will be seen once you respawn.

game.Players.LocalPlayer.PlayerGui.ScreenGui.Frame.TextLabel.Text = "Yes hi"

This change will be seen immediately.

Properties and Variables

Can’t think of a good title, but people often assume local value = numberValue.Value (for example) will store a reference to the actual Value property in the variable. So that they can go value = value + 5 or something to change the property.

Well all that does is store the current value at the time the script ran. It won’t update on its own: you need to do this yourself. Changing the variable value only changes the variable value, not the property itself.

It’s important to know the difference between reference and value.


Lua passes objects (tables, threads, userdatas, functions) by reference. Part of this means that variables and table fields contain references to these objects and not the objects themselves.

Think of references as arrows. Arrows point to something. Like it might point to a gas station right across the street. The arrow isn’t the gas station itself it just points to it.

local t = {'a', 'b', 'c'};
local t2 = {'a', 'b', 'c'};
local t_ref = t;

print("t == t2:", t == t2, "t == t_ref:", t == t_ref);


t == t2:    false    t == t_ref:    true

t and t_ref point to the same exact table. t2 is different even if it has the same elements in the same position.

Let’s now remove a few things.

table.remove(t_ref, 2);
print(t_ref[2], t[2], t2[2]);


c    c    b


Lua passes numbers, booleans etc by value.

local n = 8;
local n_ref = n; -- not even a reference lol

n = n + 5;
print(n, n_ref);


13    8

Both variables have different memory so changing 1 won’t change the other.

The fix is to have your variables point to the number value object (for example) itself and make direct accesses to the Value property to read it or write to it.

Using GetChildren table to modify children

Can’t think of a title for this one either. But lots of people looking for a quick way to change a property in all children, have code looking something like so:

game.Workspace.Model:GetChildren().BrickColor = BrickColor.Random();

:GetChildren returns a table of all the children of an object, and all you’re doing in that example is adding a BrickColor field to the table.

You need to traverse this table, so you can get each child.

for _, v in ipairs(game.Workspace.Model:GetChildren()) do
    v.BrickColor = BrickColor.Random();


I go over a few common mistakes, and a solution to them. I hope you found this helpful and if you see anyone commit any of these mistakes do share this to them. I know there’s more mistakes, and do please tell me of them so I can add them to the list.


This topic was automatically closed after 1 minute. New replies are no longer allowed.