Sending a Function Through RemoteEvent Returns Nil

So, as part of a dialogue tree system, I’ve been inserting functions into dictionaries. The dialog tree is one giant nested dictionary in a moduleScript.

Currently, I have a localScript that requires the dialogue module and eventually gets to a list that contains the function.

{"exitDialogue", "serverFunction", function(plr) 
	plr.Character:FindFirstChild("tickedOffJup").Value = true
end}

In my localScript, the function is called using something like:

endList[3](plr)

Where the endList refers to the list above. It works there, but only runs on the client. I wanted to make it run on the server, so I decided to fire a RemoteEvent to a serverScript. I pass through the player and endList[3].

When the serverScript receives it though:

choiceFuncEvent.OnServerEvent:Connect(function(plr, functionToRun) -- if there's a function to be ran during dialog and it's labeled a "serverFunction", it hands the job here.
	print(functionToRun)
	functionToRun(plr)
end)

The argument functionToRun returns nil. From what I can see, it should be the function’s hexadecimal memory address, and I don’t get why it just seems to…break upon being passed through an event. At least, I think it’s the memory address. Maybe it’s referring to the function inside the moduleScript? When I printendList[3], I get:

function: 0x2b289b9ae7d49269

I’m also pretty sure this isn’t because I forgot to require the moduleScript, as the argument I’m passing here already comes from the localScript, which has required the dialogue module. Besides, shouldn’t it just be passing the function? I’m stumped here.


TL;DR: I’m trying to pass a function through a RemoteEvent, but it comes out as nil when received. By passing a function, it might actually be its memory address.

You cannot pass functions, or anything holding functions, through remote events as they are not serializable (it cannot be persisted through memory). You should instead declare and run the function on the server with the plr argument

As described in the documentation for RemoteEvents:

There are several restrictions on the values that can be sent through them, including functions not being replicated at all:

This next section is getting into the weeds a little bit, but;

The address you get when printing (or converting it to a string with tostring) is the address of the parameter passed to the C function that tries to convert it to a string (so function: 0x2b289b9ae7d49269 is actually relative to print, or, more specifically, the array that Luau uses to pass arguments to functions defined in C/C++). Even if the memory address was successfully replicated, this would still be very flimsy as there’s no way Roblox could guarantee identical memory layout.

Replicating functions from the Client to the Server would actually be a huge security risk, as Clients do not have access to the source code of the scripts they are running, only the compiled bytecode. Bytecode itself is not guaranteed by the Luau VM to be safe to execute as it is very difficult to validate, so if Clients could send arbitrary bytecode to the Server, that would open the door to Remote Code Execution exploits and sandbox escaping.

Luau cannot really handle passing functions around between VMs regardless, there’s a similar problem if you venture into Parallel Luau, where even staying on the same device, you can’t pass functions between Actors.

I wasn’t even thinking this deep lol I just think if they allowed passing of functions through remote events that it could definitely be used to crash servers

1 Like

Passing data just by itself generally can’t cause a crash, but in this case it’s super dangerous because the Server doesn’t know what code it’s running, and has no way to know if it’s “safe”. It can end up doing stuff that regular Luau scripts can’t do by using specific combinations of bytecode that the regular Luau compiler won’t generate, like setting values in random parts of memory.

1 Like

That’s what RemoteFunctions are for. Create a RemoteFunction, make OnInvoke call the function you want and send it to the client.

1 Like

I think you completely misunderstood what OP was having trouble with.

You can’t send functions across the server-client boundary nor across Lua VMs.

I did and I provided the correct way you are meant to do this. You give the client an instance it can use to call the function on the server and get the results back. This is good enough if you don’t mind the delayed response.

that physically impossible for it to pass a function.
There no ways to serialize it.

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