Saving A IntValue

Hello,
I have a intvalue in a tool that serves at the max ammo for a gun. I am trying to data save its value, then load it. I made this script, but it is not working and doesn’t print any errors. Any help would be appreciated! If this helps, the int values value is 30.

Script:

local dataStores = game:GetService("DataStoreService")
local dataStore = dataStores:GetDataStore("DataStore")
local players = game:GetService("Players")

players.PlayerAdded:Connect(function(player)


	local data
	local success, result = pcall(function()
		data = dataStore:GetAsync("Player_"..player.UserId)
	end)

	if success then
		if data then
			if player.Backpack:FindFirstChild("A.S.Q - 70") then
				player.Backpack:FindFirstChild("A.S.Q - 70"):FindFirstChild("maxammo").Value = data
			end
			print(result)
			
		else
			print(result)
		end
	else
		warn(result)
	end
end)

players.PlayerRemoving:Connect(function(player)	
	local success, result = pcall(function()
		dataStore:SetAsync("Player_"..player.UserId, player.Backpack:FindFirstChild("A.S.Q - 70"):FindFirstChild("maxammo"))
	end)

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

game:BindToClose(function()
	for _, player in ipairs(players:GetPlayers()) do
		local success, result = pcall(function()
			dataStore:SetAsync("Player_"..player.UserId, player.Backpack:FindFirstChild("A.S.Q - 70"):FindFirstChild("maxammo"))
		end)

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

A few things… the pcall should look like this

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

The if success check should look like…

	if success then
data = result
		if data then
			if player.Backpack:FindFirstChild("A.S.Q - 70") then
				player.Backpack:FindFirstChild("A.S.Q - 70"):FindFirstChild("maxammo").Value = data
			end
			print(result)
			
		else
			print(result)
		end
	else
		warn(result)
	end

Then farther down in code you have another pcall, where you are printing the result on success, but not returning anything from the :SetAsync, so try it as…

	local success, result = pcall(function()
		return dataStore:SetAsync("Player_"..player.UserId, player.Backpack:FindFirstChild("A.S.Q - 70"):FindFirstChild("maxammo"))
	end)

if you are only checking to see if a pcall fails or succeeds you don’t have to return a ‘result’ from inside the pcall.
However, if you are wanting to print out a successful result, or you are using the result as some sort of data or instance, then you need to make sure you have a return from within the pcall returning the result you are wanting to use.

Here’s an example script I just wrote which achieves what you’re trying to achieve, I tested it and it was able to save/load a tool’s IntValue’s value of 100.

This script will be able to save/load a single ValueBase instance inside a tool which stores one of the available primitive value types (string, number, boolean).

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 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)
		
		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 success, result = pcall(function()
		return datastore:GetAsync("Tool_"..player.UserId)
	end)
	
	if success then
		if result then
			value.Value = result
		end
	else
		warn(result)
	end
end

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

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

image

instead of defining a whole function to pcall, the statement can be simplified.

local s,r = pcall(datastore.GetAsync,datastore,"Player_"..player.UserId)

s will be whether the statement executes correctly. If s is false, then R will represent the error. If s is true, then R will represent the result.

Same thing with SetAsync

local s,r = pcall(datastore.SetAsync,datastore,"Player_"..player.UserId,player.Backpack:FindFirstChild("A.S.Q - 70"):FindFirstChild("maxammo")

After testing this in game, and in studio, it doesn’t work, it just goes back to the default value of 30. Unsure why it doesn’t work.

The script worked fine when I tested. I’ll provide a model file so you can see exactly where you might have gone wrong.

repro.rbxm (1.9 KB)

Just a tool instance, a value instance inside that tool instance and the script.

Tested again with a value of 1,000.

Hmmm, even using this file, and a intvalue, my gun’s max ammo doesn’t save. I don’t know why, but I could send my guns local script and see if something could possibly mess with it?

Its because here you are saving the instance, not the value:

dataStore:SetAsync("Player_"..player.UserId, player.Backpack:FindFirstChild("A.S.Q - 70"):FindFirstChild("maxammo"))

Save the value of it instead:

dataStore:SetAsync("Player_"..player.UserId, player.Backpack:FindFirstChild("A.S.Q - 70"):FindFirstChild("maxammo").Value)
1 Like

Sure, send me the gun’s model file.

Ill try that after I send forummer the gun file.

gun.rbxm (55.6 KB)

Okay, so the ammo’s value is being changed by the client, which means when you leave and rejoin the gun’s ammo is still 30 (changes made by the client don’t replicate to the server). You need to change the gun’s ammo on the server via a RemoteEvent.

So, I am confused, what lines do I need to change?

I made it fire a event and have a server script recieve it, but on line 3 it says lua ServerScriptService.DataStores.Script:3: attempt to index nil with 'maxammo'

Script:

 game.ReplicatedStorage.Ammo.OnServerEvent:Connect(function(player, clipsize)
local tool = player:WaitForChild("Backpack"):FindFirstChild("Rifle")
	if tool.maxammo.Value - (clipsize - tool.ammo.Value) >= 0 then
		tool.maxammo.Value = tool.maxammo.Value - (clipsize - tool.ammo.Value)
		tool.ammo.Value = clipsize
	else
		tool.ammo.Value = tool.ammo.Value + tool.maxammo.Value
	end
end)


Adding onto this, I changed it so that the script is in the tool, but I ran into a new error of Players.GrumpyCools.Backpack.Rifle.Script:4: attempt to perform arithmetic (sub) on Instance and number

Script:

local tool = script.Parent
tool.Ammo.OnServerEvent:Connect(function(player, clipsize)

	if tool.maxammo.Value - (clipsize - tool.ammo.Value) >= 0 then
		tool.maxammo.Value = tool.maxammo.Value - (clipsize - tool.ammo.Value)
		tool.ammo.Value = clipsize
	else
		tool.ammo.Value = tool.ammo.Value + tool.maxammo.Value
	end
end)


That means “clipsize” is a reference to an instance.

I have since fixed the problem, but ran into a brand new one. The values no longer save!

Yesterday it would save fine, now it won’t save at all, and on my new post people keep telling me different things that I don’t understand.

1 Like