Make sure to use pcall
as it is safer to use and helps prevent crashing. Many people tend to not use it, but it is recomended.
it is hard for me to understand and use the scripts that are mentioned in an article in the developer hub. The thing that I want to save is the file “leaderstats” which inside any player that joins the game, and the values inside the file, “Points” and “XP”
game:BindToClose(function()
for _, player in pairs(game.Players:GetPlayers()) do
local points = player.Points
local success, errorMsg = pcall(function()
pointsDS:SetAsync(plr.UserId, points.Value
end
end)
this script is full of errors just check the script before you tell me to use it, when pasted your script, too many red lines.
red lines = error
and there was 2 unknown globals
Instead of saving data with the bind to close, just add a wait(5)
so that the PlayerRemoving
function can run, saving the player’s data. There’s not much use in saving within the BindToClose()
Putting the data into a table reduces the amount of things to save to just one. So, it saves space, you can save data more often, and there is “less” data to remember.
can you show me the results of the script?
First: Please learn from this script, do NOT past the script.
Second: This script is an adjustment for Nifemiplayz script. It works for me.
I think that if your having a hard time understanding those articles you might have to learn some of the basics of LuaU(the coding language Roblox uses)
I recommend if you wanna learn about saving player data follow this article which teaches about data stores in a way easier to understand and shows some code examples found on the developer wiki and also just following the basic coding tutorials found on the Roblox developer onboarding page
I hope this helps!!!
He posted that assuming you would setup the data store and where the points are saved yourself, that script is just how to save it to a datastore not setup the data store I recommend following the article/pages I linked on my other post. I’ll quote it below
Try this script.
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("DataStoreValues") --Name the DataStore whatever you want
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder", player)
leaderstats.Name = "leaderstats"
local Points = Instance.new('NumberValue', leaderstats)
Points.Name = "Points"
Points.Value = 0
local value1Data = Points
local s, e = pcall(function()
value1Data = DataStore:GetAsync(player.UserId.."-Value1") or 0 --check if they have data, if not it'll be "0"
end)
if s then
Points.Value = value1Data --setting data if its success
else
game:GetService("TestService"):Error(e) --if not success then we error it to the console
end
end)
game.Players.PlayerRemoving:Connect(function(player)
local s, e = pcall(function()
DataStore:SetAsync(player.UserId.."-Value1", player.leaderstats.Points.Value) --setting data
end)
if not s then game:GetService("TestService"):Error(e)
end
end)
Although I would recommend not using an instance based data setup rather backend data setups you can read more about the benefits and how to do it here(this link leads to a Roblox developer article on medium.com and is not one of the Roblox.com sites
local DB = game:GetService("DataStoreService")
local pDB = DB:GetDataStore("Points")
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder", player)
leaderstats.Name = "leaderstats"
local points = Instance.new("IntValue", leaderstats)
points.Name = "Points"
points.Value = 0
local pData
pcall(function()
pData = pDB:GetAsync(player.UserId.."-Points")
end)
if pData then
points.Value = pData
end
while wait(2) do points.Value = points.Value + 1 end
end)
game.Players.PlayerRemoving:Connect(function(player)
pcall(function()
pDB:SetAsync(player.UserId.."-Points", player.leaderstats.Points.Value)
end)
end)
Oh yea, my bad i forgot about that
So anyone can tell me the script that I need to use?
local DataStoreService = game:GetService(“DataStoreService”)
local StatsStore = DataStoreService:GetDataStore(“Game”)
local loaded = {}
game.Players.PlayerAdded:Connect(function(player)
local SystemData = Instance.new("Folder")
SystemData.Name = "leaderstats"
SystemData.Parent = player
local Points = Instance.new("IntValue")
Points .Name = "Points"
Points .Parent = SystemData
Points .Value = 0
local XP = Instance.new("IntValue")
XP.Name = "XP"
XP.Parent = SystemData
XP.Value = 0
local Data = player:WaitForChild("leaderstats")
if player.UserId > 0 and player.Parent then
local DataStats = StatsStore:GetAsync(player.UserId)
if DataStats ~= "Saving Stats" then
if DataStats then
for i, stat in ipairs(Data:GetChildren()) do
local value = DataStats[stat.Name]
if value then
stat.Value = value
end
end
end
loaded[player] = true
end
end
end)
game.Players.PlayerRemoving:connect(function(player)
local Data = player:FindFirstChild(“leaderstats”)
if Data then
if loaded[player] then
local DataStats = {}
for i, stat in ipairs(Data:GetChildren()) do
DataStats[stat.Name] = stat.Value
end
StatsStore:SetAsync(player.UserId, DataStats)
end
end
loaded[player] = nil
end)
Try use this
I tried it, it works, then next time does not work. Next time works, next time does not work, and so it continues.
local statList = {
{Name = “Points”, Type = “IntValue”};
{Name = “XP”, Type = “IntValue”};
}
local Players = game:GetService(“Players”)
local Datastore = game:GetService(“DataStoreService”):GetDataStore(“Stats”)
local function SavePlayer(player)
local dataToSave = {};
for _, stat in pairs(player.leaderstats:GetChildren()) do
dataToSave[stat.Name] = stat.Value
end
local success, err = pcall(function()
Datastore:SetAsync(player.UserId, dataToSave)
end)
if not success then
warn("Error saving data" .. player.Name)
end
end
local function NewStat(statType, statName, statParent)
local new = Instance.new(statType)
new.Name = statName
new.Parent = statParent
return new
end
Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new(“Folder”)
leaderstats.Name = “leaderstats”
leaderstats.Parent = player
for _, statInfo in pairs(statList) do
local success, err = pcall(function()
NewStat(statInfo.Type, statInfo.Name, leaderstats)
end)
if not success then
warn("Error" .. tostring(statInfo.Name) .. ": " .. tostring(err))
end
end
local data; local success, err = pcall(function()
data = Datastore:GetAsync(player.UserId)
end)
if success and data then
for statName, statValue in pairs(data) do
if leaderstats:FindFirstChild(statName) then
leaderstats[statName].Value = statValue
end
end
elseif err then
warn("Error loading data" .. player.Name .. ": " .. tostring(err))
end
end)
Players.PlayerRemoving:Connect(SavePlayer)
game:BindToClose(function()
for _, player in pairs(Players:GetPlayers()) do
SavePlayer(player)
end
end)
Make sure active Roblox studio api service
I made a youtube tutorial on how you can do this. Just follow step by step and it should work. You do have to customize this to get your points and xp value and stuff.
If you have trouble saving BOTH those values, then leave a post and I will help.
I know this has been solved but you could use this.
This will fully work.
local Players = game:GetService("Players") -- Main | Players
local DataStoreService = game:GetService("DataStoreService") -- DataStoreService
local Data = {Points = DataStoreService:GetDataStore("Points"), XP = DataStoreService:GetDataStore("Experience")} -- data
local DebugMode = true -- [Disable/Set to false ] if you don't want to see warn(msg) in output
function Add(Player)
local ldr = Instance.new("Folder")
ldr.Parent = Player
ldr.Name = "leaderstats"
local PointsVal = Instance.new("IntValue")
PointsVal.Parent = ldr
PointsVal.Name = "Points"
PointsVal.Value = Data.Points:GetAsync(tostring(Player.UserId)) or 0 -- at 0, set starter points
local XPval = Instance.new("IntValue")
XPval.Parent = ldr
XPval.Name = "XP"
XPval.Value = Data.XP:GetAsync(tostring(Player.UserId)) or 0 -- at 0, set starter XP
while wait(60) do
Data.Points:SetAsync(tostring(Player.UserId), PointsVal.Value)
Data.XP:SetAsync(tostring(Player.UserId), XPval.Value)
if DebugMode then
warn("Stats have been saved! Player > "..Player.Name.." [AutoSave]") -- Check Output
end
end
end
function Leave(Player)
if DebugMode then
warn("Stats have been saved to "..Player.Name..", they left the game! [AutoSave]") -- Check Output
end
Data.Points:SetAsync(tostring(Player.UserId), Player:WaitForChild("leaderstats"):WaitForChild("Points").Value) -- saving value on leave
Data.XP:SetAsync(tostring(Player.UserId), Player:WaitForChild("leaderstats"):WaitForChild("XP").Value) -- saving value on leave
end
Players.PlayerAdded:Connect(Add)
Players.PlayerRemoving:Connect(Leave)