These are some of your pcalls. What happens is if the code works then success will exist. If it doesn’t then you will get errormessage and success would be nil.
all you have to do is repeat it until success has a value (meaning it worked)
These are some of your pcalls. What happens is if the code works then success will exist. If it doesn’t then you will get errormessage and success would be nil.
all you have to do is repeat it until success has a value (meaning it worked)
The problem is it is not rare for me and usually only one tool does not save, which causes the problem because it is a new tool.
Is the tool that doesn’t save the tool that the player has equipped at the time?
How do I define success, errorMessage then? do I do local success, errorMessage = Datastore:GetAsync(plr.UserId)
This could be it maybe but I can double check right now.
Which again, is a user error. You’re not storing your data properly. I’m not trying to sound mean or anything but asking “how to make a datastore stronger” isn’t going to help you; your problem is with how you’re saving data.
This is a possibility and should be considered.
You are right I think, but I am not completely sure because I left pretty quick but every other tool except the one I was holding saved. Maybe that is the problem,.
Can all tools in your game be acquired by a shop? If so you can also save the tool to the DataStore on purchase, not when you’re leaving the game because it may be unreliable.
No not all some are accquired by a click detector for events such as that, but most are in the Shop.
I know your problem, you loop through every tool in their backpack and save it. If they have a tool equipped that tool won’t be in their character, instead it would be a child to their character.
success is automatically assigned to based on the outcome of the pcall.
pcall attempts to run the code within it and will even return success or the errormessage it would have created.
pcall runs once.
It will return success = true when the code works
on failure success = nil and errormessage will have value.
Yes you might be true I am not completely sure but the tool I equipped just got lost for some reason which could be a coincedence. I can test again to be sure.
When tools are equipped they get parented to the character, they get moved back to the players backpack when it’s unequipped. None of his code iterates through the character to try to find an equipped tool to save.
If you need an example on using datastores, this is how I will use :GetAsync()
, and the same can be applied to other datastore functions:
local function load(datastore, player, defaultValue)
local key = tostring(player.UserId)
local s, data
for i=1,5 do
s, data = pcall(datastore.GetAsync, datastore, key)
if s then
if data == nil then
return defaultValue
end
return data
end
end
if player then
player:Kick("Error occured while loading data.")
end
warn("Error occured while loading data. Key: \"" .. key .. "\"")
end
That is wrong because I tried it again, and another tool I equipped was lost.
But then I would be kicking players randomly which is bad if they really like the game.
You could try this. I added some code to check if there is a tool in the player’s character, if there is then it saves that too.
local DataStore = game:GetService("DataStoreService"):GetDataStore("MyDataStore")
game.Players.PlayerAdded:Connect(function(plr)
local data
local success, errorMessage = pcall(function()
data = DataStore:GetAsync(plr.UserId)
end)
if data ~= nil then
for _, toolName in pairs(data) do
local tool = game.ReplicatedStorage.ToolsSaved:FindFirstChild(toolName)
if tool then
local newTool = tool:Clone()
newTool.Parent = plr.Backpack
local newTool = tool:Clone()
newTool.Parent = plr.StarterGear
end
end
end
end)
game.Players.PlayerRemoving:Connect(function(plr)
local toolsTable = {}
for _, tool in pairs(plr.Backpack:GetChildren()) do
if game.ReplicatedStorage.ToolsSaved:FindFirstChild(tool.Name) then
table.insert(toolsTable,tool.Name)
end
end
local toolcheck = plr.Character:FindFirstChildWhichIsA("Tool")
if toolcheck then
table.insert(toolsTable,toolcheck.Name)
end
local success, errorMessage = pcall(function()
DataStore:SetAsync(plr.UserId,toolsTable)
end)
end)
game:BindToClose(function()
for _, plr in pairs(game.Players:GetPlayers()) do
local toolsTable = {}
for _, tool in pairs(plr.StarterGear:GetChildren()) do
if game.ReplicatedStorage.ToolsSaved:FindFirstChild(tool.Name) then
table.insert(toolsTable,tool.Name)
end
end
local success, errorMessage = pcall(function()
DataStore:SetAsync(plr.UserId,toolsTable)
end)
end
end)
while wait(10) do --Every 30 seconds loop through all of the players (you can also change this time to anything you want)
for i, plr in pairs (game.Players:GetChildren()) do --loop through all of the players
local toolsTable = {}
for _, tool in pairs(plr.StarterGear:GetChildren()) do
if game.ReplicatedStorage.ToolsSaved:FindFirstChild(tool.Name) then
table.insert(toolsTable,tool.Name)
end
end
local success, errorMessage = pcall(function()
DataStore:SetAsync(plr.UserId,toolsTable)
end)
end
end
It will only kick the player if the script fails to load the data after 5 tries. It won’t randomly kick players.
I’m going to refer you to my other replies in regard to this specific post:
Oh! I never knew that you could repeat datastore attempts!
A new thing learned everyday!