Hello, I followed this YouTube tutorial by Tech with Mike on how to save and load multiple sets of data with Data Store. The script works perfectly, although I found one small (BIG) issue: Adding or removing values from the script results in complete data loss. How would I fix/prevent this??
Here is my full script:
local DSS = game:GetService("DataStoreService")
local playerData = DSS:GetDataStore("PlayerData")
local function onPlayerJoin(player)
-- Levels \/
local leaderstats = Instance.new("Folder",player)
leaderstats.Name = "leaderstats"
local level = Instance.new("NumberValue",leaderstats)
level.Name = "Level"
level.Value = 1
local xp = Instance.new("NumberValue",player)
xp.Name = "xp"
xp.Value = 0
local requiredXp = Instance.new("NumberValue",player)
requiredXp.Name = "requiredXp"
requiredXp.Value = 250
-- Levels /\
--
-- Currency \/
local gold = Instance.new("NumberValue",player)
gold.Name = "gold"
gold.Value = 100
local gems = Instance.new("NumberValue",player)
gems.Name = "gems"
gems.Value = 50
-- Currency /\
--
-- Hidden player stats \/
local damage = Instance.new("NumberValue",player)
damage.Name = "damage"
damage.Value = 0
local kills = Instance.new("NumberValue",player)
kills.Name = "kills"
kills.Value = 0
local dungeonsCompleted = Instance.new("NumberValue",player)
dungeonsCompleted.Name = "dungeonsCompleted"
dungeonsCompleted.Value = 0
-- Hidden player stats /\
--
-- Skill Points \/
local pointsToSpend = Instance.new("NumberValue",player)
pointsToSpend.Name = "pointsToSpend"
pointsToSpend.Value = 2
local swordPoints = Instance.new("NumberValue",player)
swordPoints.Name = "swordPoints"
swordPoints.Value = 0
local aspectPoints = Instance.new("NumberValue",player)
aspectPoints.Name = "aspectPoints"
aspectPoints.Value = 0
local healthPoints = Instance.new("NumberValue",player)
healthPoints.Name = "healthPoints"
healthPoints.Value = 0
-- Skill Points /\
-- Holdables \/
-- Holdables /\
local playerUserId = "Player_"..player.UserId
local data = playerData:GetAsync(playerUserId)
if data then
level.Value = data["Level"]
xp.Value = data["xp"]
requiredXp.Value = data["requiredXp"]
gold.Value = data["gold"]
gems.Value = data["gems"]
damage.Value = data["damage"]
kills.Value = data["kills"]
dungeonsCompleted.Value = data["dungeonsCompleted"]
pointsToSpend.Value = data["pointsToSpend"]
swordPoints.Value = data["swordPoints"]
aspectPoints.Value = data["aspectPoints"]
healthPoints.Value = data["healthPoints"]
else
level.Value = 1
xp.Value = 0
requiredXp.Value = 250
gold.Value = 100
gems.Value = 50
damage.Value = 0
kills.Value = 0
dungeonsCompleted.Value = 0
pointsToSpend.Value = 2
swordPoints.Value = 0
aspectPoints.Value = 0
healthPoints.Value = 0
end
-- Level Up and XP \/
xp.Changed:Connect(function()
if xp.Value >= requiredXp.Value then
player.Character:WaitForChild("Humanoid").Health = player.Character:WaitForChild("Humanoid").MaxHealth
xp.Value -= requiredXp.Value
level.Value += 1
requiredXp.Value *= 1.10
pointsToSpend.Value += 2
local levelUpSFX = game.ReplicatedStorage.Sounds.Player.LevelUpSound:Clone()
levelUpSFX.Parent = player.Character
levelUpSFX:Play()
levelUpSFX.Ended:Wait()
levelUpSFX:Destroy()
end
end)
-- Level Up & XP /\
end
local function create_table(player)
local player_stats = {}
for _,stat in pairs(player:GetDescendants()) do
if stat:IsA("NumberValue") or stat:IsA("IntValue") then
player_stats[stat.Name] = stat.Value
end
end
return player_stats
end
local function onPlayerExit(player)
local player_stats = create_table(player)
local success, err = pcall(function()
local playerUserId = "Player_"..player.UserId
playerData:SetAsync(playerUserId, player_stats)
end)
if not success then
warn("Could not save data", err)
end
end
game.Players.PlayerAdded:Connect(onPlayerJoin)
game.Players.PlayerRemoving:Connect(onPlayerExit)
Any and all help is appreciated, thank you!
EDIT: It prints this error
value of type nil cannot be converted to a number
and it links to the new value under the “GetAsync - if data then” section.
i.e. new.Value = data[“new”]