i wanted to make my datastore save to a table, ive done it before this exact way but when there is no data it shows “attempt to index nil with money” and i just want it to save and load data and if you have none, it sets it to 750
local Players = game:GetService("Players")
local DataStore = game:GetService("DataStoreService"):GetDataStore("Player_data")
Players.PlayerAdded:Connect(function(Player)
local leaderstats = Instance.new("Folder", Player)
leaderstats.Name = "leaderstats"
local Money = Instance.new("IntValue", leaderstats)
Money.Name = "Money"
local success, Data = pcall(function()
return DataStore:GetAsync(Player.UserId)
end)
if not Data.Money then
Money.Value = 750
else
Money.Value = Data.Money
end
end)
Players.PlayerRemoving:Connect(function(Player)
DataStore:SetAsync(Player.UserId,{Money = Player.leaderstats.Money.Value})
end)
game:BindToClose(function()
for _, Player in pairs(Players:GetPlayers()) do
DataStore:SetAsync(Player.UserId, {Money = Player.leaderstats.Money.Value})
end
end)
You could try doing this. Not sure if it’ll make a difference though.
local Players = game:GetService("Players")
local DataStore = game:GetService("DataStoreService"):GetDataStore("Player_data")
Players.PlayerAdded:Connect(function(Player)
local leaderstats = Instance.new("Folder", Player)
leaderstats.Name = "leaderstats"
local Money = Instance.new("IntValue", leaderstats)
Money.Name = "Money"
local Data
local success, err = pcall(function()
data = DataStore:GetAsync(Player.UserId)
end)
if not success then print(err) end
if not Data.Money then
Money.Value = 750
else
Money.Value = Data.Money
end
end)
Players.PlayerRemoving:Connect(function(Player)
local s, e = pcall(function()
DataStore:SetAsync(Player.UserId,{Money = Player.leaderstats.Money.Value})
end)
if not s then print(e) end
end)
game:BindToClose(function()
for _, Player in pairs(Players:GetPlayers()) do
local s, e = pcall(function()
DataStore:SetAsync(Player.UserId, {Money = Player.leaderstats.Money.Value})
end)
if not s then print(e) end
end
end)
I dont recommend you using Data Stores. If the server crashes then all of your data is gone. and you have to script extra for that. Use profile service its easier and more simple to understand.
You get the error because you’re checking if Data.Money exists and not if Data exists.
Change your if statement to if not Data then.
The errors occurs because you can’t check for .Money if Data doesn’t exist.
if not Data then
Money.Value = 750
else
Money.Value = Data.Money
end
local Players = game:GetService("Players")
local DataStore = game:GetService("DataStoreService"):GetDataStore("Player_data")
local function GetPlayerData(player: Player)
local Success, Data = pcall(function()
DataStore:GetAsync(player.UserId)
end)
return Data
end
local function SavePlayerData(player: Player)
local leaderstats = player:FindFirstChild("leaderstats")
local Success, Error = pcall(function()
-- You should use UpdateAsync over SetAsync
DataStore:UpdateAsync(player.UserId, function()
return {Money = leaderstats.Money.Value}
end)
end)
if not Success then
error(Error)
end
end
Players.PlayerAdded:Connect(function(Player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = Player
-- Don't set the parent with the Instance.new() method
-- It is considered bad practice to do so and is slower than setting the parent on a separate line
local Money = Instance.new("IntValue")
Money.Name = "Money"
Money.Parent = leaderstats
local Data = GetPlayerData(Player)
if not Data then
Money.Value = 750
else
Money.Value = Data.Money
end
end)
Players.PlayerRemoving:Connect(function(Player)
SavePlayerData(Player)
end)
You don’t want to be using the WaitForChild method on the server unless you’re referencing leaderstats from another script and have to wait for them to be created by the script that does. Your suggestion doesn’t make much sense at all as it doesn’t have any relevance to the error message.
local Players = game:GetService("Players")
local DataStore = game:GetService("DataStoreService"):GetDataStore("Player_data")
local DataTemplate = {
["Money"] = 750
}
local DataCache = {}
Players.PlayerAdded:Connect(function(Player)
local leaderstats = Instance.new("Folder", Player)
leaderstats.Name = "leaderstats"
local Money = Instance.new("IntValue", leaderstats)
Money.Name = "Money"
local success, Data = pcall(function()
return DataStore:GetAsync(Player.UserId) or DataTemplate
end)
DataCache[Player] = Data
if success then
Money.Value = Data.Money
end
end)
Players.PlayerRemoving:Connect(function(Player)
DataStore:SetAsync(Player.UserId, DataCache[Player])
DataCache[Player] = nil
end)
game:BindToClose(function()
for _, Player in pairs(Players:GetPlayers()) do
DataStore:SetAsync(Player.UserId, DataCache[Player])
end
end)
To be brutally honest. Data stores are trash. You need to litteraly script every single thing, For example if the server crashes all of the player’s data is lost, You have to make it so that if the server crashes Your data doesnt wipe. Profile service does it all for you. Saves data for you. And all of that, + You dont have to use pcalls, And data stores are trash because of that.
There is something entirely wrong with your statement.
ProfileService uses Datastores to save data. So, by your logic that Datastore is trash, ProfileService is also trash. This is clearly wrong.
ProfileService is a module that assists developers to get and save data without the need to consider possible data corruption and data erasure. It allows new and existing developers to save data without having to worry when a server crashes, having an auto-save feature, and others.