What do you want to achieve? An obby game with datastore to save player progress and a skip stage developer product.
What is the issue? At first it was working, but then suddenly it stopped working properly.
What solutions have you tried so far? I looked in the developer forum, but I couldn’t really find a solution to my issue. I also tried disabling API Services in Studio and the skip stage developer product still wasn’t working when purchased.
In the beginning it was working as intended, but after several people joined in the game (they weren’t hackers or anything of that sort), the skip stage developer product no longer worked when purchased and after rejoin, everyone was spawning at the lobby. They kept their stage number, but they didn’t spawn at the stage they were at as it used to be, but if they reset, then they would go to the stage they were before leaving.
I also get that warning when I try to purchase the Skip Stage developer product in Studio twice:
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local SaveDataStore = DataStoreService:GetDataStore("SaveData")
local function SavePlayerData(player)
local success,errormsg = pcall(function()
local SaveData = {}
for i,stats in pairs(player.leaderstats:GetChildren()) do
SaveData[stats.Name] = stats.Value
end
SaveDataStore:SetAsync(player.UserId,SaveData)
end)
if not success then
return errormsg
end
end
Players.PlayerAdded:Connect(function(player)
local Stats = Instance.new("Folder")
Stats.Name = "leaderstats"
Stats.Parent = player
local Stage = Instance.new("StringValue")
Stage.Name = "Stage"
Stage.Parent = Stats
Stage.Value = 1
local Data = SaveDataStore:GetAsync(player.UserId)
if Data then
print(Data.Stage)
for i,stats in pairs(Stats:GetChildren()) do
stats.Value = Data[stats.Name]
end
else
print(player.Name .. " has no data.")
end
player.CharacterAdded:Connect(function(character)
local Humanoid = character:WaitForChild("Humanoid")
local Torso = character:WaitForChild("HumanoidRootPart")
wait()
if Torso and Humanoid then
if Stage.Value ~= 0 then
local StagePart = workspace.Stages:FindFirstChild(Stage.Value)
Torso.CFrame = StagePart.CFrame + Vector3.new(0,1,0)
end
end
end)
end)
Players.PlayerRemoving:Connect(function(player)
local errormsg = SavePlayerData(player)
if errormsg then
warn(errormsg)
end
end)
game:BindToClose(function()
for i,player in pairs(Players:GetPlayers()) do
local errormsg = SavePlayerData(player)
if errormsg then
warn(errormsg)
end
end
wait(2)
end)
Skip Stage script:
local martketplace = game:GetService("MarketplaceService")
martketplace.ProcessReceipt = function(receiptinfo)
local players = game.Players:GetPlayers()
local finish = 0
for i=1, #players do
if players[i].UserId == receiptinfo.PlayerId then
if receiptinfo.ProductId == 1190837096 and finish == 0 then -- change your product id here at 0000000
finish = 1
players[i].leaderstats.Stage.Value = players[i].leaderstats.Stage.Value + 1
players[i].Character:MoveTo(game.Workspace.Stages:FindFirstChild(players[i].leaderstats.Stage.Value).Position)
end
end
end
return Enum.ProductPurchaseDecision.PurchaseGranted
end
I really don’t know why your Stage Spawn code fails since it seems to be written correctly (Maybe you have a spawnlocation at lobby) but about DataStores…
This means (Maybe, since the code in your post, it looks like it only saves data when they leave.) that you’re saving player’s data each time they purcharse the product without a cooldown. In Data Stores you can see in Server Limits that you have to put a cooldown (6 seconds) when repeating a write data function in the same key.
This could also tell about your problem: Players sending lots of DataStore requests, requests being dropped, new data doesn’t save and oof.
Then you have to check when your code saves player’s data, how many times could it save, and regulate it
Hello! Sorry to annoy you, but I don’t really know how to do that.
I tried adding wait() in the DataStore script (I’m not even sure if that’s the right thing to do), but it didn’t work.
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local SaveDataStore = DataStoreService:GetDataStore("SaveData")
local function SavePlayerData(player)
local success,errormsg = pcall(function()
local SaveData = {}
for i,stats in pairs(player.leaderstats:GetChildren()) do
SaveData[stats.Name] = stats.Value
end
SaveDataStore:SetAsync(player.UserId,SaveData)
end)
if not success then
return errormsg
end
--- wait(6)
end
Players.PlayerAdded:Connect(function(player)
local Stats = Instance.new("Folder")
Stats.Name = "leaderstats"
Stats.Parent = player
local Stage = Instance.new("StringValue")
Stage.Name = "Stage"
Stage.Parent = Stats
Stage.Value = 1
local Data = SaveDataStore:GetAsync(player.UserId)
if Data then
--- wait(6)
print(Data.Stage)
for i,stats in pairs(Stats:GetChildren()) do
stats.Value = Data[stats.Name]
end
else
print(player.Name .. " has no data.")
end
player.CharacterAdded:Connect(function(character)
local Humanoid = character:WaitForChild("Humanoid")
local Torso = character:WaitForChild("HumanoidRootPart")
wait()
if Torso and Humanoid then
if Stage.Value ~= 0 then
local StagePart = workspace.Stages:FindFirstChild(Stage.Value)
Torso.CFrame = StagePart.CFrame + Vector3.new(0,1,0)
end
end
end)
end)
Players.PlayerRemoving:Connect(function(player)
local errormsg = SavePlayerData(player)
--- wait(6)
if errormsg then
warn(errormsg)
end
end)
game:BindToClose(function()
for i,player in pairs(Players:GetPlayers()) do
local errormsg = SavePlayerData(player)
--- wait(6)
if errormsg then
warn(errormsg)
end
end
wait(2)
end)
You don’t have to modify your functions or adding wait(6) inside of them, just add wait(6) where your code can call DataStore requests too often, for example:
-- This code is poop, don't even try to adapt it to your system
-- It's just an example
local Bool = true -- Using a boolean to yield
Event:Connect(function() -- DataStore requests can be called too often in this event
if Bool then
Bool = false
SaveDataFunction()
Bool = true
else
wait(6)
SaveDataFunction()
Bool = true
end
end
You should check these posts which helped me when I had a similar problem.