- What are you attempting to achieve? I’m looking to improve my Purchase system to put more of the process on the server-side than the client-end to ensure that bad player experiences - such as having a purchase put your Coins in the negatives, does not occur.
- What is the issue? I’m a bit shaky on my understanding of Remote Events, and am unsure if I’m using them in the most efficient way.
- What solutions have you tried so far? (Have you searched for solutions through the Roblox Wiki yet?) I have indeed used the Wiki, and have edited my script many times as my understanding has grown. I’ve considered making a unique Remote Event for every single purchase, but I have over 700+ items and would like to avoid that many Remote Events if there’s a better way to do this,
So far, the script I have is working just fine, but I want to know if I can make it better to improve player experience and prevent potential bad things from happening - double purchases, overcharged, reduce the ability to exploit as much as possible.
Here are my Remote Events inside the Script under ServerScriptStorage:
--//Get Services local ReplicatedStorage = game:GetService("ReplicatedStorage") --//EventFolder local Events = ReplicatedStorage:WaitForChild("Events") --//Remote Events local CoinsPurchase = Events:WaitForChild("CoinsPurchase") local ItemOwned = Events:WaitForChild("ItemOwned") local CanAffordItem = Events:WaitForChild("CanAffordItem") -- PURCHASE WITH COINS -- CoinsPurchase.OnServerEvent:Connect(function(Player, Value, Amount) if Player.leaderstats.Coins.Value >= Amount then print('Server says player has enough Coins for the purchase.') Player.leaderstats.Coins.Value = Player.leaderstats.Coins.Value - Amount print(Value) Value.Value = true else print("Player does not have enough Coins for the purchase.") end end) --CHECK IF ITEM OWNED -- ItemOwned.OnServerEvent:Connect(function(Player,Value) if Value.Value == false then print('Player does not own this item.') else print('Player does own item') end end) --CHECK IF PLAYER CAN AFFORD ITEM -- CanAffordItem.OnServerEvent:Connect(function(Player,Value, Amount) if Player.leaderstats.Coins.Value >= Amount then print('Player CAN afford Item') else print('Player Can NOT afford Item') end end)
And this is a slightly abbreviated version of my shop purchase Local Script inside the Shop Gui. When the Item01 button is clicked, lines on that at the end of the script, it makes visible the BuyButton script and fills in the variables, specifically the Cost and the Value:
--//Get Services local RS = game:GetService("ReplicatedStorage") local Players = game:GetService("Players") local Player = Players.LocalPlayer local currencyCOINS = Player.leaderstats.Coins --//EventFolder local Events = RS:WaitForChild("Events") --//Events local ToolPurchase = Events:WaitForChild("ToolPurchase") local CoinsPurchase = Events:WaitForChild("CoinsPurchase") local ItemOwned = Events:WaitForChild("ItemOwned") local CanAffordItem = Events:WaitForChild("CanAffordItem") --//SHOP FRAME local PurchaseFrame = Frame.PurchaseFrame local BuyButton = PurchaseFrame.BuyButton local ItemDesc = PurchaseFrame.ItemDesc local Price = PurchaseFrame.Price local ItemTrackName = RS:WaitForChild("ItemTrackNameShop") local ItemPurchased = RS:WaitForChild("ItemPurchased") local ItemPriceAmount = RS:WaitForChild("ItemPriceAmount") BuyButton.MouseButton1Click:Connect(function() MenuClickSound:Play() local amount = Cost local Value = ItemPurchased.Value ItemDesc.Text = 'Purchase '..ItemTrackName.Value..'?' Price.Text = ItemPriceAmount.Value ItemOwned:FireServer(Player.Inventory[Value]) -- Checks if the Item is owned. CanAffordItem:FireServer(Player.Inventory[Value], amount) -- Checks if the Player can afford the Item. if Player.Inventory[Value].Value == true then ItemDesc.Text = 'You have already purchased this Item!' wait(3) else if Player.leaderstats.Coins.Value >= amount then CoinsPurchase:FireServer(Player.Inventory[Value], amount) wait(1) PurchaseClickSound:Play() ItemDesc.Text = 'Purchase Complete for '..ItemTrackName.Value..'! Equip this Item from your Inventory!' wait(3) PurchaseFrame.Visible = false ItemDesc.Text = 'Purchase '..ItemTrackName.Value..'?' wait(1) else local coinsrequired = amount - currencyCOINS.Value ItemDesc.Text = 'You need '.. coinsrequired ..' more Coins to buy this item!' wait(2) ItemDesc.Text = 'Purchase '..ItemTrackName.Value..'?' wait(5) PurchaseFrame.Visible = false end end end)--Closes Purchase Frame Item01.MouseButton1Click:Connect(function() PurchaseFrame.Visible = true ItemTrackName.Value = 'Item01' ItemDesc.Text = 'Purchase Item01?' ItemPurchased.Value = 'Item01' Cost = 10 ItemPriceAmount.Value = Cost end) --Additional Items: Item02, Item03, etc. that when their respective button is pressed, will change the variables in the BuyButton script above.
As you can see in the shop purchase script above, I first run the Remote Events to see if the Player already owns the item, and then if they can afford the item, before following it up with the local/client determining the same thing, and then the Remote Event fires that actually grants the Item, and deducts the amount/cost of the Item.
Am I using the Remote Events correctly here? Can I improve upon it further?