Int Value Isn't saving at all!

Hello,
I have been on the dev forum for the past few days asking about data saving int values. Just when I thought it worked, I ran into a problem. Before, it was saving perfectly. Now, it won’t save at all. Any help would be appreciated.
The data saving script:

local players = game:GetService("Players")
local datastores = game:GetService("DataStoreService")
local datastore = datastores:GetDataStore("DataStore")

local toolName = "10mm" 
local valueName = "maxammo" 
local value2name = 'ammo'
local playerToolValues = {}
playerToolValues2 = {}
local function onPlayerAdded(player)
	local function onCharacterAdded(character)
		local backpack = player:WaitForChild("Backpack")
		local tool = backpack:WaitForChild(toolName)
		local value = tool:WaitForChild(valueName)
		local value2 = tool:WaitForChild(value2name)
		playerToolValues2[player] = value2
		playerToolValues[player] = value
	end

	player.CharacterAdded:Connect(onCharacterAdded)

	local character = player.Character or player.CharacterAdded:Wait()
	local backpack = player:WaitForChild("Backpack")
	local tool = backpack:WaitForChild(toolName)
	local value = tool:WaitForChild(valueName)
	playerToolValues[player] = value
	local value2 = tool:WaitForChild(value2name)
	playerToolValues2[player] = value2name
	local success, result = pcall(function()
		return datastore:GetAsync("Tool_"..player.UserId)
	end)
	local success2, result2 = pcall(function()
		return datastore:GetAsync("Tool_"..player.UserId)
	end)

	if success then
		if result then
			value.Value = result
		end
	else
		warn(result)
	end
	if success2 then
		if result2 then
			value2.Value = result2
		end
	end
end
local function onPlayerRemoving(player)
	local value = playerToolValues[player]
	playerToolValues[player] = nil
	local value2 = playerToolValues2[player]
	playerToolValues2 = nil
	local success, result = pcall(function()
		return datastore:SetAsync("Tool_"..player.UserId, value.Value)
	end)
	local success2, result2 = pcall(function()
		return datastore:SetAsync("Tool_"..player.UserId, value2.Value)
	end)
	if success then
		if result then
			print(result)
		end
	else
		warn(result)
	end
	if success2 then
		if result2 then
			print(result2)
		end
	end
end

players.PlayerAdded:Connect(onPlayerAdded)
players.PlayerRemoving:Connect(onPlayerRemoving)

game:BindToClose(function()
for _, player in ipairs(players:GetPlayers()) do
		local value = playerToolValues[player]
		playerToolValues[player] = nil
		local value2 = playerToolValues2[player]
		playerToolValues2 = nil
		local success, result = pcall(function()
			return datastore:SetAsync("Player_"..player.UserId, value.Value)
		end)
		local success2, result2 = pcall(function()
			return datastore:SetAsync("Player_"..player.UserId, value2.Value)
		end)
		if success then
			print(result)
		else
			warn(result)
		end
		if success2 then
			print(result2)
		else
			warn(result2)
		end
	end
end)

Script changing the int value (Server Script as well):

local tool = script.Parent
local clipsize = tool.ammo.Value

tool.Ammo.OnServerEvent:Connect(function(player)
print("Yes!")
if tool.maxammo.Value - (clipsize - tool.ammo.Value) >= 0 then
		print("yes")
		tool.maxammo.Value = tool.maxammo.Value - (clipsize - tool.ammo.Value)	
		tool.ammo.Value = clipsize
		player.PlayerGui.ScreenGui.Ammo.TextLabel.Text = 'Ammo: ' .. tostring(tool.ammo.Value) .. ' / ' .. tostring(tool.maxammo.Value)
	else
		tool.ammo.Value = tool.ammo.Value + tool.maxammo.Value
		tool.maxammo.Value = 0
        print('no')
		player.PlayerGui.ScreenGui.Ammo.TextLabel.Text = 'Ammo: ' .. tostring(tool.ammo.Value) .. ' / ' .. tostring(tool.maxammo.Value)
	end
	print("yes")
end)

tool.Shoo.OnServerEvent:Connect(function(player)
	tool.ammo.Value = tool.ammo.Value - 1

	player.PlayerGui.ScreenGui.Ammo.TextLabel.Text = 'Ammo: ' .. tostring(tool.ammo.Value) .. ' / ' .. tostring(tool.maxammo.Value)

end)

tool.AmmoPickup.OnServerEvent:Connect(function(player)
	tool.maxammo.Value = tool.maxammo.Value + 10
	print(tool.maxammo.Value)
	player.PlayerGui.ScreenGui.Ammo.TextLabel.Text = 'Ammo: ' .. tostring(tool.ammo.Value) .. ' / ' .. tostring(tool.maxammo.Value)
end)

I tried fixing it by realizing playerToolValues2 didnt have the [player], but even that didn’t fix it.

Use UpdateAsync instead of SetAsync, and remove the return on the pcall to get and to set data. When getting the value use DS:GetAsync(key) or 0.

I am confused on what you mean by use DS:GetAsync(key). What is the key part? What am I supposed to replace key with, and where?

Datastores work like dictionaries, here’s an example of a dictionary:

local dict = {
   key_1 = "value_1",
   key_2 = "value_2"
}

As you can tell from this example, the key’s are the things on the left, and the values on the right - you can save values into specific keys, for example:

DataStore:SetAsync("whatever key you want, probably including player id", "whatever value you want, this also can include numbers etc.")

Now if you were to do:

DataStore:GetAsync("<the key you set>")

You’d get the value you set

(Side note: You should use these functions in pcall cause they can fail sometimes and give errors you can’t evade, which can stop a script from running further.)

So on player removing i’d do the set async part, and on the player added i’d do get async?

Exactly right, Set is for setting/saving, Get is for getting the data

(fyi: you can’t save arrays/dictionaries (tables) in a single key)

I am super confused on what I should be doing right now, people keep telling me different things and when I try them they don’t work, how exactly am I supposed to get the value in the tool? You just made a dictionary but didn’t say anything about actually getting the value.

I pretty clearly showed how you can save or get data

I understand that, but the value is in the tool, how do I get the value from the tool?

get the IntValue instance, and get the value of it by reading the .Value property of it

1 Like

I am unfamiliar with values and such, and I really have no idea what you mean.

here you can find the api reference for IntValue instances, further I’d recommend you read through basic general api reference here as it seems you’re not too familiar with LUAU programming

For some reason the script isn’t letting me get any of the keys I set. On get async and both. Also, I am still confused on how to get the value on the tool, you keep saying to get a instance but that isn’t helping me.

local players = game:GetService("Players")
local datastores = game:GetService("DataStoreService")
local datastore = datastores:GetDataStore("DataStore")

local toolName = "Tool" --Change to name of tool.
local valueName = "Value" --Change to name of value.
local valueName2 = "Value2" --Change to name of value.

local playerToolValues = {} --Cache.

local function onPlayerAdded(player)
	local function onCharacterAdded(character)
		local backpack = player:WaitForChild("Backpack")
		local tool = backpack:WaitForChild(toolName)
		local value = tool:WaitForChild(valueName)
		local value2 = tool:WaitForChild(valueName2)
		
		playerToolValues[player] = value
	end

	player.CharacterAdded:Connect(onCharacterAdded)

	local character = player.Character or player.CharacterAdded:Wait()
	local backpack = player:WaitForChild("Backpack")
	local tool = backpack:WaitForChild(toolName)
	local value = tool:WaitForChild(valueName)
	local value2 = tool:WaitForChild(valueName2)
	playerToolValues[player] = {value, value2}

	local success, result = pcall(function()
		return datastore:GetAsync("Tool_"..player.UserId)
	end)

	if success then
		if result then
			value.Value = result[1]
			value2.Value = result[2]
		end
	else
		warn(result)
	end
end

local function onPlayerRemoving(player)
	local values = playerToolValues[player]
	playerToolValues[player] = nil

	local success, result = pcall(function()
		return datastore:SetAsync("Tool_"..player.UserId, {values[1].Value, values[2].Value})
	end)

	if success then
		if result then
			print(result)
		end
	else
		warn(result)
	end
end

players.PlayerAdded:Connect(onPlayerAdded)
players.PlayerRemoving:Connect(onPlayerRemoving)

Posting here too.

Ran into the error on line 36,

 ServerScriptService.DataStores.AmmoHandler:36: attempt to index number with number 
if type(result) == "table" then
	value.Value = result[1]
	value2.Value = result[2]
end

Ah, the side effects of changing how data is stored, replace the middle two lines with these four.

Play tested in game, and even looked for errors in output and studio, doesn’t save and doesn’t print any errors.

Remember to change the names at the top of the script.

did do that, changed the lines, changed the names and stuff, still not working for me for some reason :confused: