So i’m making a datastore save system, everything works correctly but at the moment of saving (player leaves the game), script couldn’t find PlayerGui, where the values i want to save are.
What have i tried?
I made a for i, v in pairs do function inside the player and print v.Name, to see if the playergui really isn’t inside player, and yeah, it doesn’t print PlayerGui, so basically i can’t index this and i’m needing another method
i have put saveData function inside loadData function so i could use the same variable i used loading the data, but it doesn’t work, at the moment of saving that variable is empty
Script:
local sFind = string.find
local tDelay = delay
local tWait = wait
local insert = table.insert
local number = tonumber
local DTS = game:GetService ‘DataStoreService’
local HTP = game:GetService ‘HttpService’
local function loadData(Player:Player)
repeat tWait(2) until Player.PlayerGui:FindFirstChild’Shop’
local PlayerSkins = Player.PlayerGui.Shop.store.Skins.SkinsFrame;
local key = Player.UserId
local success, saved = pcall(function()
return General:GetAsync(key)
end)
if saved then
saved = HTP:JSONDecode(saved)
for i, v in ipairs(PlayerSkins:GetDescendants()) do
if v:IsA’ViewportFrame’ then
if saved[i] then
v:SetAttribute(‘isBought’, saved[i].boughtVal)
v:SetAttribute(‘isEquipped’, saved[i].equippedVal)
end
end
end
end
end
local function saveData(Player:Player)
local PlayerSkins = Player.PlayerGui.Shop.store.Skins.SkinsFrame;
local save = {}
for i, v in ipairs(PlayerSkins:GetDescendants()) do
if v:IsA’ViewportFrame’ then
print(i)
insert(save, {boughtVal = v:GetAttribute’isBought’, equippedVal = v:GetAttribute’isEquipped’})
end
end
local key = Player.UserId
local success, errMsg = pcall(function()
General:SetAsync(key, HTP:JSONEncode(save))
end)
if not success then warn('Failed to save data: '…Player.Name) return end
end
it doesn’t work, i also tried for debugging a for i, v in pairs inside the player and print v.Name, but it doesn’t print PlayerGui, this script runs at player leaving the game cuz is a saveData function using datastoreservice
It’s because the PlayerGui gets destroyed almost instantly when the player leaves the game - it should not be used to gather save data. It is destroyed so fast you have no time to read from it. Use a different source to manage save data, for instance a player inventory module in ServerScriptService - then you can take as long as you need to save data. Just remember to destroy it afterwards.
This would change absolutely nothing apart from causing an Infinite Yield.
You have time to save your data, but not all day. There is no time to start defining too many things, looking for things or stalling. That should all be ready to go before they even started leaving the game. The skins they own can be set to a save list as they buy them. That way there is no, do we save this or not for loop going. It’s all full blast save and get out asap.
The save {} is being defined, the key is being defined, searching for what to save is looping…
All this can be preset.
If everything is too much to do in the moment then you can’t do it this way.
I have 15 skins to save or not save … I could say:
Player.PlayerGui.Shop.store.Skins.SkinsFrame.skin1 ← this is what it is doing even with the PlayerSkins defined.
Player.PlayerGui.Shop.store.Skins.SkinsFrame.skin1
Player.PlayerGui.Shop.store.Skins.SkinsFrame.skin2
Player.PlayerGui.Shop.store.Skins.SkinsFrame.skin3
Player.PlayerGui.Shop.store.Skins.SkinsFrame.skin4 all the way to 15 of them and checking if they are owned.
OR I could have one string.Value that gets updated as I buy skins.
“001001000000000” – I own skin 3 and 6. DatasStore only needs to save one string. I’ll break that down when they log in.
Just little tricks to cut down the data needing to be saved.
Using a bunch of instance values will eventually impact on memory. You also do have a window of time to save player data - this is crucial for things like player character position saving and os.time() - things that would otherwise be innacurate. That is why the leaving event is called PlayerRemoving and it fires when a player is about to leave the game.
These things would otherwise snow under the memory, using things like GetPropertyChangedSignal, etc.