Hello! I am becoming more and more familiar with modules… Finally! But, i have a very important question that i cant seem to find a straight answer for: If you call a module from a local script, will it only perform the function in the client? Or can it run in the server? and if so, how?
Now, What is the cleanest way of bouncing a modular function back and forth from local and server functions? For instance, if i want to call a server function from a module, in a local script, would i need to remote to a server and then perform the function? If so, then what is the point of using a module instead of just a server script?
I am cleaning up a very messy magical system for my game, ’ A Mystical Life’, and i want it to be primarily modular… however it requires stuff from both local and server so i’m wondering what the best way of doing this is. The functions themselves aren’t important… I can figure that stuff out, whats important is me understanding the relationship of modules between server and client. THANKS!
loading a ModuleScript is kinda like calling a bindablefunction, the code will act like it is the localscript, that means that, no, the localscript cannot do any server-only function
No problem, remember if you come up with a way to bounce around, you can always use RunService:IsClient() and RunService:IsServer() to get if the code is running in the client or in the server!
If you think your question got solved, don’t forget to mark as solved!
A ModuleScript is basically a Local Script and a Server Script at the same time. When you require a ModuleScript, you’re doing that through either the Client or the Server. When you execute code through that ModuleScript, either the Client or Server will run that code.
As an example, if I had function foo() in a ModuleScript (game.Workspace.Module), On my Client, I’d do:
local module = require(game.Workspace.Module)
When I did module.foo() the Client would run that code. If I did it from a Server script, the Server would execute that function.
From what I remember, module scripts will cache the result that is returned.
i.e
--in the script
require(script.ModuleScript)
require(script.ModuleScript)
--in module script under the script
print(1)
return nil
This will only print once, as the result is cached and the module script won’t run again when the require function is called on it.
But using a BindableFunction the result isn’t cached.
i.e
local Bind = Instance.new"BindableFunction"
function Bind.OnInvoke()
print(1)
return nil
end
Bind:Invoke()
Bind:Invoke()
This will print out twice, as the data isn’t cached.
Also, logically using a BindableFunction could have issues as the script which registers the function should run before all the functions which use it. (if its not registered then it will yield until a function is registered, but its still an unnecessary yield) Module scripts don’t suffer from the issue because they don’t need any script to register the function.
Thankyou! Yes, i’m familiar with remote events and functions, i just want to downsize the amount of running scripts as possible so i’m moving to modules.
In addition, what I do for my game when I need for modules to be use with both server and client alot is by using the run service for example:
local RunService = game:GetService("RunService")
module.Example = function()
if RunService:IsClient() then
--This will check if the module is running on the client
elseif RunService:IsServer() then
--This will check if the module is running on the server
end
end
This way you can have the client and server call the same module, but will carry out different instructions and its pretty neat and I ended going from using 5 remotes for one task to none through manipulating this tactic.
You can check where is has been required from with RunService:IsClient(), which returns true on the client and false on the server. Then, just use remotes on the client version and connect them on the server side one, and you should be good.
If the ModuleScrips functions are being ran by a LocalScript they will only be ran on the client. If the ModuleScripts functions are being ran by a script then they will only be ran on the server.
I am going to try and explain this as best as I can so bare with me. A ModuleScript is a container where you store code until it is required. This means you can run functions that are in a module in multiple scripts at the same time.
If your ModuleScript is located within ReplicatedStorage you can require it from the server and the client. This means you can run the functions in the ModuleScript on the client and the server at the same time. However if you change any variables/tables ect on the client they wont be replicated to the server and vice versa.
Instead of using the same function and changing it’s action based on the environment, it would be much easier to change the function itself based on the environment. I find this to be much more manageable.
local RunService = game:GetService("RunService")
local IS_SERVER = RunService:IsServer()
local module = {}
module.Example = IS_SERVER and function(args)
print("server", args)
end or function(args)
print("client", args)
end