InvokeClient not working

Server

print("Send startmatch data to "..v.Name)
game.ReplicatedStorage.Function:InvokeClient(game.Players[v.Name], "StartMatch") 

Client

function game.ReplicatedStorage.Function.OnClientInvoke(A)
	print("Got "..A)
	if A == "StartMatch" then
		print("Loading")
		_G.StartMatchGui()
	end
end

This code (unchanged since) worked a week or two ago. Now it doesn’t print anything on the client. The problem is not my code. It does this with FE enabled or disabled.

I ran your code and got it to work fine. Perhaps it’s a race condition where the client hasn’t yet set the callback when the server invokes it?

It has. I print right above the .OnClientInvoke to make SURE it latches onto the Function in time.

print("Looking for")
function game.ReplicatedStorage.Function.OnClientInvoke(A)
	print("Got "..A)
	if A == "StartMatch" then
		print("Loading")
		_G.StartMatchGui()
	end
end
print("Found")

blob.png

I can send a repro file to an admin if needed.

1 Like

I’ve experienced, in the past, that often, RemoteEvents/RemoteFunctions do not work within the first 1-3 seconds of the client joining. They just won’t receive the data. Could this be what’s happening to you?

Unrelated sidenote: If you aren’t going to be returning any data using the RemoteFunction, please use RemoteEvents instead. :slightly_smiling:

1 Like

RemoteFunctions will wait until the function finishes.

RemoteEvents will not.

I use RemoteFunctions so that I can ensure all players have their loading screens set up before we start the match.

Don’t see why you’d be doing that, but whatever.

How about my suggestion pertaining to the OP? :stuck_out_tongue:

1 Like

Why would I create a loading screen if I didn’t wait for it to open?

I’ve found something interesting…

blob.png
blob.png

By delaying the function by 1 second it works properly. This is definitely a roblox bug.

Just out of curiosity, why are you using a RemoteFunction instead of a RemoteEvent?

I don’t want these teleports to begin until after the loading screen fades in. The game is very well polished and it’d ruin the immersion if things randomly became choppy.

If you want to debug the network traffic, you can enable settings().Network.PrintEvents. This will print out the replication of remotes, among other things.

After combining and sorting the outputs of the server and the client, the signature of a call to InvokeClient will look something like this:

Server: [timestamp] - Replication: RemoteFunction-[debugID].RemoteOnInvokeClient >> [clientIP], bytes: [x]
Client: [timestamp] - Replication: RemoteFunction-[debugID].RemoteOnInvokeClient << [serverIP]
Client: [timestamp] - Replication: RemoteFunction-[debugID].RemoteOnInvokeSuccess >> [serverIP], bytes: [y]
Server: [timestamp] - Replication: RemoteFunction-[debugID].RemoteOnInvokeSuccess << [clientIP]

If you’re having trouble finding the right RemoteFunction, you can use the command line on either the server or client to get the debug ID:

print(RemoteFunction:GetDebugId())

Like I said, I believe that the reason you aren’t receiving the RemoteFunction the first time is because the client just joined. The client is unable to receive RemoteEvent/RemoteFunction calls for the first 1-3 seconds after joining.

Isn’t that still a bug?

Yeah, I’d say it is. Wasn’t claiming it’s not a bug. :slight_smile:

1 Like

First up: remote functions require a return statement. If there is no return statement, the thread yields indefinitely.

Second up: invoking a client is poor design! The state of the client is unknown and harder to control than the server, so your thread can halt indefinitely because a client isn’t ready to receive the invocation, which is what you are seeing. Server-to-client communication should be facilitated using remote events for this reason. A proper way to do what you are trying to do is to have remote events tell all clients to load the GUI, then each client will respond back saying that they are ready. Any client that does not respond back in 5 or so seconds will not play that round, because either they have left or their internet is too poor to play.

5 Likes

If he has the :InvokeClient() in a function fired by an event (e.g. PlayerAdded) that handles stuff for that client exclusively, there wouldn’t be any problems since the yield wouldn’t affect other clients.

Yes, but it makes it extremely difficult to handle timeouts and no-responses. Remote Events are the way to tell clients what to do.

There’s no need to handle timeouts and no-responses in his case because they’re automatically taken care of. If a client doesn’t respond, InvokeClient doesn’t return and they don’t get teleported into the game. You’re suggesting he use RemoteEvents and if the client doesn’t respond after x amount of time, don’t teleport them into the game. The end results are the same.

My code is fine :stuck_out_tongue:

Did you check a relevant part of his post? Does your code work again when you stick an empty return at the end of the function? I don’t know how the rest of your code works, but I assume this may also be causing issues.