So I took some advice and made some changes, but am facing another problem; the else statement on line 9 is firing. So my question is, am I saving the datastore incorrectly? When a player leaves the game it prints all the saving messages as it should, so im perplexed as to why its not getting anything when a player joins. Any and all help is greatly appreciated! :)
local Data = game:GetService("DataStoreService"):GetDataStore("Data123") game.Players.PlayerAdded:Connect(function(Player) pcall(function() local PlayerData = Data:GetAsync(Player.UserId) if PlayerData then setStats(Player, PlayerData.Stats) setBackpack(Player, PlayerData.Backpack) else defaultStats(Player) game.ReplicatedStorage.Weapons.StarterSword:Clone().Parent = Player:WaitForChild("Backpack") end local CanSave = Instance.new("BoolValue", Player) CanSave.Name = "CanSave" CanSave.Value = true end) end) --Stats Portion function setStats(Player, SavedStats) local Stats = createStats(Player) if SavedStats then print("Got SavedStats") Stats.Level.Value = SavedStats.Level Stats.Exp.Value = SavedStats.Exp Stats.Gold.Value = SavedStats.Gold end end function defaultStats(Player) print("Defaulting stats for " .. Player.Name) local Stats = createStats(Player) Stats.Level.Value = 1 Stats.Exp.Value = 0 Stats.Gold.Value = 25 end function createStats(Player) local Stats = Instance.new("Folder", Player) Stats.Name = "Stats" local Level = Instance.new("IntValue", Stats) Level.Name = "Level" local Exp = Instance.new("IntValue", Stats) Exp.Name = "Exp" local Gold = Instance.new("IntValue", Stats) Gold.Name = "Gold" return Stats end function getStats(Player) local PlayerStats = {} if Player:FindFirstChild("Stats") then for _, Stat in pairs(Player.Stats:GetChildren()) do print("Saving " .. Player.Name .. "'s " .. Stat.Name .. " = " .. Stat.Value) PlayerStats[Stat.Name] = Stat.Value end end return PlayerStats end --Backpack Portion function setBackpack(Player, SavedWeapons) if SavedWeapons then print("Got SavedWeapons") for _, WeaponName in pairs(SavedWeapons) do print("Weapon for loop") local Weapon = game.ReplicatedStorage.Weapons:FindFirstChild(WeaponName) if Weapon then print("Loading " .. Weapon.Name) Weapon:Clone().Parent = Player:WaitForChild("Backpack") Weapon:Clone().Parent = Player:WaitForChild("StarterGear") end end else print("SavedWeapons else fired") end end function getBackpack(Player) local WeaponsTable = {} local EquippedWeapon = getEquippedWeapon(Player) if EquippedWeapon then print("Saving " .. Player.Name .. "'s " .. EquippedWeapon.Name) table.insert(WeaponsTable, EquippedWeapon.Name) end for _, Weapon in pairs(Player.Backpack:GetChildren()) do print("Saving " .. Player.Name .. "'s " .. Weapon.Name) table.insert(WeaponsTable, Weapon.Name) end return WeaponsTable end function getEquippedWeapon(Player) local Character = game.Workspace:FindFirstChild(Player.Name) if Character then for _, Item in pairs(Character:GetChildren()) do if Item:IsA("Tool") then return Item end end end return end game.Players.PlayerRemoving:Connect(function(Player) pcall(function() print("Player Removing") if Player.CanSave then print(Player.Name .. " is saving") local DataDictionary = { Stats = getStats(Player), Backpack = getBackpack(Player) } Data:SetAsync(Player.UserId, DataDictionary) else print(Player.Name .. " can't save") end end) end)
(Assuming you've been testing in studio)
Unless you have the setting labelled Enable Studio Access to API Services
set to true
(can be found in the game settings), the data won't actually save between test sessions. You can turn this setting on (don't recommend if this game is live or planning to go live) or just test on the roblox client itself. Everything you are doing looks right and there is no immediate problem. One thing that I'd like to point out though is your misuse of pcall
.
Your call to pcall
should only wrap the call to the datastore and that's it. It shouldn't include the rest of the logic because that breaks the whole point of protected call. Instead, I would do something like this:
local success , result = pcall(function() return Data:GetAsync(Player.UserId) end) if success then --results would be the data retrieved in this case --normal stuff else --handle error --results would be the error object in this case warn(result) end