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)
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)
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?
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.
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)