Trouble with Server Vs Client

hello im a semi new roblox developer and im trying to make a system where players can buy a item and then when said item has been bought the stock of the item will decrease for all players. however im been having some trouble wrapping my head around how i should do the client vs servers. I know that if i want to replicate change for all the players i need to use sever. my server code isnt really working and i dont know why.

this is what ive come up with:

– local script

-- local ToolsIndexScript = require(game.ReplicatedStorage.ToolsIndex)
local boughtEvent = game:GetService("ReplicatedStorage").BoughtEvnt
local rep = game:GetService("ReplicatedStorage")
local openDealerEvent = rep.OpenDealer

local tweenService = game:GetService("TweenService")

local ItemsForSaleFrame = script.Parent.ItemsForSaleFrame
local scrollingFrame = ItemsForSaleFrame.ItemsFrame.ItemsScrollingFrame

local closebutton = ItemsForSaleFrame.CloseButton

ItemsForSaleFrame.Visible = false


openDealerEvent.OnClientEvent:Connect(function()
	ItemsForSaleFrame.Visible = true
end)



closebutton.MouseButton1Click:Connect(function()
	ItemsForSaleFrame.Visible = false
end)

local player = game:GetService("Players")

local toolTemplate = script.Template -- Assuming the template is in StarterGui, you can adjust this as per your structure

for _, toolInfo in ipairs(ToolsIndexScript) do
	local newTEMP = toolTemplate:Clone()
	newTEMP.Parent = scrollingFrame
	
	local bar = newTEMP.StockFrame.bar
	local stocktext = newTEMP.StockFrame.StockText
	
	local CurrentQuanitity = newTEMP.CurrentQuanitity
	
	CurrentQuanitity.Value = toolInfo.MaxQuantity - 1
	
	bar.Size = UDim2.new(CurrentQuanitity.Value / toolInfo.MaxQuantity, 0, 1, 0)
	newTEMP.StockFrame.StockText.Text = CurrentQuanitity.Value .. "/" .. tostring(toolInfo.MaxQuantity)

	-- Populate information
	newTEMP.ToolNameFrame.ToolNameTextLabel.Text = toolInfo.Name
	newTEMP.PriceFrame.PriceTextLabel.Text = "$" .. tostring(toolInfo.Cost)
	newTEMP.ToolImage.Image = toolInfo.Image
	
	local buybutton = newTEMP.BuyButton
	if buybutton then
		buybutton.MouseButton1Click:Connect(function()
			
			boughtEvent:FireServer(buybutton)
	end)
end



	CurrentQuanitity:GetPropertyChangedSignal("Value"):Connect(function()
		bar.Size = UDim2.new(CurrentQuanitity.Value / toolInfo.MaxQuantity, 0, 1, 0)
		newTEMP.StockFrame.StockText.Text = CurrentQuanitity.Value .. "/" .. tostring(toolInfo.MaxQuantity)
	end)
end

– server script


boughtEvent.OnServerEvent:Connect(function(player, buybutton)
	if buybutton:IsA("TextButton") then
		local CQ = buybutton.Parent.CurrentQuanitity

		if CQ.Value > 0 then
			CQ.Value = CQ.Value -1 
		end
    end
end)

1 Like

You can’t really put stuff that was made using localscript into a RemoteEvent:Fire() function, since that object only exists on the Player’s end. Therefore, it doesn’t exist on the server

I’d recommend reading through this
https://devforum.roblox.com/t/understanding-the-difference-between-server-side-and-client-side/

You are sending a “BuyButton” to the server, but was it created on the client? It won’t appear on the client, you have to do it another way.

I would make it a RemoteFunction, and instead have the player send the .CurrentQuantity value, and then return the value to change it to subsequently.

Server:

boughtEvent.OnServerInvoke = function(player, cq)
	if cq > 0 then
		cq = cq - 1 
	end

        return cq
end

Client

-- local ToolsIndexScript = require(game.ReplicatedStorage.ToolsIndex)
local boughtEvent = game:GetService("ReplicatedStorage").BoughtEvnt
local rep = game:GetService("ReplicatedStorage")
local openDealerEvent = rep.OpenDealer

local tweenService = game:GetService("TweenService")

local ItemsForSaleFrame = script.Parent.ItemsForSaleFrame
local scrollingFrame = ItemsForSaleFrame.ItemsFrame.ItemsScrollingFrame

local closebutton = ItemsForSaleFrame.CloseButton

ItemsForSaleFrame.Visible = false


openDealerEvent.OnClientEvent:Connect(function()
	ItemsForSaleFrame.Visible = true
end)



closebutton.MouseButton1Click:Connect(function()
	ItemsForSaleFrame.Visible = false
end)

local player = game:GetService("Players")

local toolTemplate = script.Template -- Assuming the template is in StarterGui, you can adjust this as per your structure

for _, toolInfo in ipairs(ToolsIndexScript) do
	local newTEMP = toolTemplate:Clone()
	newTEMP.Parent = scrollingFrame
	
	local bar = newTEMP.StockFrame.bar
	local stocktext = newTEMP.StockFrame.StockText
	
	local CurrentQuanitity = newTEMP.CurrentQuanitity
	
	CurrentQuanitity.Value = toolInfo.MaxQuantity - 1
	
	bar.Size = UDim2.new(CurrentQuanitity.Value / toolInfo.MaxQuantity, 0, 1, 0)
	newTEMP.StockFrame.StockText.Text = CurrentQuanitity.Value .. "/" .. tostring(toolInfo.MaxQuantity)

	-- Populate information
	newTEMP.ToolNameFrame.ToolNameTextLabel.Text = toolInfo.Name
	newTEMP.PriceFrame.PriceTextLabel.Text = "$" .. tostring(toolInfo.Cost)
	newTEMP.ToolImage.Image = toolInfo.Image
	
	local buybutton = newTEMP.BuyButton
	if buybutton then
		buybutton.MouseButton1Click:Connect(function()
			
			boughtEvent:FireServer(buybutton.Parent.CurrentQuanitity.Value)
	end)
end



	CurrentQuanitity:GetPropertyChangedSignal("Value"):Connect(function()
		bar.Size = UDim2.new(CurrentQuanitity.Value / toolInfo.MaxQuantity, 0, 1, 0)
		newTEMP.StockFrame.StockText.Text = CurrentQuanitity.Value .. "/" .. tostring(toolInfo.MaxQuantity)
	end)
end

so will all players be able to see if the cq.Value changed? I want the action of one player to be seen on all clients

Changing anything on the server will update it for all clients, changing it for a client will only happen on that client.

1 Like

so how would i make it exisst on the server ?

1 Like