So I have some functions in a ModuleScript that are called by the client, but that I need to run server-side. The first solution I came up with was a RemoteFunction accompanied by a script in ServerScriptService:
local RemoteFunction = game.ReplicatedStorage:WaitForChild("ModuleCaller")
RemoteFunction.OnServerInvoke = function(moduleFunction, ...)
if ... == nil then
moduleFunction()
return nil
else
return moduleFunction(...)
end
end
The intention of this was to allow the RemoteFunction to be called from the client with the function it wanted to run (and the module, i.e. Module.Function(parameter)) and then run that function (the if … == nil thing was to allow functions without parameters to use the same system)
This doesn’t work, with the error ‘attempt to call a Instance value’ appearing both in line 4 of the above and the local script I invoked the function from.
Therefore, how could I efficiently have a module function called by the client run server-side, or fix the above?
When OnServerInvoke fires, it passed the player object as the first argument so you need to change function(moduleFunction, ...) to something like function(_,moduleFunction, ...) so you actually fire the function you passed with :InvokeServer().
Did that - it now errors with ‘attempt to call a nil value’ i.e. moduleFunction is nil. This happens when I pass both Module.Function and Module.Function() as that parameter.
As in, one RemoteFunction per function? My issue with that is that it’s clunky and would take forever to do. And can you explain what you mean by the latter?
I have a feeling what you’re trying to do is reliant on the client and server sharing the same memory which isn’t the case. You can’t pass any function directly from the client to the server so you’d have to try and change this to a reference based system.
The latter method that was suggested is having the server script also load the module and then have the client invoke the remote function and send the name of the function as an argument instead of the function itself.
(Very similar to what @Club_Moo wrote) something like:
local module = require(\path)
remoteFunction.OnServerInvoke = function(player, funcName, ...)
if module[funcName] then
return module[funcName](...)
end
end