Hello!
- 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?
Thank you!