Keep in mind that I'm a beginner at developing roblox games and have started to understand how codes work generally.
In my game: one of the major parts of the game is to make the shop system efficient and secure. Of course I have to make all features secure.
So far I've come up with this kind of shop system. In which the purchase event runs with the button(Currently this works for coins only. I haven't made the system check what kind of currency is going to be used yet)
When the buy button is pressed, the display price(display is supported with Ui with a script designed for the shop system itself. This menas there's going to be many scripts) is going to be subtracted from the players price. If the player doesn't have enough coins, a frame will pop up telling them. Else, It's going to do as the code does. After that, the corresponding item Ui with a script designed for the equipment system will be cloned to the weapon equipment scrolling frame.
It also comes with an addition of telling if the player has bought the item. I used a folder to make sure that everything which was bought is going to the specific folder.
(localscript)
-- Player vars
local Player = game.Players.LocalPlayer
local leaderboard = Player:WaitForChild("leaderstats")
-- services
local RS = game:GetService("ReplicatedStorage")
-- Events
local EFolder = game.ReplicatedStorage:WaitForChild("EventsFolder")-- Brings the folder
local CPurchase = EFolder:WaitForChild("CoinsPurchase")
local OweItem = EFolder:WaitForChild("OwnedItem")
local Affordable = EFolder:WaitForChild("OwnedItem")
-- Buttons and item data
local button = script.Parent
local price = script.Parent.Parent.Price
local thisName = script.Parent.Parent.ItemNameview
local Purchased = script.Parent.Parent.PurchasedLabel
-- CheckItemsOwned folder
local BoughtItems = game.ReplicatedStorage.BoughtItems
-- Purchase
button.MouseButton1Click:Connect(function()
game.ReplicatedStorage.EventsFolder.CoinsPurchase:FireServer()
if leaderboard.Coins.Value >= price.Value then
leaderboard.Coins.Value = leaderboard.Coins.Value - price.Value
local RSItem = RS:WaitForChild(thisName.Text)
RSItem:Clone().Parent = BoughtItems
local ThisUI = game.ReplicatedStorage.UIStore:WaitForChild(thisName.Text)
local WeaponEquipment = Player.PlayerGui.Navigations.EquipmentFrame.WeaponsScroller
ThisUI:Clone().Parent = WeaponEquipment
end
if BoughtItems:FindFirstChild(thisName.Text) then -- Check if the item is owned/purchased
button.Visible = false
Purchased.Visible = true
else
button.Visible = true
Purchased.Visible = false
end
if leaderboard.Coins.Value < price.Value then
Player.PlayerGui.Navigations.ShopFrame.InsufficientDisplay.Visible = true
end
end)
Here comes the part which I haven't fully understood yet. Using the remoteevents. From what I understand, I have to set up a condition, which in this case is when I press the purchase button. When that condition triggers, I have to tell the remote event what to do. I think whatever code I write in the onserverevent is what I code I want to become legit. Do I think right?
-- folder
local EFolder = game.ReplicatedStorage.EventsFolder
-- services
local RS = game:GetService("ReplicatedStorage")
-- events
local CPurchase = EFolder.CoinsPurchase
local GPurchase = EFolder.GemsPurchase
-- functions
CPurchase.OnServerEvent:Connect(function(player) -- event for CPurchase
print("event fired")
local Player = game.Players.LocalPlayer
repeat wait() until Player
local leaderboard = Player:WaitForChild("leaderstats")
local price = Player.PlayerGui.Navigations.ShopFrame.ShopPreviewFrame.Price
local thisName = Player.PlayerGui.Navigations.ShopFrame.ShopPreviewFrame.ItemNameview
local BoughtItems = game.ReplicatedStorage.BoughtItems
local button = Player.PlayerGui.Navigations.ShopFrame.ShopPreviewFrame.BuyButton
local Purchased = Player.PlayerGui.Navigations.ShopFrame.ShopPreviewFrame.PurchasedLabel
if leaderboard.Coins.Value >= price.Value then
leaderboard.Coins.Value = leaderboard.Coins.Value - price.Value
local RSItem = RS:WaitForChild(thisName.Text)
RSItem:Clone().Parent = BoughtItems
local ThisUI = game.ReplicatedStorage.UIStore:WaitForChild(thisName.Text)
local WeaponEquipment = game.Players.LocalPlayer.PlayerGui.Navigations.EquipmentFrame.WeaponsScroller
ThisUI:Clone().Parent = WeaponEquipment
end
if BoughtItems:FindFirstChild(thisName.Text) then
button.Visible = false
Purchased.Visible = true
else
button.Visible = true
Purchased.Visible = false
end
if leaderboard.Coins.Value < price.Value then
game.StarterGui.Navigations.ShopFrame.InsufficientDisplay.Visible = true
end
end)
Is there any way to improve the whole entire thing? Leave comments below.

4 comments
Just one problem: It's literally impossible to make a game exploit-free.
Yap, people say using remote events prevent it but that's so wrong, there are some ways to do it, but you gotta go deep
As long as you make sure the server (normal Script) handles everything that could be exploited your fine and you can use remotes to communicate between the client and the server.
@gullet please give an example