Way to put module functions into event calls

local function Set(player, active)
	local Character = player.Character
	if not Character then return end
	
	local Humanoid = Character:FindFirstChild('Humanoid')
	if not Humanoid then return end
	
	Humanoid.JumpPower = active and 35 or 0
	Humanoid.WalkSpeed = active and 18 or 0
end

function MovementManager:Setup(player)
	Set(player, true)
end

Movement.OnServerEvent:Connect(Set)

Problem lies with the Set. Is there a clean way to allow other scripts access to this module? The only other way I thought of doing this was

function MovementManager:Set(player, active)
	local Character = player.Character
	if not Character then return end
	
	local Humanoid = Character:FindFirstChild('Humanoid')
	if not Humanoid then return end
	
	Humanoid.JumpPower = active and 35 or 0
	Humanoid.WalkSpeed = active and 18 or 0
end

Movement.OnServerEvent:Connect(function(player, active)
    MovementManager:Set(player, active)
end)

Because I can’t do

Movement.OnServerEvent:Connect(MovementManager:Set())

Honestly have no idea how to title this, so sorry if it’s the wrong title :grimacing:

If you change Set from a method to a function (define it with a period instead of a colon, which you should do anyway if you don’t use self), you could simplify this to Movement.OnServerEvent:Connect(module.Set) Otherwise, you’ll need to stick to using the anonymous function.

8 Likes

Your solution to just wrap it in an anonymous function is correct. I know it’s not ideal, but that’s the way to go.

The only other option would be to create a somewhat-memoized function that wraps the call as well, but it’s just doing the same thing at the end of the day:

local function DoSet(...)
   MovementManager:Set(...)
end

Movement.OnServerEvent:Connect(DoSet)

^ I do not recommend doing that.

4 Likes

So this is the correct way??

function MovementManager:Set(player, active)
	local Character = player.Character
	if not Character then return end
	
	local Humanoid = Character:FindFirstChild('Humanoid')
	if not Humanoid then return end
	
	Humanoid.JumpPower = active and 35 or 0
	Humanoid.WalkSpeed = active and 18 or 0
end

Movement.OnServerEvent:Connect(function(player, active)
    MovementManager:Set(player, active)
end)

The actual correct way is to drop the : in favor of a .. Your module is not an object and it’s instead a table of functions, so it shouldn’t be using : in the first place for declarations.

Also, wrapping with a 2nd function incurs minor overhead you should be aware of.

4 Likes

When should I use : then? :confused: I’ve always used : and had no problems?

You only use : when defining and calling methods for OOP objects/classes. It’s bad practice to use it anywhere else because it gives the reader the impression you’re accessing a function that depends on object state. The forum has a couple OOP tutorials that probably better explain it.

4 Likes

Doesn’t it cause any problems tho? I mean, imo, : looks a lot nicer than .

Plus I don’t work with other coders in my games, so it doesn’t really matter who can read it, as long as I can right?

It’s like creating an object in Java with no fields and adding non-static functions to it. The functions never use the object, but you need to have one anyways to use it.

Whether you work with others or not you should stop doing, because you wouldn’t do the same in other languages.

It looks a lot less clean when you wrap its call in an anonymous function instead of just doing my method. So, yes, it does cause “problems”, just not anything that you can’t work around easily.

2 Likes

I don’t code in other languages tho? I mean I’ve read through All about Object Oriented Programming and I can’t find anywhere stating when to use : or .

Also, quoted from that link

here is also a neat little feature in Lua where if you do function table:Method() self is auto declared. It is the same as doing function table.Method(self). Remember how boop:Beep() is the same as calling boop.Beep(boop)

ie, they the same :man_shrugging:

When you use : it will automatically add the preceding object into the first argument.

local t = {}

function t.output(a, b)
    print(a, b)
end

t.output("Hello", "World") -- prints "Hello World"
t:output("Hello", "World") -- prints "table: 0x.... Hello"

This is helpful when the function declaration also uses : as it then places that first argument into a new variable called self.

local t = {}

function t:output(a, b)
    print(a, b, self)
end

t.output("Hello", "World") -- prints "World nil Hello"
t:output("Hello", "World") -- prints "Hello World table: 0x...."

If you don’t match them correctly then it will mess with your arguments and you will seemingly lose or change variables.

So I have to do this then?

function MovementManager.Set(player, active)
	local Character = player.Character
	if not Character then return end
	
	local Humanoid = Character:FindFirstChild('Humanoid')
	if not Humanoid then return end
	
	Humanoid.JumpPower = active and 35 or 0
	Humanoid.WalkSpeed = active and 18 or 0
end

Movement.OnServerEvent:Connect(MovementManager.Set)
1 Like

Yep exactly.

What you did before by wrapping with an anonymous function is also correct, as Crazyman32 stated, however in this case wrapping is unnecessary. Here you are using a static table so it is always the same table. If however you had an object, you would need to wrap with an anonymous function and call with : to pass the object as the first argument (to get it auto-declared as self). Don’t worry if that is confusing for now as it is only relevant to object orientation.

2 Likes