Module that does both server and client work?

(Title may be misleading, I literally had no idea what to name it)

In certain modules (the best example being rek_kie’s TweenService Plus+) it has the client only need to require the module, and then the server calls a function and fires to the client and also does client work at the same time, without any other work other than requiring the module from the client. How is this possible? (I do hope this makes sense, I’m not the best at explaining things)

1 Like

Could you try giving an example, i still don’t understand.

haven’t look into it, maybe the client fires the server, then the server fire all the clients, then those clients perform the tweens. not sure.

Not exactly sure what your question is, but here’s some possible answers:

A module script can do both server and client tasks as long as the module is available on both. This would mean the module is in a container like Replicated Storage.

Module scripts can also do this by using remotes created on the server and the client has the respective code to process the requests.

To do this, you’d need some form of client-server communication, aka a remote, which is what TS+ does on initialization.

Now, you have a remote, but you need to be able to communicate between client and server in the same module.

Luckily though, it’s pretty easy to do this with RunService - it has functions called :IsClient() and :IsServer() and returns true if what the module is running on is the client or server, obviously.

For a module to run, you just need to require it, which is why modules like this need you to require it somewhere on the client. Modules can actually run separate regular code inside of them (stuff outside what is returned) which is the whole reason why you’re able to control both sides in the same module.

So for example if you had a module like this:

local module = {}
print("HI")
return module

and required it somewhere, the code would print.

So applying this to allow you to control both sides in the same module would look like this:

local rs = game:GetService("RunService") 
local repStorage = game:GetService("ReplicatedStorage")

local remote -- Make an empty variable, because this needs to be referenced differently depending on where the module is running
local moduleTest = {}

if rs:IsServer() then -- if this is running on the server, 
    remote = Instance.new("RemoteEvent") -- Create the remote on runtime, make sure it's on the server!
    remote.Name = "Test"
    remote.Parent = repStorage -- This can be wherever you want
elseif rs:IsClient() then
    remote = repStorage:WaitForChild("Test") -- Have the client wait for that same remote the server will create
end

-- At this point, now you have access to both the remote on the server and client.
-- Since like I said, modules can run regular code just be being required, you 
-- can do this in the same module 

if rs:IsClient() then -- have the client connect to the remote
   remote.OnClientEvent:Connect(message)
        print("Received message:", message)
   end 
end 

-- Now, we can make a function in the module that fires the same remote. Only the server can fire remotes, so we do a check, too.

function moduleTest.sendMessage(message)
    if not rs:IsServer() then return end 

    remote:FireAllClients(message)
end 

return moduleTest

Now that you have the module done, it’s easy.

Require it somewhere on the client so that the client code runs (you don’t even need to store it in a variable or anything):

require(game:GetService("ReplicatedStorage"):WaitForChild("ModuleTest")) -- wherever the module is

-- Do it in either StarterCharacterScripts or StarterGui so that the code 
-- refreshes on respawns 

Then, you can use the module wherever you want on the server and all the client code picks up the actions.

local testModule = require(game:GetService("ReplicatedStorage"):WaitForChild("ModuleTest"))

wait(20)

testModule.sendMessage("Hello from the server")

And there you have it! The client should be able to pick up the code, and you’re controlling both sides from one module.

6 Likes

I see. Very grateful for your help! I’ll use this information well.

1 Like

No problem. If this solved your problem make sure to mark the post as solution so that people know where the answer is

Edit: It was marked, I had to refresh