You shouldnt do this as it will cause dataloss because theres too many SetAsync requests
I’ll tell you what to do. U need a Loop that waits 1 minute and everytime a Minute is passed. Loop trough all Players and Save their Data, U also want a longer wait time since u don’t want to throttle your DataStore
You can’t do this, saving that much values from all players at the same time is going to make it throttle
How much u Save data depends on the Amount of Players are in the game so thats not a problem
Also i meant saving data for each player after each other not at the same time
How could I fix that? And why do too many SetAsync requests cause dataloss? I also don’t think that I’m using too many Async requests.
Doing this can cause data loss because of too many Async requests.
They cause data loss because every time you send a request, ROBLOX’s API has to process that request and execute what you want it to do. If you send too many requests, that is too many requests for ROBLOX’s API to handle which will cause it to throttle, and if you send even more, it will stop listening to your requests altogether, meaning no data will be saved at all.
I’d recommend switching to Datastore2, as @BindStep suggested.
Why do you even want it to auto save every minute?
Based off of that, it should be plenty, and I’m perfectly fine…
I need to save player WalkSpeed and JumpPower, although that can’t be done when PlayerRemoving because their Humanoid doesn’t exist anymore, so saving it prior to that is the solution.
One way would be to use some sort of infinite loop,
while true do
-- loop through all players, saving all of their data individually
for _, player in ipairs(game:GetService("Players"):GetPlayers()) do
-- save data
wait(5) -- an interval between saving data, to prevent throttling requests
end
wait(60)
end
Try having a PropertyChangedSignal event and store the New Value somewhere. When the player leaves use that Value when Saving
You shouldn’t really worry about data loss, it’s enough time to not throttle.
game.Players.PlayerAdded:Connect(function()
coroutine.wrap(function()
while true do
wait(60)
-- Save Data
end
end)
end)
Ok, so this is what i came up with, although it says that it was unable to get PlayerUserId:
local ServerStorage = game:GetService("ServerStorage")
local DataStoreService = game:GetService("DataStoreService")
local myDataStore = DataStoreService:GetDataStore("myDataStore")
local AUTOSAVE_INTERVAL = 60
local VIPid = 9456079
game.Players.PlayerAdded:Connect(function(player)
local character = player.Character
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local Points = Instance.new("IntValue")
Points.Name = "Points"
Points.Parent = leaderstats
local Wins = Instance.new("IntValue")
Wins.Name = "Wins"
Wins.Parent = leaderstats
local Activations = Instance.new("IntValue")
Activations.Name = "Activations"
Activations.Parent = leaderstats
local Deaths = Instance.new("IntValue")
Deaths.Name = "Deaths"
Deaths.Parent = leaderstats
local Upgrades = Instance.new("Folder")
Upgrades.Name = "Upgrades"
Upgrades.Parent = player
local SpeedLevel = Instance.new("IntValue")
SpeedLevel.Name = "SpeedLevel"
SpeedLevel.Parent = Upgrades
local JumpLevel = Instance.new("IntValue")
JumpLevel.Name = "JumpLevel"
JumpLevel.Parent = Upgrades
local maxSpeed = Instance.new("IntValue")
maxSpeed.Name = "maxSpeed"
maxSpeed.Parent = player
local maxJump = Instance.new("IntValue")
maxJump.Name = "maxJump"
maxJump.Parent = player
local CurrentSpeed = Instance.new("IntValue")
CurrentSpeed.Name = "CurrentSpeed"
CurrentSpeed.Parent = player
local CurrentJump = Instance.new("IntValue")
CurrentJump.Name = "CurrentJump"
CurrentJump.Parent = player
local Multiplier = Instance.new("NumberValue")
Multiplier.Name = "Multiplier"
Multiplier.Parent = player
if game:GetService("MarketplaceService"):UserOwnsGamePassAsync(player.UserId, VIPid) then
Multiplier.Value = 1.5
else
Multiplier.Value = 1
end
-->> Data: Begining
local playerUserId = "Player_"..player.UserId
-->>Data: Load Data
local data
local success, errormessage = pcall(function()
data = myDataStore:GetAsync(playerUserId)
end)
if success then
if data then
Points.Value = data.Points
Wins.Value = data.Wins
Activations.Value = data.Activations
Deaths.Value = data.Deaths
SpeedLevel.Value = data.SpeedLevel
JumpLevel.Value = data.JumpLevel
maxSpeed.Value = data.maxSpeed
maxJump.Value = data.maxJump
--CurrentSpeed = data.CurrentSpeed
--CurrentJump = data.CurrentJump
Multiplier = data.Multiplier
end
end
end)
-->> Data: Saving Stats
local function saveData(player)
local playerUserId = "Player_"..player.UserId
local data = {
Points = player.leaderstats.Points.Value;
Wins = player.leaderstats.Wins.Value;
Activations = player.leaderstats.Activations.Value;
Deaths = player.leaderstats.Deaths.Value;
SpeedLevel = player.Upgrades.SpeedLevel.Value;
JumpLevel = player.Upgrades.JumpLevel.Value;
maxSpeed = player.maxSpeed.Value;
maxJump = player.maxJump.Value;
--CurrentSpeed = player.Character:FindFirstChild("Humanoid").WalkSpeed;
--CurrentJump = player.Character:FindFirstChild("Humanoid").JumpPower;
Multiplier = player.Multiplier.Value;
}
local success, errormessage = pcall(function()
myDataStore:SetAsync(playerUserId, data)
end)
if success then
print("Data succefully saved!")
else
print("Data saving error")
warn(errormessage)
end
end
game.Players.PlayerRemoving:Connect(saveData)
while true do
for _, player in ipairs(game:GetService("Players"):GetPlayers()) do
saveData()
wait(5)
end
wait(60)
end
Thank you for your comment… This is my first ever “Heavy game” and this does not encourage. I have been scripting almost everyday for the past year now and am still learning. I know all the basics and the problem I have doesn’t happen to be basic. I just have a problem because rn my script doesn’t get PlayerUserId, whereas it did. Instead of making me feel bad for myself, help.
just use that function saveData in a loop;
-- you already defined local function saveData in your script
local Players = game:GetService("Players")
while true do
for _, player in ipairs(Players:GetPlayers()) do
saveData(player)
wait(5) -- a delay between saving data for every player
end
wait(60) -- delay between each time the code in the while loop is to run
end
Your stat save script should be a function in itself and not just hardcoded into the PlayerAdded() function. This will help you in the long run when your scripts are pushing the hundreds or even thousands of lines and readability & comprehensiveness becomes a necessity.
Below is something similar that I use for DataStores:
local save_interval = 120 --roblox limits it to every 2 minutes so we'll roll with this
function SaveFunction(PLR)
coroutine.wrap(function() --wrapping it in a coroutine will allow the rest of the script to run after this is called
while true do
wait(save_interval)
-- do save logic here
end
end)()
end)
If you’re trying to save a humanoid’s walkspeed, you can simply have an IntValue inside of the player called “Walkspeed” and set that to the Humanoid’s walkspeed whenever it changes. Then, save that value on PlayerRemoving.
How tf did I not think abt this before… I had made a IntValue but not saving speed whenever it is changed… Thank you.