Help With RemoteFunction/Event

I have a shop script that uses RemoteEvents and RemoteFunctions. The shop first uses a RemoteFunction to check that the player has enough gems to purchase the item on the server side, please keep in mind that the shop script is a LocalScript.

If the RemoteFunction returns that the player has enough gems, it fires the RemoteEvent to deduct the correct amount of gems from the player and the LocalScript handles the rest after the deduction.

However, the script does not deduct the gems when the player confirms the purchase. If I remove the GemCheck from the script it works again and the gems get deducted, which makes me think that the issue is with how I’m checking if the player has the correct amount of gems. The scripts are below;

Local Script; purchase script

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local currentEquipped = game.Players.LocalPlayer.EquippedSword

local buyButton = script.Parent
local equipButton = script.Parent.EquipButton
local clickSound = ReplicatedStorage.GameSounds.ClickSound
local hoverSound = ReplicatedStorage.GameSounds.HoverSound

local sword_to_give = script.Parent.Name
local sword = ReplicatedStorage.Swords:FindFirstChild(sword_to_give)
local gemCost = script.Parent.Price.Value

local buyButtonConnection
local yesButtonConnection
local uiElement = Players.LocalPlayer.PlayerGui:WaitForChild("User Interface"):WaitForChild("UserUI").SwordPurchaseUI

local player = Players.LocalPlayer
local swordStorage = game.ReplicatedStorage:WaitForChild("Swords")
local equippedSwordChangedEvent = game.ReplicatedStorage.Events:WaitForChild("EquippedSwordChangedEvent")
local swordPurchasedEvent = game.ReplicatedStorage.Events:WaitForChild("SwordPurchasedEvent")
local checkGems = game.ReplicatedStorage.Functions:WaitForChild("CheckGems")
local childrenNames = {}

for _, child in ipairs(swordStorage:GetChildren()) do
	childrenNames[child.Name] = true
end

local function checkAndReplaceSword()
	local backpack = player.Backpack
	for _, tool in ipairs(backpack:GetChildren()) do
		if childrenNames[tool.Name] then
			tool:Destroy()
		end
	end
end

local function changeImage()
	local imageLink = "rbxassetid://17316025753"
	local parent = script.Parent.Parent

	for _, child in ipairs(parent:GetChildren()) do
		local image = child:FindFirstChild("EquipButton")

		if (image == nil) then
			continue
		end

		image.Image = imageLink
	end
end

local function TweenUI()
	uiElement.Position = UDim2.new(0.5, 0, 1.5, 0)
	uiElement.Size = UDim2.new(0, 0, 0, 0)
	uiElement.Visible = true
	uiElement.SwordImage.Image = script.Parent.ImageLabel.Image
	uiElement.SwordImageBg.Image = script.Parent.ImageLabel.Image
	game.Lighting.Blur.Enabled = true

	local tweenInfo = TweenInfo.new(
		1,
		Enum.EasingStyle.Quad,
		Enum.EasingDirection.Out,
		0,
		false,
		0
	)

	local targetProperties = {
		Position = UDim2.new(0.275, 0,0.258, 0),
		Size = UDim2.new(0, 589,0, 387),
	}

	local tween = TweenService:Create(uiElement, tweenInfo, targetProperties)
	tween:Play()
end

script.Parent.MouseEnter:Connect(function()
	hoverSound:Play()
end)

local function buyItem()
	clickSound:Play()
	script.Parent.Parent.Parent.Visible = false

	local confirmationUI = player.PlayerGui["User Interface"].UserUI.SwordConfirmationUI
	confirmationUI.SwordName.Text = script.Parent.Name

	if confirmationUI then
		confirmationUI.Visible = true
		confirmationUI.GemsCost.Text = gemCost
		confirmationUI.SwordImage.Image = script.Parent.ImageLabel.Image
		local yesButton = confirmationUI:FindFirstChild("YesButton")
		if yesButton then
			yesButton.MouseButton1Click:Connect(function()
				local checkGems = game.ReplicatedStorage.Functions.CheckGems:InvokeServer(gemCost)
				if checkGems then
					swordPurchasedEvent:FireServer(sword)
					confirmationUI.Visible = false
					equipButton.Visible = true
					TweenUI()
					game.ReplicatedStorage.GameSounds.PurchaseSound:Play()
				else
					print("Not enough gems")
				end
			end)
		end

		local noButton = confirmationUI:FindFirstChild("NoButton")
		if noButton then
			noButton.MouseButton1Click:Connect(function()
				confirmationUI.Visible = false
				clickSound:Play()
				script.Parent.Parent.Parent.Visible = true
			end)
		end
	end
end


buyButton.MouseButton1Click:Connect(buyItem)

equipButton.MouseEnter:Connect(function()
	hoverSound:Play()
end)

equipButton.MouseButton1Click:Connect(function()
	clickSound:Play()
	if equipButton.Image == "rbxassetid://17316025753" then
		if sword_to_give then
			changeImage()
			equippedSwordChangedEvent:FireServer(sword_to_give) 
			equipButton.Image = "rbxassetid://17316048949"
		end
	elseif equipButton.Image == "rbxassetid://17316048949" then
		equipButton.Image = "rbxassetid://17316025753"    
	end
end)

Gem Checker Script;

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local checkGemFunction = ReplicatedStorage.Functions.CheckGems

checkGemFunction.OnServerInvoke = function(player, gemCost)
		if player.leaderstats.Gems.Value >= gemCost then
			return true
		else
			return false
		end
	end

Deduct Gems Script;

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local swordPurchasedEvent = ReplicatedStorage.Events.SwordPurchasedEvent

local swordPrices = {
	["Spartan Sword"] = 500,
	["Steampunk Sword"] = 1000,
	["Skelly Slayer"] = 1500,
	["Signifier Sword"] = 2000,
	["Darkheart"] = 2750,
	["Overseer Wrath"] = 5000,
	["Serpent Sword"] = 6000,
	["Light Blade"] = 7500,
	["Plated Sword"] = 9250,
	["Uppercut Sword"] = 11000,
	["Evil Knight"] = 13450,
	["Arabian Knight"] = 16000,
	["Spec Elipson"] = 19000,
	["Interstellar Sword"] = 23500,
	["RGB Sword"] = 31000,
	["Violet Sword"] = 40000,
	["Gilded Sword"] = 52500,
	["Omi Odachi Sword"] = 65000,
	["Orc Blade"] = 80000,
	["Sorcus Sword"] = 97500,
	["Sword Of Darkness"] = 111000,
	["Amethyst Rock Sword"] = 125000,
	["Blood Sword"] = 200000,
	["Molten Scythe"] = 250000,
}

swordPurchasedEvent.OnServerEvent:Connect(function(player, sword)
	local weapon = ReplicatedStorage.Swords:FindFirstChild(sword)
	if weapon then
		local price = swordPrices[sword]
		if player.leaderstats.Gems.Value >= price then
			player.leaderstats.Gems.Value = player.leaderstats.Gems.Value - price
		end
	end
end)

In summary, the issue is that when the player buys the item, the purchase goes through however the gems do not get deducted. I only faced this issue after adding the GemCheck RemoteFunction, I would check if the player has enough gems on the purchase script however exploiters could change their gem value on the client side and the purchase script would allow the purchase to go through, as it is a LocalScript.

Maybe try putting the gem deduct thing to be inside of the gem checker. There’s no need to separate them.

This might help you debug it

But also keep that module with the list of prices.

Also another thing you can do is add an IntValue named Price and put them in each of the objects tools(For example Serpent Sword) in ServerStorage. Assuming that you have the objects in ServerStorage. Or you could also use attributes.

How do you suggest I put the two together? It’s really confusing to me since I’m a bit new to RemoteEvents and RemoteFunctions.

I don’t really see how putting them two together would help.

Also, a question about RemoteFunctions, when they return something - such as true or false how do I use an if statement with what it returned?

For example, if the RemoteFunction returns true would it be something like;

`
if gemCheck == true then
print(hello)
end

`
?

Please let me know if you can, thanks. :happy3:

Server script

checkGemFunction.OnServerInvoke = function(player, gemCost)
		if player.leaderstats.Gems.Value >= gemCost then
                        player.leaderstats.Gems.Value -= gemCost-- add this
			return true
		else
			return false
		end
	end

Local script

.MouseButton1Click(function()
   local success = checkGemFunction:InvokeServer(gemCost)

   if success then

   end

end)

Also I recommend renaming the remote function to “buySwordRemote” or something like that.

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