RemoteFunction not returning anything but still proceeds with client code

Hey guys! I am currently invoking a Remote Function from the client. Now, obviously, we all know that when you call this, it yields the Lua thread which basically means that code after running this function will not execute until the Remote Function has returned a value from the server.

However, for some reason, even though no value is getting returned, the code after this line is still getting executed. Does anyone have an explanation as to why?

(I tried logging what gets returned from the remote function on the client as it’s just “nil”, which is to be expected considering nothing was returned.)

1 Like

Could you provide your scripts? Also, ensure your RemoteFunction is in ReplicatedStorage, otherwise it may not run depending on where you’ve stored it.

local success = game.ReplicatedStorage.BlueMilesTransaction:InvokeServer("Test", 0)
print(success)
print("Hello world!")

And yes, the Remote Function is in ReplicatedStorage.

1 Like

Thanks!

Could you provide your server script? Also, just to be sure, your script isn’t in ReplicatedStorage or ServerStorage, right?

rep:WaitForChild("BlueMilesTransaction").OnServerInvoke = function(player, name, price)
	local GUI = bmTransaction:Clone()
	GUI.Parent = player.PlayerGui

	local background = GUI.Background

	local miles = getBlueMiles(player)
	background.Price.Text = "Price: "..price.." BM"
	background.Item.Text = name

	if miles >= price then
		background.BMAfter.Text = "BM After Purchase: "..(tostring(miles - price))
	else
		background.BMAfter.TextColor3 , background.BMAfter.Text = Color3.fromRGB(255, 76, 6), "Not enough BM for item."
	end	

	background.Loading.Visible, background.LoadingLabel.Visible = false, false
	background.Price.Visible, background.Item.Visible, background.BMAfter.Visible = true, true, true

	background.Confirm.MouseButton1Down:Connect(function()
		background.Confirm.Visible, background.Decline.Visible = false, false
		background.Loading.Position = UDim2.new(0.499, 0, 0.749, 0)
		background.Loading.Visible = true

		miles = getBlueMiles(player)

		if miles >= price then
			local s, err = pcall(function()
				milesDatabase:IncrementAsync(player.UserId.."/Miles", -(price))	
			end)

			if s then
				transactionError(player, "Purchase successful!", GUI, "Check")
				return true
			else
				warn("BH Miles System | Failed to process transaction for "..player.Name.." | "..err)
				transactionError(player, "This transaction has failed.", GUI, "Failed")
				return false
			end	
		else
			transactionError(player, "You do not have enough blue miles for this purchase.", GUI, "Failed")
			return false
		end
	end)

	background.Decline.MouseButton1Down:Connect(function()
		background.Confirm.Visible, background.Decline.Visible = false, false
		transactionError(player, "Transaction declined.", GUI, "Failed")
		return false
	end)
end

As you can see, it should only be returning a value after the player clicks on one of the buttons, not as soon as it gets invoked.

1 Like

Thanks!
You shouldn’t handle your UIs on the server side, also I don’t think the server can detect clicks from the client. Why not handle your UI on the client side, including the BM after purchase etc, and then, after you press on your confirm button, you invoke the server, and then do the necessary checks at that point?

Hmm, I already know that I shouldn’t be handling UIs on the server-side, though from my perspective after trying to do it, it just seemed like a better solution to handling transactions. I’ll see what I can do to handle UI interactions on the client-side, and then handle the actual transactions on the server through a Remote Function/Event.

1 Like

You could always invoke the client, but it isn’t really recommended as per the developer.roblox.com link.

(here: Custom Events and Callbacks | Documentation - Roblox Creator Hub)

If your biggest concern is exploiters, they can get access to the remote function and invoke it anyway. As long as you are handling the purchase on the server side and checking that they have enough money, exploiters can’t do anything.

1 Like

You need to setup ui interaction client side as he stated above then send info to the remote function handle it there and return what you need

the reason this returns with nil is because everything in the function is being ran/passed and returning nil
there is nothing in the function to hold/yield it for the return value

1 Like