i want to add 1 time purchase on items but it allows many times and my script don’t work
local Name = script.Parent.Name
local Robux = script.Parent.Robux
local Imageid = script.Parent.Image
local BoolIfOwns = script.Parent.SlingShot
local DataStoreService = game:GetService("DatastoreService")
local ds = DataStoreService:GetDataStore("datatest")
print("Running Robux Purchases")
while wait() do
if script.Parent.Parent.InsidePurchase then
script.Parent.Title.Text = tostring(script.Parent.NamePass.Value) --does the name first
script.Parent.Price.Text = tostring(script.Parent.Robux.Value)
script.Parent.ImageLabel.Image = "http://www.roblox.com/asset/?id="..tostring(Imageid.Value)
Robux.Value = string.gsub(Robux.Value, "^(-?%d+)(%d%d%d)", '%1,%2')
if Robux.Value == "0" then
Robux.Value = "Free"
end
end
end
game.Players.PlayerAdded:Connect(function(plr)
local Folder = Instance.new("Folder",plr)
Folder.Name = "Purchase"
local BoolValue = Instance.new("BoolValue",Folder)
BoolValue.Name = "SlingShot"
local dataofuser = ds:GetAsync(plr.UserId)
if dataofuser ~= nil then -- anything but nil
print("Found data for " .. plr.Name)
BoolValue.Value = ds[1]
else
print("Replacing no data with new data.")
BoolValue = false
end
end)
game.Players.PlayerRemoving:Connect(function(plr)
local datasave = {}
table.insert(datasave, plr:WaitForChild("Purchase"):WaitForChild("SlingShot").Value)
local success,response = pcall(function()
ds:SetAsync(plr.UserId, datasave)
end)
if success then
print("succesfully saved data of " .. plr.Name)
else
warn(response)
end
end)
bro not the question like buying tools and then it disables but
isn’t working here picture I remade it coz I am making like roblox but ok I added boolvalue still NOT WORKING /: I wanna save it too so
Do you mean the player can own multiple copies of the tool at once, or do they have to repurchase the item each time they join the game? If it’s the former, ensure the player doesn’t already have the item before giving it to them.
From my understanding, the code snippet only updates the pop-up that appears and manages data. Can you share the code that gives the player the item, please?
Anyway, with your method, you could check if the item is owned with something like
if item.IsOwned.Value == false then
-- give the player the item
where IsOwned is a BoolValue inside the item.
If you haven’t already, I suggest looking at solutions related to your goal on the DevHub.
To fix this issue, you will need to update your code to properly track whether a player has already purchased an item. One way to do this is to store a list of items that the player has purchased in the Datastore, and check if the item they are trying to purchase is already in that list. If it is, you can prevent the player from purchasing the item again.
local toolfolder = game:GetService("ServerStorage"):FindFirstChild("Tools")
local DataStoreService = game:GetService("DataStoreService")
local SaveData = DataStoreService:GetDataStore("SaveData")
game.Players.PlayerAdded:Connect(function(Player)
local ToolData = SaveData:GetAsync(Player.UserId)
local Backpack = Player:WaitForChild("Backpack")
local StarterGear = Player:WaitForChild("StarterGear")
if ToolData ~= nil then
for i, v in pairs(ToolData) do
if toolfolder:FindFirstChild(v) and Backpack:FindFirstChild(v) == nil and StarterGear:FindFirstChild(v) ==nil then
toolfolder[v]:Clone().Parent = Backpack
toolfolder[v]:Clone().Parent = StarterGear
end
end
end
Player.CharacterRemoving:Connect(function(Character)
Character:WaitForChild("Humanoid"):UnequipTools()
end)
end)
game.Players.PlayerRemoving:Connect(function(Player)
local ToolTable = {}
for i, v in pairs(Player.Backpack:GetDescendants()) do
table.insert(ToolTable, v.Name)
end
if ToolTable ~= nil then
SaveData:SetAsync(Player.UserId, ToolTable)
end
end)
but I’m making roblox studio inside roblox and wanted to make custom gamepass with boolvalue every single place there are 1 per purchase
Sorry, I mean the code that gives the player the item when they click the “Buy” button.
toolfolder[v]:Clone().Parent = StarterGear
For the code you sent, I wouldn’t recommend cloning the tool to StarterGear since any players who join after will get the tool. Cloning it to their Backpack is sufficient.
local Name = script.Parent.Name
local Robux = script.Parent.Robux
local Imageid = script.Parent.Image
local BoolIfOwns = script.Parent.SlingShot
local DataStoreService = game:GetService("DatastoreService")
local ds = DataStoreService:GetDataStore("datatest")
print("Running Robux Purchases")
while wait() do
if script.Parent.Parent.InsidePurchase then
script.Parent.Title.Text = tostring(script.Parent.NamePass.Value) --does the name first
script.Parent.Price.Text = tostring(script.Parent.Robux.Value)
script.Parent.ImageLabel.Image = "http://www.roblox.com/asset/?id="..tostring(Imageid.Value)
Robux.Value = string.gsub(Robux.Value, "^(-?%d+)(%d%d%d)", '%1,%2')
if Robux.Value == "0" then
Robux.Value = "Free"
end
end
end
no worrys its just test place but i am making like roblox purchase popup but old version and coz I don’t want to make people get robux only get ingame and I wanna make 1 per purchase per fake gamepasses
--[[ the first script ]]--
-- code before...
game.Players.PlayerRemoving:Connect(function(plr)
local datasave = {}
-- boolean value is saved here...
table.insert(datasave, plr:WaitForChild("Purchase"):WaitForChild("SlingShot").Value)
local success,response = pcall(function()
ds:SetAsync(plr.UserId, datasave)
end)
-- code after...
--[[ the second script ]]--
-- code before...
if ToolData ~= nil then
for i, v in pairs(ToolData) do -- v is a boolean value (true/false)
-- ... but we need a string name to find the tool, which won't work with bool values
if toolfolder:FindFirstChild(v) and Backpack:FindFirstChild(v) == nil and StarterGear:FindFirstChild(v) ==nil then
toolfolder[v]:Clone().Parent = Backpack
toolfolder[v]:Clone().Parent = StarterGear
end
end
end
-- code after...
It looks like the BoolValue value of SlingShot, which is either true or false, is saved to track purchased items (first script), but the items are looked for by name, which is a string, when loading them (second script).
It may be better to check if the player owns the item with the BoolValue, then store the name of the item to match the loading method.
-- itemValue is the BoolValue associated with the item
local itemValue = plr:WaitForChild("Purchase"):WaitForChild("SlingShot")
if itemValue.Value == true then
table.insert(datasave, itemValue.Name)
end
-- code continues...
In that case, store the value of NamePass in datasave. Since NamePass represents a string and not a boolean, it won’t tell you if the player owns the item or not.
table.insert(datasave, NamePass.Value)
-- or whatever the path for NamePass is
Based on how I understand the code, this is what I have in mind for that section.
-- itemValue is the BoolValue associated with the item
local itemValue = plr:WaitForChild("Purchase"):WaitForChild("SlingShot")
if itemValue.Value == true then
table.insert(datasave, NamePass.Value)
end
-- code continues...
Correct me if I’m wrong, but itemValue is a boolean value that marks whether the item is owned. It’s the same BoolValue created and added to the player’s purchase folder when they join. I’ve only stored the value as itemValue to make the code more readable, although it doesn’t make it any different from
if plr:WaitForChild("Purchase"):WaitForChild("SlingShot").Value == true then
table.insert(datasave, NamePass.Value)
end
-- code continues...