Remote function always returns false?

I recently implemented a crate opening system, and unfortunately, it is malfunctioning. It always seems to print “Cancelled Process”, despite me returning a boolean within the local script, of which I want the event to return. I don’t understand what it is that I am doing wrong. Help?

Local Script

local function Dissipate()
	local blur = workspace.Camera:FindFirstChildOfClass("BlurEffect")
	if blur then
		blur:Destroy()
	end
	wait()
	for index, Item in pairs(script.Parent:GetDescendants()) do
		if Item:IsA("TextButton") or Item:IsA("Frame") or Item:IsA("TextLabel") then
			coroutine.resume(coroutine.create(function()
				if Item:IsA("Frame") then
					for newIndex = 0, 1, 0.1 do
						Item.BackgroundTransparency = newIndex
						wait()
					end
					Item.BackgroundTransparency = 1
				else
					for newIndex = 0, 1, 0.1 do
						Item.TextTransparency = newIndex 
						Item.BackgroundTransparency = newIndex
						wait()
					end
					Item.BackgroundTransparency = 1
					Item.TextTransparency = 1
				end
			end))
		end
	end
end

local function Prompt()
	local newBlur = Instance.new("BlurEffect")
	newBlur.Size = 1
	newBlur.Parent = workspace.Camera
	for index = 1,24 do
		newBlur.Size = index
		wait()
	end
	wait(1)
	for index, Item in pairs(script.Parent:GetDescendants()) do
		if Item:IsA("TextButton") or Item:IsA("Frame") or Item:IsA("TextLabel") then
			coroutine.resume(coroutine.create(function()
				if Item:IsA("Frame") then
					for newIndex = 1, 0, -0.1 do
						Item.BackgroundTransparency = newIndex
						wait()
					end
					Item.BackgroundTransparency = 0
				else
					for newIndex = 1, 0, -0.1 do
						Item.TextTransparency = newIndex 
						Item.BackgroundTransparency = newIndex
						wait()
					end
					Item.BackgroundTransparency = 0
					Item.TextTransparency = 0 
				end
			end))
		end
	end

	script.Parent.Yes.Activate.MouseButton1Click:Connect(function()
		newBlur:Destroy()
		Dissipate()
		return true
	end)
	script.Parent.No.Activate.MouseButton1Click:Connect(function()
		newBlur:Destroy()
		return false
	end)
end


game.ReplicatedStorage.PromptCratePurchase.OnClientInvoke = Prompt

Server Script

local current = 0
local lootMModule = require(game.ServerStorage.LootModule)
script.Parent.Touched:Connect(function(Hit)
	if os.clock() - current >= 1 then
		current = os.clock()
		local Character = Hit.Parent
		if Character:FindFirstChild("Humanoid") then
			local Player = game.Players:GetPlayerFromCharacter(Character)
			if Player then
				local hasConfirmed = game.ReplicatedStorage.PromptCratePurchase:InvokeClient(Player)
				if hasConfirmed == true then
					print("Is processing..")
					Player.SpleefCoins.Value -= 200
					lootMModule.SelectItem(Player)
				else
					print("Cancelled Process")
					return
				end
			end
		end
	end
end)

This wouldn’t work because the script would simply connect the functions and proceed (making the function return nil). In addition, returning a value from a RBXScriptSignal connection wouldn’t return it to the server script.


You’d want to do something like this:

local yesConnection = nil -- a pre-defined variable for the 'yes' button
local noConnection  = nil-- a pre-defined variable for the 'no' button
local returnedValue = nil -- the value to be returned to the server

yesConnection = GuiButton.MouseButton1Click:Connect(function()
   returnedValue = true -- sets the return value to 'true'
   yesConnection:Disconnect() -- disconnects the event so that it isn't fired again
   noConnection:Disconnect()
end)

noConnection = GuiButton.MouseButton1Click:Connect(function()
   returnedValue = false -- sets the return value to 'false'
   noConnection:Disconnect() -- disconnects the event so that it isn't fired again
   yesConnection:Disconnect()
end)

while returnedValue == nil do
   -- a while loop to wait for the value to change
   game:GetService('RunService').Heartbeat:Wait()
end

return returnedValue

This is risky though because if an exploiter modifies the script and makes the loop yield forever and/or the player doesn’t press a button, the server will also yield forever.

True. Maybe I’ll use an alternative, non-yielding method instead! Thanks!