Hi,
I’ve recently released a small community game that involves a lot of data values that I save when a player leaves. The only problem is – the data takes 5 minutes to save. My code looks like this:
function module:SavePlayerData(player, fromShutdown)
local repDataValues = RepDataValues:FindFirstChild(player.UserId .. "_Data")
local servDataValues = SerDataValues:FindFirstChild(player.UserId)
if not (repDataValues and servDataValues) then return end
local playerTable = {}
playerTable["NormalStats"] = getCurrentData(player)
if playerTable["NormalStats"]["TimePlayed"] and player:FindFirstChild("timePlayed") then
playerTable["NormalStats"]["TimePlayed"] = playerTable["NormalStats"]["TimePlayed"]+ (os.time() - player:FindFirstChild("timePlayed").Value)/60
TIME_COUNT:SetAsync(player.Name.."_"..player.UserId, math.floor(playerTable["NormalStats"]["TimePlayed"]))
end
if fromShutdown or game.ServerStorage:FindFirstChild("ShutDown") then print(player) playerTable["NormalStats"]["Combat"] = false end
local inventoryData = game.ReplicatedStorage.Inventories:FindFirstChild(player.UserId .. "_Inventory")
playerTable["Inventory"] = getCurrentInventory(player)
playerTable["Upgrades"] = UpgradesFunction:Invoke(player, true)
playerTable["Subclass"] = SubclassFunction:Invoke(player, true)
spawn(function()
local success = pcall(function()
data:UpdateAsync(player.UserId, function(oldVal)
if not playerTable["Upgrades"] then
playerTable["Upgrades"] = oldVal["Upgrades"]
end
return playerTable or oldVal
end)
end)
if not success then
local c = 0
repeat
c = c + 1
success = pcall(function()
data:UpdateAsync(player.UserId, function(oldVal)
if not playerTable["Upgrades"] then
playerTable["Upgrades"] = oldVal["Upgrades"]
end
return playerTable or oldVal
end)
end)
RUN.Heartbeat:Wait()
until success or c > 30
end
-- clear the connections
if eventTable[player.UserId .. "_InvConnect"] ~= nil then
eventTable[player.UserId .. "_InvConnect"]:Disconnect()
eventTable[player.UserId .. "_InvConnect"] = nil
end
repDataValues:Destroy()
servDataValues:Destroy()
inventoryData:Destroy()
end)
end
Assuming I use this function on Players.PlayerRemoving, why does it seem like the data throttles? I don’t get any warnings in the output whenever a player leaves the game, and it doesn’t seem like I have any yields.
The weird part about this is that if you hop servers quickly, then you get some old data, but if you wait 5 minutes, then it seems like your data saves normally.
I would add an incremental auto-save, but the server size is 50 players and it would be saving a player’s data maybe every 3 seconds.
Something like this:
while true do
for _, player in next, game:GetService"Players":GetPlayers() do
module:UpdatePlayerData(player)
wait(3)
end
wait(3)
end
Only thing I’m worried about is this causing extreme stress on the server due to this many requests… so I’m kind of stumped on what to do here.
One of the things that we did do to solve this problem momentarily was add an “auto-save” every time you complete a quest in the game, which occurs maybe every 20-30 minutes. This isn’t very reliable, though, because not everyone does quests very often, so it can’t be used as a reliable auto-save.
Does anyone know how I can fix this problem? It’s a very weird bug that I’ve never encountered before.