Hello its me Inquistor again, and I have a question. My DataStore for my game saves the currency in my game, but sometimes it doesn’t save correctly like sometimes it does not load and sometimes when you leave incorrectly or when you leave and its in between the stages of saving, it does not load. Is there anyway for me to speed up the datastore or make a new datastore?
local function SaveData(plr,t)
if plr and t then
data:SetAsync(plr.UserId,t.Value)
end
end
game.Players.PlayerAdded:Connect(function(plr)
Instance.new("Folder",plr).Name = "leaderstats"
local stat
local function Getleaderstats()
wait(0.1)
if not plr:FindFirstChild("leaderstats") then
wait(1.5)
Getleaderstats()
else
stat = plr:WaitForChild("leaderstats")
return true;
end
end
Getleaderstats()
local function CreateStat(class,name,parent)
local i = Instance.new(class)
i.Name = tostring(name)
i.Parent = parent
return i
end
local money = CreateStat("IntValue","Gold",stat)
wait(0.03)
local SavedLevel = data:GetAsync(plr.UserId)
if SavedLevel then
money.Value = SavedLevel
else
money.Value = 1
wait(0.08)
SaveData(plr,money)
end
end)
game.Players.PlayerRemoving:Connect(function(plr)
if plr:FindFirstChild("leaderstats") and plr.leaderstats:FindFirstChild("Gold") then
SaveData(plr,plr.leaderstats["Gold"])
end
end)
if not game:GetService("RunService"):IsStudio() then
game:BindToClose(function()
for _,plr in pairs(game:GetService("Players")) do
if plr:FindFirstChild("leaderstats") and plr.leaderstats:FindFirstChild("Gold") then
SaveData(plr,plr.leaderstats["Gold"])
end
end
wait(10)
end)
end
---This is the first script, in ServerScriptService then then next is---
```game.Players.PlayerAdded:connect(function(player)
local DataStore = game:GetService("DataStoreService")
local leader = Instance.new("Folder",player)
leader.Name = "leaderstats"
for i,v in pairs(script:GetChildren()) do
local d = DataStore:GetDataStore(v.Name)
local x = Instance.new("NumberValue",leader)
x.Name = v.Name
x.Value = d:GetAsync(player.UserId) or v.Value
end
end)
game.Players.PlayerRemoving:Connect(function(player)
for i,v in pairs(script:GetChildren()) do
print("Getting")
local DataStore = game:GetService("DataStoreService")
local d = DataStore:GetDataStore(v.Name)
d:SetAsync(player.UserId, player.leaderstats[v.Name].Value)
print("Saved")
end
end)
---This is a seperate script in ServerScriptService---
First off if you are the last player in the game you should make a game:BindToClose function that will make it so if the server is ready to shutdown it must execute said code before it can shutdown
like kick every player left in the server and wait 5 seconds before shuting down use this code
local MDT = DTS:GetDataStore("CurrencyDT") -- Change you YOUR datastore name
local PS = game:GetService("Players")
local currencyName = "Currency" -- Change to your currency name
game.Players.PlayerAdded:Connect(function(plr)
local Folder = Instance.new("Folder")
Folder.Name = "leaderstats"
Folder.Parent = plr
local Value = Instance.new("IntValue")
Value.Name = currencyName
Value.Parent = Folder
local ID = currencyName.."-"..plr.UserId
local savedData = nil
pcall(function()
savedData = MDT:GetAsync(ID)
end)
if savedData ~= nil then
Value.Value = savedData
print(plr.Name.."'s data has loaded!")
elseif savedData == nil then
Value.Value = 200
print(plr.Name.." is a new player!")
end
end)
game.Players.PlayerRemoving:Connect(function(plr)
local ID = currencyName.."-"..plr.UserId
MDT:SetAsync(ID, plr.leaderstats[currencyName].Value)
end)
game:BindToClose(function()
for i, player in pairs(game.Players:GetPlayers()) do
if player then
player:Kick("This server is shutting down! Your data should be saved!")
end
end
wait(5)
end)
Studio is infamous for shutting down before the data gets saved, that’s why you have to use a BindToClose function, if you’re also checking if your current game is inside studio you can solve this issue.
See this exampel:
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
game:BindToClose(function()
if RunService:IsStudio() then
for _,Player in ipairs(Players:GetPlayers()) do
local Success,ErrorMessage = pcall(function()
--Your data saving script comes into here
end)
if not Success then
warn("Error: "..ErrorMessage)
end
end
end
end)
I also suggest using a pcall function since saving data can sometimes throw errors.
I don’t know how functions behave, if they do behave like events you’d need to put that script into your BindToClose function as events have the problem of not running if they have have been used mutliple times in one script.
What you’re doing is pretty simple, just use a dictionary to store data.
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local GoldData = DataStoreService:GetDataStore("Gold")
Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local gold = Instance.new("IntValue")
gold.Name = "Gold"
local data = nil
local success, err = pcall(function()
data = GoldData:GetAsync(player.User.."-gold")
end)
if success then — if getting data was successful
if data then — if the player has data then...
gold.Value = data.Gold — looks into the dictionary, and grabs gold’s value
else — there’s no data, must be a new player
gold.Value = 100 — give the player 100 gold when they first join
end
else — getting data wasn’t successful
warn("There was an error whilst grabbing data!")
warn("Error:", err)
end
end)
Players.PlayerRemoving:Connect(function(player)
local gold = player:WaitForChild("leaderstats").Gold
local data = {
Gold = gold.Value — save a key called “Gold” to be referenced later
}
local success, err = pcall(function()
GoldData:UpdateAsync(player.UserId.."-gold", function()
return data — save the data
end)
end)
if not success then
warn("There was an error whilst saving data!")
warn("Error:", err)
end
end)
Also theres a problem with that I already have a different script that names my leaderstats that is named Gold. So how would I refer to that using your script?
since im pretty sure when you hit close in a play-solo you kinda “force shut” the game. I think in real servers the server gets shut down after 2-3 seconds of the last player leaves (which gives the server time to save the data)
I made a DataStore2 and it works. But how would I add my currency that kills players for money inside of it?
Here is my DataStore2 code here. I know where to plug the script in just need to know how it would be plugged in.
local defaultValue = 100
game.Players.PlayerAdded:Connect(function(plr)
local goldDataStore = DataStore2("gold",plr)
local leaderstats = Instance.new("Folder", plr)
leaderstats.Name = "leaderstats"
local gold = Instance.new("IntValue", leaderstats)
gold.Name = "Gold"
local function goldUpdate(updatedValue)
gold.Value = goldDataStore:Get(updatedValue)
end
goldUpdate(defaultValue)
goldDataStore:OnUpdate(goldUpdate)
end)
game.Workspace:WaitForChild("ChickenO").ClickDetector.MouseClick:Connect(function(player)
local goldDataStore = DataStore2("gold", player)
goldDataStore:Increment(50, defaultValue)
end)
The data might not save properly in studio because the game leaves really fast, or the server shuts down in an unexpected way. But there is a really really useful function for that (as some people mentioned already.) game:BindOnClose()!
You can check more about this function or how to properly save here.
P.S. This thread helped a lot of people. Including me!