Why don't I have IntValue saved?

Local:

local remote = game:GetService("ReplicatedStorage"):WaitForChild("Remotes"):WaitForChild("Save")
local ld = game.Players.LocalPlayer:WaitForChild("leaderstats")
local folder = game.Players.LocalPlayer:WaitForChild("Data")

while true do
	wait(5) -- TIME FOR SAVE
	local saveDataTable = {}
	table.insert(saveDataTable, 1, ld.Wins.Value)
	table.insert(saveDataTable, 2, ld.Power.Value)
	table.insert(saveDataTable, 3, folder.PlusPower.Value)
	table.insert(saveDataTable, 4, ld.Mass.Value)
	table.insert(saveDataTable, 6, folder.PlusMass.Value)
	table.insert(saveDataTable, 7, ld.Rebirth.Value)
	remote:FireServer(saveDataTable)
	--print("Autosaved ".. game.Players.LocalPlayer.Name.. "'s Data")
end

Server:

local DataStore = game:GetService("DataStoreService"):GetDataStore("Saves")
local saveRemote = game:GetService("ReplicatedStorage"):WaitForChild("Remotes"):WaitForChild("Save")

game.Players.PlayerAdded:Connect(function(player)
	local ld = Instance.new("Folder", player)
	ld.Name = "leaderstats"
	
	local folder = Instance.new("Folder", player)
	folder.Name = "Data"
	
	local tools = Instance.new("Folder", player)
	tools.Name = "Tools"

	local wins = Instance.new("IntValue", ld)
	wins.Name = "Wins"
	
	local power = Instance.new("IntValue", ld)
	power.Name = "Power"
	
	local plusPower = Instance.new("IntValue", folder)
	plusPower.Name = "PlusPower"
	
	local mass = Instance.new("IntValue", ld)
	mass.Name = "Mass"
	
	local plusMass = Instance.new("IntValue", folder)
	plusMass.Name = "PlusMass"
	
	local rebirth = Instance.new("IntValue", ld)
	rebirth.Name = "Rebirth"
	
	local success, errormag = pcall(function()
		local getData = DataStore:GetAsync(player.UserId)
		for i, v in pairs(getData) do
			if i == 1 then
				wins.Value = getData[i]
			elseif i == 2 then
				power.Value = getData[i]
			elseif i == 3 then
				plusPower.Value = getData[i]
			elseif i == 4 then
				mass.Value = getData[i]
			elseif i == 5 then
				plusMass.Value = getData[i]
			elseif i == 6 then
				rebirth.Value = getData[i]
			end
		end
	end)
	
	if success then
		--print("Successfully loaded ".. player.Name.. "'s data!")
	elseif not success then
		-- FIRST TIME JOINING --
		wins.Value = 0
		power.Value = 0
		plusPower.Value = 1
		mass.Value = 0
		plusMass.Value = 1
		rebirth.Value = 0
		
		local powerTool1 = game:GetService("ReplicatedStorage"):WaitForChild("Tools").Dumbbell1
		powerTool1.Parent = player.Backpack
		
		local massTool1 = game:GetService("ReplicatedStorage"):WaitForChild("Tools").Mass1
		massTool1.Parent = player.Backpack
		
		game:GetService("ReplicatedStorage"):WaitForChild("Settings").currentTool.Value = powerTool1.Name
		--error("Something went wrong while loading the data of ".. player.Name.. ": ".. errormag)
	end
end)

saveRemote.OnServerEvent:Connect(function(player, val)
	DataStore:SetAsync(player.UserId, val)
	--print("Successfully saved ".. player.Name.. "'s data!")
end)

So I have this system working, that is, when I quit the game, everything is saved. BUT!!! Here when I decided to add Rebirth, then when I exit and a new entry into the game it was not saved although the rest of the data is still saved, the error is not written, so the question. Why it is not saved?

P.S. initially rebirth I have on 0, I make it 1, and leave the game. At a new entry, all is saved but rebirths are equal to 0.

1 Like

You aren’t reconciling the table i.e adding in the new entry to getData. Do a google search and you will get the necessary function. Also, you are allowing the client to control which data gets saved which is exploitable and unreliable.

1 Like

can you give me a sample code to fix this, if it’s not too much trouble?

1 Like
local template = {
    [1] = 0,
    [2] = 0,
    [3] = 0,
    [4] = 0,
    [5] = 0,
    [6] = 0
}

local function Reconcile(data)
    for idx, val in template do
        if not data[idx] then data[idx] = val end
    end
end

And add this modified version:

local success, errormag = pcall(function()
	local getData = DataStore:GetAsync(player.UserId) or {}
    Reconcile(getData)

	for i, v in pairs(getData) do
		if i == 1 then
			wins.Value = getData[i]
		elseif i == 2 then
			power.Value = getData[i]
		elseif i == 3 then
			plusPower.Value = getData[i]
		elseif i == 4 then
			mass.Value = getData[i]
		elseif i == 5 then
			plusMass.Value = getData[i]
		elseif i == 6 then
			rebirth.Value = getData[i]
		end
	end
end)

and where should I place the first code?

top of your script

you mean at the top of my entire script. I mean at the top?

Bro anywhere, place it where it can be called from

Okay, thanks for your help. [character limit].

Okay, I did this:

local DataStore = game:GetService("DataStoreService"):GetDataStore("Saves")
local saveRemote = game:GetService("ReplicatedStorage"):WaitForChild("Remotes"):WaitForChild("Save")

game.Players.PlayerAdded:Connect(function(player)
	local ld = Instance.new("Folder", player)
	ld.Name = "leaderstats"
	
	local folder = Instance.new("Folder", player)
	folder.Name = "Data"
	
	local tools = Instance.new("Folder", player)
	tools.Name = "Tools"

	local wins = Instance.new("IntValue", ld)
	wins.Name = "Wins"
	
	local power = Instance.new("IntValue", ld)
	power.Name = "Power"
	
	local plusPower = Instance.new("IntValue", folder)
	plusPower.Name = "PlusPower"
	
	local mass = Instance.new("IntValue", ld)
	mass.Name = "Mass"
	
	local plusMass = Instance.new("IntValue", folder)
	plusMass.Name = "PlusMass"
	
	local rebirth = Instance.new("IntValue", ld)
	rebirth.Name = "Rebirth"
	
	local template = {
		[1] = 0,
		[2] = 0,
		[3] = 0,
		[4] = 0,
		[5] = 0,
		[6] = 0
	}

	local function Reconcile(data)
		for idx, val in template do
			if not data[idx] then data[idx] = val end
		end
	end
	
	local success, errormag = pcall(function()
		local getData = DataStore:GetAsync(player.UserId)
		for i, v in pairs(getData) do
			if i == 1 then
				wins.Value = getData[i]
			elseif i == 2 then
				power.Value = getData[i]
			elseif i == 3 then
				plusPower.Value = getData[i]
			elseif i == 4 then
				mass.Value = getData[i]
			elseif i == 5 then
				plusMass.Value = getData[i]
			elseif i == 6 then
				rebirth.Value = getData[i]
			end
		end
	end)
	
	if success then
		--print("Successfully loaded ".. player.Name.. "'s data!")
	elseif not success then
		-- FIRST TIME JOINING --
		wins.Value = 0
		power.Value = 0
		plusPower.Value = 1
		mass.Value = 0
		plusMass.Value = 1
		rebirth.Value = 0
		
		local powerTool1 = game:GetService("ReplicatedStorage"):WaitForChild("Tools").Dumbbell1
		powerTool1.Parent = player.Backpack
		
		local massTool1 = game:GetService("ReplicatedStorage"):WaitForChild("Tools").Mass1
		massTool1.Parent = player.Backpack
		
		game:GetService("ReplicatedStorage"):WaitForChild("Settings").currentTool.Value = powerTool1.Name
		--error("Something went wrong while loading the data of ".. player.Name.. ": ".. errormag)
	end
end)

saveRemote.OnServerEvent:Connect(function(player, val)
	DataStore:SetAsync(player.UserId, val)
	--print("Successfully saved ".. player.Name.. "'s data!")
end)

but it didn’t help.

This is easily exploitable by exploiters. You should never trust the client, here’s what I usually do when I save data

local datastoreService = game:GetService("DataStoreService")
local datastore = datastoreService:GetDataStore("zeroPoint1")
local data

game.Players.PlayerAdded:Connect(function(player)
	playersFolder = Instance.new("Folder")
	playersFolder.Name = "Players"
	playersFolder.Parent = game.ReplicatedStorage

	playerStats = Instance.new("Folder")
	playerStats.Name = "player_" .. player.UserId
	playerStats.Parent = playersFolder

	key = "playerData_" .. player.UserId

	coins = Instance.new("NumberValue")
	coins.Name = "Coins"
	coins.Value = 0
	coins.Parent = playerStats

	checkpoint = Instance.new("NumberValue")
	checkpoint.Name = "Checkpoint"
	checkpoint.Value = 1
	checkpoint.Parent = playerStats

	local success, errorMessage = pcall(function()
		data = datastore:GetAsync(key)
	end)
	if success and data then
		coins.Value = data[coins]
		checkpoint.Value = data[checkpoint]
		print("Data has been loaded!")
	elseif not data then
		warn(errorMessage)
	end
end)

function saveData(player)
	local dataToSave = {
		dataId = 0;
		coins = coins.Value;
		checkpoint = checkpoint.Value;
		items = {};
	}
	if data then
		datastore:UpdateAsync(key, function(oldData)
			local previousData = oldData or {dataId = 0}
			if previousData.dataId == dataToSave.dataId then
				dataToSave.dataId += 1
				return dataToSave
			else
				return nil
			end
		end)
	else
		datastore:SetAsync(key, dataToSave)
	end
end

game.Players.PlayerRemoving:Connect(function(player)
	saveData(player)
end)

game:BindToClose(function()
	for _, player in ipairs(game.Players:GetChildren()) do
		saveData(player)
	end
end)

You can add a while wait() loop to automatically save the player’s data

You need to call the function y’know?

local success, errormag = pcall(function()
	local getData = DataStore:GetAsync(player.UserId) or {}    
    Reconcile(getData)

	for i, v in pairs(getData) do
		if i == 1 then
			wins.Value = getData[i]
		elseif i == 2 then
			power.Value = getData[i]
		elseif i == 3 then
			plusPower.Value = getData[i]
		elseif i == 4 then
			mass.Value = getData[i]
		elseif i == 5 then
			plusMass.Value = getData[i]
		elseif i == 6 then
			rebirth.Value = getData[i]
		end
	end
end)