How can I pass a function as an argument?

Hey devforum! How would I pass a function as an argument?

Here’s my code:
LocalScript:

-- Don't make the keycode F or else it will interfere with the flashlight
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ContextActionService = game:GetService("ContextActionService")

local Player = Players.LocalPlayer
local RemoteEvents = ReplicatedStorage:WaitForChild("RemoteEvents")
local InteractionSystemEevent = RemoteEvents:WaitForChild("InteractionSystemEvent")
local Mouse = Player:GetMouse()
local SelectionBox = script:WaitForChild("SelectionBox")

function MouseMoved()
	ContextActionService:UnbindAction(Player.Name.."Interaction")
	if Mouse.Target then
		local Object = Mouse.Target
		
		if Object:HasTag("CanInteract") then
			local InteractionInstructions = require(Object:WaitForChild("InteractionInstructions"))
			local Keycode = InteractionInstructions.Keycode
			local RunContext = InteractionInstructions.RunContext
			
			local function HandleAction(actionName, inputState, _inputObject)
				if actionName == Player.Name.."Interaction" and inputState == Enum.UserInputState.Begin then
					
					if RunContext == Enum.RunContext.Server then
						InteractionSystemEevent:FireServer(InteractionInstructions.InstructionsToCarryOut)
					elseif RunContext == Enum.RunContext.Client then
						InteractionInstructions.InstructionsToCarryOut()
					else
						warn(Object.Name..".InteractionInstructions.RunContext is invalid: Must be Enum.RunContext.Server or Enum.RunContext.Client")
					end
					
					SelectionBox.Parent = script
					SelectionBox.Adornee = nil
				end
			end
			
			SelectionBox.Parent = workspace
			SelectionBox.Adornee = Object
			ContextActionService:BindAction(Player.Name.."Interaction", 
										   	HandleAction,
											true,
											Keycode)
		elseif Mouse.Target == nil then
			SelectionBox.Parent = script
			SelectionBox.Adornee = nil
			ContextActionService:UnbindAction(Player.Name.."Interaction")
		else
			SelectionBox.Parent = script
			SelectionBox.Adornee = nil
		end
		
	end
	
end

Mouse.Move:Connect(MouseMoved)

ServerScript:

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local RemoteEvents = ReplicatedStorage:WaitForChild("RemoteEvents")
local InteractionSystemEevent = RemoteEvents:WaitForChild("InteractionSystemEvent")

function OnServerEvent(player, ...)
	({...})[1]()
end

InteractionSystemEevent.OnServerEvent:Connect(OnServerEvent)

I apologize if the code lacks comments or documentation as this project of mine is in it’s very early stages.

The InstructionsToCarryOut() function is a function without any arguments located inside of a ModuleScript in any part or model with the CanInteract tag that should be ran. Inside of the ModuleScript is also a RunContext variable which should decide whether it should be ran on the client or server to prevent using many RemoteEevents. There are 3 conditions which decide so and are located in the LocalScript. If the RunContext is set to the server then I want the InstructionsToCarryOut() function to be ran in the ServerScript using the RemoteEvent. I’m using a tuple and it doesn’t seem to be working. I keep getting a attempt to call a nil value error on Line 7 of the ServerScript.

Any help much appreciated!
Thank you in Advance.

1 Like

You cannot pass functions through RemoteEvents. In fact, you cannot pass a lot of things for security and technical reasons.

You can see the rules here:

P.S. having the server run code/functions that the client sends is a TERRIBLE idea, regardless of if it works or not. You are essentially creating a RAT (remote access trojan) in your game that exploiters can take advantage of. It’s the same reason why loadstring is disabled by default on the server and it gives off a warning if you turn it on. It’s all for the sake of your game’s security.

2 Likes

Ah. Didn’t know. Thanks for the advice.

Random fun fact: While protecting your game is one of the reasons it’s blocked, it is actually blocked to avoid exploiters passing a malicious function to the server and dumping RCCService. They can pass a non lua functions that can execute code in a lower level in Roblox’s servers which would lead to disaster.

That is actually wild to think of how easy it is do if it wasn’t blocked.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.