How can I improve my Shop purchase script further?
Hello!
I have a pretty nifty shop purchase script, but I want to streamline it further to put more of the work on the Server as opposed to the Client/Local. I've created a few Remote Events that seem to be working fine, but I'm not sure I'm utilizing them properly for max efficiency. Essentially, my goal here is to make sure the shop purchase script works properly, and never over/double charges the player, or sends their Coins into the negative. I'd had that happen previously, randomly, when I was relying entirely on the Client/Local doing the function, and that is not ideal for the player experience.
Here are my Remote Events inside the Script under ServerScriptStorage:
02 | local ReplicatedStorage = game:GetService( "ReplicatedStorage" ) |
04 | local Events = ReplicatedStorage:WaitForChild( "Events" ) |
06 | local CoinsPurchase = Events:WaitForChild( "CoinsPurchase" ) |
07 | local ItemOwned = Events:WaitForChild( "ItemOwned" ) |
08 | local CanAffordItem = Events:WaitForChild( "CanAffordItem" ) |
11 | CoinsPurchase.OnServerEvent:Connect( function (Player, Value, Amount) |
12 | if Player.leaderstats.Coins.Value > = Amount then |
13 | print ( 'Server says player has enough Coins for the purchase.' ) |
14 | Player.leaderstats.Coins.Value = Player.leaderstats.Coins.Value - Amount |
18 | print ( "Player does not have enough Coins for the purchase." ) |
24 | ItemOwned.OnServerEvent:Connect( function (Player,Value) |
25 | if Value.Value = = false then |
26 | print ( 'Player does not own this item.' ) |
28 | print ( 'Player does own item' ) |
34 | CanAffordItem.OnServerEvent:Connect( function (Player,Value, Amount) |
35 | if Player.leaderstats.Coins.Value > = Amount then |
36 | print ( 'Player CAN afford Item' ) |
38 | print ( 'Player Can NOT afford Item' ) |
And this is a slightly abbreviated version of my shop purchase Local Script. When the Item01 button is clicked, it makes visible the BuyButton script and fills in the variables:
02 | local RS = game:GetService( "ReplicatedStorage" ) |
03 | local Players = game:GetService( "Players" ) |
04 | local Player = Players.LocalPlayer |
05 | local currencyCOINS = Player.leaderstats.Coins |
08 | local Events = RS:WaitForChild( "Events" ) |
11 | local ToolPurchase = Events:WaitForChild( "ToolPurchase" ) |
12 | local CoinsPurchase = Events:WaitForChild( "CoinsPurchase" ) |
13 | local ItemOwned = Events:WaitForChild( "ItemOwned" ) |
14 | local CanAffordItem = Events:WaitForChild( "CanAffordItem" ) |
17 | local PurchaseFrame = Frame.PurchaseFrame |
18 | local BuyButton = PurchaseFrame.BuyButton |
19 | local ItemDesc = PurchaseFrame.ItemDesc |
20 | local Price = PurchaseFrame.Price |
22 | local ItemTrackName = RS:WaitForChild( "ItemTrackNameShop" ) |
23 | local ItemPurchased = RS:WaitForChild( "ItemPurchased" ) |
24 | local ItemPriceAmount = RS:WaitForChild( "ItemPriceAmount" ) |
27 | BuyButton.MouseButton 1 Click:Connect( function () |
30 | local Value = ItemPurchased.Value |
31 | ItemDesc.Text = 'Purchase ' ..ItemTrackName.Value.. '?' |
32 | Price.Text = ItemPriceAmount.Value |
34 | ItemOwned:FireServer(Player.Inventory [ Value ] ) |
35 | CanAffordItem:FireServer(Player.Inventory [ Value ] , amount) |
36 | if Player.Inventory [ Value ] .Value = = true then |
37 | ItemDesc.Text = 'You have already purchased this Item!' |
41 | if Player.leaderstats.Coins.Value > = amount then |
42 | CoinsPurchase:FireServer(Player.Inventory [ Value ] , amount) |
44 | PurchaseClickSound:Play() |
45 | ItemDesc.Text = 'Purchase Complete for ' ..ItemTrackName.Value.. '! Equip this Item from your Inventory!' |
47 | PurchaseFrame.Visible = false |
48 | ItemDesc.Text = 'Purchase ' ..ItemTrackName.Value.. '?' |
51 | local coinsrequired = amount - currencyCOINS.Value |
52 | ItemDesc.Text = 'You need ' .. coinsrequired .. ' more Coins to buy this item!' |
54 | ItemDesc.Text = 'Purchase ' ..ItemTrackName.Value.. '?' |
56 | PurchaseFrame.Visible = false |
61 | Item 01. MouseButton 1 Click:Connect( function () |
62 | PurchaseFrame.Visible = true |
63 | ItemTrackName.Value = 'Item01' |
64 | ItemDesc.Text = 'Purchase Item01?' |
65 | ItemPurchased.Value = 'Item01' |
67 | ItemPriceAmount.Value = Cost |
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!