So I currently have this script to give cash when you buy one of my Developer Products from my shop.
local rep = game.ReplicatedStorage local PurchaseHistory = game:GetService("DataStoreService"):GetDataStore("PurchaseHistory") local MarketplaceService = game:GetService("MarketplaceService") --Looks cleaner this way, huh? local passes = { AddHealthID = 23781490 , AddSpeedID = 23781477, CashID = 23781403, CashID2 = 23781461, AddGear = { 23781539, 23781551, 23781557, 23781581 } } MarketplaceService.ProcessReceipt = function(receiptInfo) local playerProductKey = receiptInfo.PlayerId .. ":" .. receiptInfo.PurchaseId if PurchaseHistory:GetAsync(playerProductKey) then return Enum.ProductPurchaseDecision.PurchaseGranted end for i, player in ipairs(game.Players:GetPlayers()) do if player.userId == receiptInfo.PlayerId then local hum = player.Character:WaitForChild('Humanoid') local bp = player.Backpack local sg = player.StarterGear --Health if receiptInfo.ProductId == passes.AddHealthID then hum.MaxHealth = hum.MaxHealth + 50 hum.Health = hum.MaxHealth --Speed elseif receiptInfo.ProductId == passes.AddSpeedID then hum.WalkSpeed = hum.WalkSpeed + 15 --Gear 1 elseif receiptInfo.ProductId == passes.AddGear[1] then local tool = rep.GravityCoil tool:Clone().Parent = bp tool:Clone().Parent = sg --Gear 2 elseif receiptInfo.ProductId == passes.AddGear[2] then local tool = rep.LockonLauncher tool:Clone().Parent = bp tool:Clone().Parent = sg --Gear 3 elseif receiptInfo.ProductId == passes.AddGear[3] then local tool = rep.JetPack tool:Clone().Parent = bp tool:Clone().Parent = sg --Gear 4 elseif receiptInfo.ProductId == passes.AddGear[4] then local tool = rep.EpicLaser tool:Clone().Parent = bp tool:Clone().Parent = sg --Money elseif receiptInfo.ProductId == passes.CashID then local stat = player.leaderstats.Cash stat.Value = stat.Value + 10000 elseif receiptInfo.ProductId == passes.CashID2 then local stat = player.leaderstats.Cash stat.Value = stat.Value + 20000 end end end PurchaseHistory:SetAsync(playerProductKey, true) return Enum.ProductPurchaseDecision.PurchaseGranted end
I used this script to give money to players with a certain GamePass and it works completely fine with the money actually being real and usable so maybe I could merge it, but I don't know how.
gps = game:GetService("GamePassService"); id = script:WaitForChild("GamePassID"); game.Players.PlayerAdded:connect(function(Player) Player:WaitForDataReady() if gps:PlayerHasPass(Player , id.Value) then stats=game.ServerStorage:WaitForChild("MoneyStorage") if stats~=nil then currency = stats:WaitForChild(Player.Name) if currency~=nil then bonus=script:WaitForChild("AdminCash") currency.Value = currency.Value+bonus.Value end end end end)
The script above has things in it named AdminCash, Currency, and GamePassID. AdminCash which is the amount of money you want to add. Currency is ya know the Currency and the GamePassID is the ID of the GamePass
This changes the number on the leader board but it is just Ghost Money meaning that it is just for show it isn't actually real. This is most likely because the Money Storage is in the ServerStorage to keep it safe. Please help edit that script to make it work with the MoneyStorage being in ServerStorage. Thanks!
Putting the money into ServerStorage would be okay. But you cannot read the money from the players client. AKA (LocalScripts) so you would have to make a different location for the money even though you are trying to keep it safe. Or you can use RemoteEvents and RemoveFunctions, to read the money.
The wiki states "Similar to BindableEvents, but allow crossing the client/server boundary. This allows a Server Script to call code in a Local Script and vice versa. This can be useful when using features such as FilteringEnabled.
If the result of the call is needed then use a RemoteFunction. Otherwise a RemoteEvent is recommended as it will minimize network traffic and latency. "
WaitForDataReady
is not necessary when working with data stores. It was meant to be used with DataPersistence
and is pretty much useless in this context.
You can't fetch/get/read anything in ServerStorage
from the client, because as seen in the name itself, it is meant to be a storage for the server. The only way to communicate and relay information between client-server would be by use of RemoteObjects (RemoteEvents and/or RemoteFunctions)
If you want to keep MoneyStorage
in ServerStorage
, you wuld definitely have to consider using remotes.
Alternatively, you could always parent MoneyStorage
to ReplicatedStorage
and save yourself the hassle of working with remotes. I wouldn't necessarily recommend it because it's always good to get used to working with FilteringEnabled
and knowing how to use remotes will be very crucial to keeping everything balanced.