Hey!
So my question is pretty much in the title already. My question would be following.
If I did:
local Players = game:GetService("Players")
local function OnJoined(plr)
print(plr.Name .. " just joined the game!")
end
Players.PlayerAdded:Connect(OnJoined)
Would it be a lot better than
local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(plr)
print(plr.Name .. " just joined the game!")
end)
?
I don’t know if this is true but I think the second one would create a new function every times a player joins which would be pretty bad performance-wise. Or does Roblox have some optimization for that that?
The real significance of defining a function first rather than using an anonymous function is that you can reuse the function. This is particularly useful when you need to call that function outside of when say, a player joins. You might want to call OnPlayerJoined for players that have already joined before your script started listening to Players.PlayerAdded for instance.
I would do Player.PlayerRemoving outside of the PlayerAdded as PlayerRemoving fires for all players meaning the event will fire for players other than the Added Player wasting resources and needing extra code to ensure the Player that is being removed is the Player that was added, overall just not a good idea to define it like that.
local function Onjoined(plr)
--function actions
end
Localizes the function to the thread which means it compiles to the memory and runs faster when referenced. A little tip is if you do this:
local OnJoined = function(plr)
--function actions
end
Is the same thing here so if you wanted to create a global variable without defining it at begging of the script that can be redefined at any given point and referenced outside of a different part of a script with the same value then the function would already be compiled to the script’s memory and able to be redefined at will in any other part or if you want to make it specific to a certain part of the thread then you do:
It’s better to think of events this way:
The line where you write the event, is just a one-time operation, which connects a function (which can be thought of as a callback) to a certain action.
When the function is called happens in the background, the same annonymous function is called each time the action happens.
If you think about it, this operation is gonna only happen once (unless you’re continuously connecting a new function to an event inside of a while loop). So whether you do the former or the latter, there is gonna be a super tiny difference, that’s made even more insignificant because the operation happens only once. As @Optikk said, choose the former if you’re gonna be reusing the function, and maybe sometimes you find it more readable.
It would not! The function is created exactly once, and PlayerAdded calls that same function every time. A function is a first class object in Lua, it can be passed around much the same as a number or table.
Look at it this way:
local function onPlayerAdded(plr) -- defined once
print(plr.Name .. " just joined the game!")
end
Players.PlayerAdded:Connect(onPlayerAdded) -- connected once
:Connect does not look at the contents of the onPlayerAdded variable every time. Rather, the contents of that variable are passed to Connect, and that’s all it will know and call.
If you reassign onPlayerAdded later after the connection, then the function that PlayerAdded will do does not change, either.
This code would make a new function every time:
Players.PlayerAdded:Connect(function(plr) -- this function is created once
return (function() -- create a new function every time...
print(plr.Name .. " just joined the game!") -- plr can be used here, it is a closure
end)() -- ... and then just call it without doing anything else with it
end)
That’s a lot harder to write. (No, it’s not universally stupid to do, it can have its uses)