The code is not working as intended

  1. What do you want to achieve? When a player doesnt have enough coins then the buy button shouldn’t be visible

  2. What is the issue? the issue is that even when the player has enough coins the buy button is not visible

  3. What solutions have you tried so far? Instead of visible i also played the transparency but it didnt work

local rep = game:GetService("ReplicatedStorage")
local items = game:GetService("ServerStorage"):WaitForChild("Tools")

local price = items[item].Cost.Value
	if player.leaderstats.Coins.Value < price then
		game.StarterGui.tools_gui.tools_frame.canbuy.ImageTransparency = 1
		print("aa") game.StarterGui.tools_gui.tools_frame.cant_buy.ImageTransparency = 0 
		print("bb") 
		game.StarterGui.tools_gui.tools_frame.status.Text = "CANT BUY!" 
		print("Cc")

elseif player.leaderstats.Coins.Value >= price then 
			player.leaderstats.Coins.Value = player.leaderstats.Coins.Value - price
			game.StarterGui.tools_gui.tools_frame.canbuy.ImageTransparency = 0
			print("a")
			game.StarterGui.tools_gui.tools_frame.cant_buy.ImageTransparency =1
			print("b")
			game.StarterGui.tools_gui.tools_frame.status.Text = "BUY!"
		print("c")
		local gear = items[item]:Clone()
		gear.Parent = game.ServerStorage.OwnedItems

		local gear = items[item]:Clone()
		gear.Parent = player.Backpack
		return true

Please help me As soon as possible, thank you :slight_smile:

Also if you are wondering i made an advanced version of this video by alvin blox: Roblox Shop GUI Tutorial - Buy Items with Currency - YouTube

2 Likes

First of all, make sure the script is a local script to make the UI invincible. Then I would suggest just having a check on the server side to make sure the player has enough coins in case they are hacking to make the button visible.

The main issue is that you are doing game.StarterGui. If you try player.PlayerGui it will work but all players will get affected because it looks like this is a server script. Use a local script inside the screen GUI and reference the player like this:

local player = game:GetService(“Players”).LocalPlayer
local screenGui = script.Parent

2 Likes

ServerScriptService.leaderstats:42: invalid argument #2 (string expected, got nil) - the error

local player = game:GetService("Players").LocalPlayer

game.ReplicatedStorage.Remotes.sale:InvokeServer(function(item)
	
	local price = game.ServerStorage.Tools[item].Cost.Value
	if player.leaderstats.Coins.Value < price then
		game.StarterGui.tools_gui.tools_frame.canbuy.ImageTransparency = 1
		print("aa") game.StarterGui.tools_gui.tools_frame.cant_buy.ImageTransparency = 0 
		print("bb") 
		game.StarterGui.tools_gui.tools_frame.status.Text = "CANT BUY!" 
		print("Cc")

	elseif player.leaderstats.Coins.Value >= price then 
		player.leaderstats.Coins.Value = player.leaderstats.Coins.Value - price
		game.StarterGui.tools_gui.tools_frame.canbuy.ImageTransparency = 0
		print("a")
		game.StarterGui.tools_gui.tools_frame.cant_buy.ImageTransparency =1
		print("b")
		game.StarterGui.tools_gui.tools_frame.status.Text = "BUY!"
		print("c")

	end
end) -- code

show us line 42, that is where the error is at

Now when I look at your code there are many things that are not right. Invoke server should be on client side and trigger a OnInvoke on server side, the price and coin check should then be on the server and then the server should return either true or false to the client depending on what it returns the UI should or should not be visible

local price = items[item].Cost.Value

local player = game:GetService("Players").LocalPlayer

game.ReplicatedStorage.Remotes.sale:InvokeServer(function(item)
	
	local price = game.ServerStorage.Tools[item].Cost.Value
	if player.leaderstats.Coins.Value < price then
		game.StarterGui.tools_gui.tools_frame.canbuy.ImageTransparency = 1
		print("aa") game.StarterGui.tools_gui.tools_frame.cant_buy.ImageTransparency = 0 
		print("bb") 
		game.StarterGui.tools_gui.tools_frame.status.Text = "CANT BUY!" 
		print("Cc")

	elseif player.leaderstats.Coins.Value >= price then 
		player.leaderstats.Coins.Value = player.leaderstats.Coins.Value - price
		game.StarterGui.tools_gui.tools_frame.canbuy.ImageTransparency = 0
		print("a")
		game.StarterGui.tools_gui.tools_frame.cant_buy.ImageTransparency =1
		print("b")
		game.StarterGui.tools_gui.tools_frame.status.Text = "BUY!"
		print("c")
		return true
	end
end)`Preformatted text`

are you sure?
the error talks about a function and the second argument is nil

ServerScriptService.leaderstats
line 42 of this script

sorry i forgot to copy all the script from my studio

game.ReplicatedStorage.Remotes.sale:InvokeServer(function(item)
	
	local price = game.ServerStorage.Tools[item].Cost.Value
	if player.leaderstats.Coins.Value < price then
		game.StarterGui.tools_gui.tools_frame.canbuy.ImageTransparency = 1
		print("aa") game.StarterGui.tools_gui.tools_frame.cant_buy.ImageTransparency = 0 
		print("bb") 
		game.StarterGui.tools_gui.tools_frame.status.Text = "CANT BUY!" 
		print("Cc")

	elseif player.leaderstats.Coins.Value >= price then 
		player.leaderstats.Coins.Value = player.leaderstats.Coins.Value - price
		game.StarterGui.tools_gui.tools_frame.canbuy.ImageTransparency = 0
		print("a")
		game.StarterGui.tools_gui.tools_frame.cant_buy.ImageTransparency =1
		print("b")
		game.StarterGui.tools_gui.tools_frame.status.Text = "BUY!"
		print("c")
		return true
	end
end)

this is the exact same code as before though

I see many problems with your script first of all you can’t use RemoteFunction same as RemoteEvent, second is that you are Invoking Server on Server so that doesn’t make really sense. You should connect the function to RemoteFunction like that

game:GetService("ReplicatedStorage").RemoteFunction.OnServerInvoke = function(player, Arg1, Arg2)
local playerGui = player.PlayerGui
print(player.Name.." Invoked server")
end)

One thing to note that with RemoteFunction or RemoteEvent the first parameter of the function is always the player that invoked server.

You use InvokeServer when making a call to the server. You’re wanting to use OnServerInvoke.

ReplicatedStorage.RemoteFunction.OnServerInvoke = function(Player, ...)
    -- code for the server to handle
end

Just as an FYI - this will not work in a client script (LocalScript), since this’s intended for the server as in the name OnServerInvoke. For calls to the client, you’d want to use OnClientInvoke/InvokeClient respectively.

1 Like
local rep = game:GetService("ReplicatedStorage")
local items = game:GetService("ServerStorage"):WaitForChild("Tools")

game.Players.PlayerAdded:Connect(function(player)
	local stats = Instance.new("Folder")
	stats.Name ="leaderstats"
	stats.Parent = player
	
	local Strength = Instance.new("NumberValue")
	Strength.Name ="Strength"
	Strength.Parent = stats
	
	local Coins = Instance.new("NumberValue")
	Coins.Name ="Coins"
	Coins.Parent = stats
	Coins.Value =50

	
	
	local gems = Instance.new("NumberValue", stats)
	gems.Name = "Gems"
	
	local storage = Instance.new("NumberValue")
	storage.Value = 10
	storage.Name = "Storage"
	storage.Parent = player
	
	local Class = Instance.new("StringValue")
	Class.Name = "Class"
	Class.Parent = stats
	
	local Equipped = Instance.new("StringValue", player)
	Equipped.Name = "Equipped"
	
	local items = Instance.new("Folder", player)
	items.Name = "OwnedItems"
end)
rep.Remotes.info.OnServerInvoke = function(player , item)
	return items[item].Cost.Value
end
game:GetService("ReplicatedStorage").Remotes.sale.OnServerInvoke = function(player , item)
	local playergui = player.PlayerGui
	print(player.Name.."Invoked server")
	local price = items[item].Cost.Value
	if player.leaderstats.Coins.Value < price then
		game.StarterGui.tools_gui.tools_frame.canbuy.ImageTransparency = 1
		print("aa") game.StarterGui.tools_gui.tools_frame.cant_buy.ImageTransparency = 0 
		print("bb") 
		game.StarterGui.tools_gui.tools_frame.status.Text = "CANT BUY!" 
		print("Cc")
		
	elseif player.leaderstats.Coins.Value >= price then 
			player.leaderstats.Coins.Value = player.leaderstats.Coins.Value - price
			game.StarterGui.tools_gui.tools_frame.canbuy.ImageTransparency = 0
			print("a")
			game.StarterGui.tools_gui.tools_frame.cant_buy.ImageTransparency =1
			print("b")
			game.StarterGui.tools_gui.tools_frame.status.Text = "BUY!"
		print("c")
		local gear = items[item]:Clone()
		gear.Parent = game.ServerStorage.OwnedItems

		local gear = items[item]:Clone()
		gear.Parent = player.Backpack
		return true
	end
end

Same happened to me a really long time ago. It’s because local values are storing the value when they’ve been used, so it won’t update. Instead of making the price value with a local value, do this;

price = items[item].Cost.Value

and it should work fine.

(Edit: You also can’t see inside of the ServerStorage and ServerScriptService via a local script. So you better move Tools into ReplicatedStorage or use Remote Events/Functions.)

i am using 2 remote functions and it still doesn’t work but no errors this time

local rep = game:GetService("ReplicatedStorage")
local items = game:GetService("ServerStorage"):WaitForChild("Tools")

game.Players.PlayerAdded:Connect(function(player)
	local stats = Instance.new("Folder")
	stats.Name ="leaderstats"
	stats.Parent = player
	
	local Strength = Instance.new("NumberValue")
	Strength.Name ="Strength"
	Strength.Parent = stats
	
	local Coins = Instance.new("NumberValue")
	Coins.Name ="Coins"
	Coins.Parent = stats
	Coins.Value =50

	
	
	local gems = Instance.new("NumberValue", stats)
	gems.Name = "Gems"
	
	local storage = Instance.new("NumberValue")
	storage.Value = 10
	storage.Name = "Storage"
	storage.Parent = player
	
	local Class = Instance.new("StringValue")
	Class.Name = "Class"
	Class.Parent = stats
	
	local Equipped = Instance.new("StringValue", player)
	Equipped.Name = "Equipped"
	
	local items = Instance.new("Folder", player)
	items.Name = "OwnedItems"
end)
rep.Remotes.info.OnServerInvoke = function(player , item)
	return items[item].Cost.Value
end
game:GetService("ReplicatedStorage").Remotes.sale.OnServerInvoke = function(player , item)
	local playergui = player.PlayerGui
	print(player.Name.."Invoked server")
	price = items[item].Cost.Value
	if player.leaderstats.Coins.Value < price then
		game.StarterGui.tools_gui.tools_frame.canbuy.ImageTransparency = 1
		print("aa") game.StarterGui.tools_gui.tools_frame.cant_buy.ImageTransparency = 0 
		print("bb") 
		game.StarterGui.tools_gui.tools_frame.status.Text = "CANT BUY!" 
		print("Cc")
		
	elseif player.leaderstats.Coins.Value >= price then 
			player.leaderstats.Coins.Value = player.leaderstats.Coins.Value - price
			game.StarterGui.tools_gui.tools_frame.canbuy.ImageTransparency = 0
			print("a")
			game.StarterGui.tools_gui.tools_frame.cant_buy.ImageTransparency =1
			print("b")
			game.StarterGui.tools_gui.tools_frame.status.Text = "BUY!"
		print("c")
		local gear = items[item]:Clone()
		gear.Parent = game.ServerStorage.OwnedItems

		local gear = items[item]:Clone()
		gear.Parent = player.Backpack
		return true
	end
end

has anyone told you not to use

Nevermind i see it was said in first reply.

You already defined playergui. Please use it.

There should be no starterGui being indexed unless intended image

game:GetService("ReplicatedStorage").Remotes.sale.OnServerInvoke = function(player , item)
	local playergui = player.PlayerGui
	print(player.Name.."Invoked server")
	price = items[item].Cost.Value
	if player.leaderstats.Coins.Value < price then
		 playergui.tools_gui.tools_frame.canbuy.ImageTransparency = 1
		print("aa") game.StarterGui.tools_gui.tools_frame.cant_buy.ImageTransparency = 0 
		print("bb") 
		 playergui.tools_gui.tools_frame.status.Text = "CANT BUY!" 
		print("Cc")
		
	elseif player.leaderstats.Coins.Value >= price then 
			player.leaderstats.Coins.Value = player.leaderstats.Coins.Value - price
			 playergui.tools_gui.tools_frame.canbuy.ImageTransparency = 0
			print("a")
			 playergui.tools_gui.tools_frame.cant_buy.ImageTransparency =1
			print("b")
			 playergui.tools_gui.tools_frame.status.Text = "BUY!"
		print("c")
		local gear = items[item]:Clone()
		gear.Parent = game.ServerStorage.OwnedItems

		local gear = items[item]:Clone()
		gear.Parent = player.Backpack
		return true
	end
end

Is this a local script?

i did it but still didnt work

local rep = game:GetService("ReplicatedStorage")
local items = game:GetService("ServerStorage"):WaitForChild("Tools")

game.Players.PlayerAdded:Connect(function(player)
	local stats = Instance.new("Folder")
	stats.Name ="leaderstats"
	stats.Parent = player
	
	local Strength = Instance.new("NumberValue")
	Strength.Name ="Strength"
	Strength.Parent = stats
	
	local Coins = Instance.new("NumberValue")
	Coins.Name ="Coins"
	Coins.Parent = stats
	Coins.Value =50

	
	
	local gems = Instance.new("NumberValue", stats)
	gems.Name = "Gems"
	
	local storage = Instance.new("NumberValue")
	storage.Value = 10
	storage.Name = "Storage"
	storage.Parent = player
	
	local Class = Instance.new("StringValue")
	Class.Name = "Class"
	Class.Parent = stats
	
	local Equipped = Instance.new("StringValue", player)
	Equipped.Name = "Equipped"
	
	local items = Instance.new("Folder", player)
	items.Name = "OwnedItems"
end)
rep.Remotes.info.OnServerInvoke = function(player , item)
	return items[item].Cost.Value
end
game:GetService("ReplicatedStorage").Remotes.sale.OnServerInvoke = function(player , item)
	local playergui = player.PlayerGui
	print(player.Name.."Invoked server")
	price = items[item].Cost.Value
	if player.leaderstats.Coins.Value < price then
		playergui.tools_gui.tools_frame.canbuy.ImageTransparency = 1
		print("aa") game.StarterGui.tools_gui.tools_frame.cant_buy.ImageTransparency = 0 
		print("bb") 
		playergui.tools_gui.tools_frame.status.Text = "CANT BUY!" 
		print("Cc")
		
	elseif player.leaderstats.Coins.Value >= price then 
			player.leaderstats.Coins.Value = player.leaderstats.Coins.Value - price
			playergui.tools_gui.tools_frame.canbuy.ImageTransparency = 0
			print("a")
			playergui.tools_gui.tools_frame.cant_buy.ImageTransparency =1
			print("b")
			playergui.tools_gui.tools_frame.status.Text = "BUY!"
		print("c")
		local gear = items[item]:Clone()
		gear.Parent = game.ServerStorage.OwnedItems

		local gear = items[item]:Clone()
		gear.Parent = player.Backpack
		return true
	end
end

also not a local script

OnServerInvoke
The OnServerInvoke event fires the bound functions in Scripts when RemoteFunction:InvokeServer is called by the client from a LocalScript

Misquoted that I thought they were refering to the remote being called from a regular script

Can I see the local script that fires this remote?

sorry for the delays I am gaming :pensive:

local reps = game:GetService("ReplicatedStorage")

local item = script.Parent.Parent.Parent:WaitForChild("selecter")
local img = script.Parent.Parent.Parent:WaitForChild("tool_img")
local name = script.Parent.Parent.Parent:WaitForChild("name")

script.Parent.MouseButton1Click:Connect(function()
	
	local price = reps.Remotes.info:InvokeServer(script.Parent.Name)
	
	if price ~= nil then
		name.Text = script.Parent.Name
		img.Image = script.Parent.A.Image
		item.Value = script.Parent.Name
		script.Parent.Parent.Parent.price.Text = price
		
	end
end)