Module script required from local script

Hey there!

So i was looking at a few posts on whether module scripts can be required from local scripts, and they all said yes. So i went back on studio, and started using Module scripts for local scripts to make everything more organised.

However, i soon came to realise, that these module scripts don’t run the code on the local script, rather the module script itself.

Is this assumption correct? Is there anyway to make this work?

Any help is appreciated.

2 Likes

The module script is ran in the environment which it is required from, so it will only run locally and not on the server.

2 Likes

I’m not sure about that, but why would that matter? Just make sure you store the modulescript somewhere the client can access, like replicatedstorage.

1 Like

@cjjdawg @apenzijncoolenleuk1

The module script is in Replicated storage. It has no problem accessing it. For some reason however stuff like script.Parent:TweenSizeAndPosition doesn’t try to Tween the local script’s Parent rather the module script’s Parent.

I’m assuming you mean the module just runs the code even if you say

require(module) Correct?

You could call the individual function if you didn’t already do that to the local script

1 Like

Sorry for not explaining the problem clearly.

The problem is that i code such as Script.Parent is inside a function inside a module script, and the module script actually modifies its Parent instead of the local script’s Parent. (The local script is calling the function from the module script.)

I’m trying to figure out if there is any solution to this, or if there’s anything i’m getting wrong.

While the module is running by the local script’s context, defining script points out the current script running it and not the original script that started it. So, it sees the parent of the module because the module isn’t simply your local script running code in the module, it just has the local script’s context since the local script told it to run.

3 Likes

I understand now. Thank you. So i’m guessing the local script doesn’t bring code from the Module script to it’s location, rather the opposite.

Does this mean i would have to change the client’s properties from the module script’s location? Is there much point of me doing this if that’s the case? Should i just keep all the code in that one local script?

Not sure what you mean, if you previously had defined variables, you have to re-define into the module or send it via the function for use if you won’t need to save the sent information. Or you can also directly edit the module since I expect your module is a table, thus you can change it.

1 Like

You don’t have to change the properties of the client. The code will work fine if you just define the variable differently is all.

Also if the variable is hard to define or whatever, you could always put the scripts somewhere else if you wanted to so it can define it better ig. other than that, you’re good.

1 Like

@ArtFoundation @daslick

So all i have to do instead of script.Parent is plr.PlayerGui?

The module is ran on the client if you require via local script, you just need to define local player again and the PlayerGui.

You could get the parent if the module’s parent is expected to be the PlayerGui.

8 Likes

Yeah pretty much. You’d do that then have WaitForChild() or just define the variable without WaitForChild(). I like using WaitForChild() tho.

1 Like
--ModuleScript
local module = {}

module.dothis(player,thing)
  print(thing.Name) -- "ThisGui"
  print(player.Name) --Your name
end

return module
--LocalScript
local player = game.Player.LocalPlayer
local thing = player.PlayerGui.ThisGui
local Module = require(game.ReplicatedStorage.ModuleScript)
function sendtomodule()
  Module.dothis(player,thing)
end

Im pretty sure localscripts dont make the first value of a function equal to player but thats an easy fix
idk if this helps but hopefully so

1 Like

Don't do this anymore, it's bad practice. Always avoid using getfenv() and setfenv(), they will mess up a lot of optimizations and improvements that Roblox has made over the years.

Original post:

In a function inside of a ModuleScript, you can use this to find the ‘script.Parent’ of the script that calls the function. getfenv returns the table that is the function environment, basically it can retrieve all variables that are not local variables as a table. You can also set variables this way. By adding the ‘2’ as a parameter, it goes to the second level. First level is the current function, second is the function calling this function, third is the function calling that one, etc. You can also give it a function instead of a number to check or assign variables used in that function, almost useless now I think but it used to have a purpose with loadstring.

In the script:

local test = require(game.ReplicatedStorage.TestModule)
test.TestFunction()

In the module:

local module = {}
module.TestFunction = function()
    print(getfenv(2).script.Parent)
end
return module

If you wanted to have some fun, you can do this too. You can create a table of variables, and automatically add all of the variables to your script with one line of code. I find it quite useful.
In the module:

local vars = {}
vars.tau = math.pi*2
vars.div3 = function(number)
    return number/3
end
return function()
    for key,value in pairs(vars) do
        getfenv(2)[key] = value
    end
end

In the script:

require(game.ReplicatedStorage.TestModule)() -- notice I call the function returned immediately.
print(tau) -- 6.28319
print(div3(tau)) -- whatever the heck 6.28 is divided by 3.
2 Likes

I was having problems because I put my module script in the wrong place, Thx