Datastores being broken

Hello. In my game, i require 2 datastores. One which holds the players win’s and coins and the other for abilities in the background, something is not right though as these datastores are heavily broken. For datastore number one (The one with wins and coins) is delayed by 5 seconds or so, could somebody help me why it does that?

For the 2nd one, it won’t save the 2nd or 3rd boolvalue half of the time. Please help!

datastore one

local DataStore = game:GetService("DataStoreService")
local ds = DataStore:GetDataStore("LeaderStatSave")
local ds2 = DataStore:GetDataStore("LeaderStatSave2")

game.Players.PlayerAdded:connect(function(player)
local leader = Instance.new("Folder",player)
leader.Name = "leaderstats"	
	local Cash = Instance.new("NumberValue",leader)
	
	Cash.Name = "Wins"
	
local Cash2 = Instance.new("NumberValue",leader)
	Cash2.Name = "Coins"
	
	Cash.Value = ds:GetAsync(player.UserId) or 0
	Cash2.Value = ds2:GetAsync(player.UserId) or 0
	ds:SetAsync(player.UserId, Cash.Value)
	ds2:SetAsync(player.UserId, Cash2.Value)
Cash.Changed:connect(function()
		ds:SetAsync(player.UserId, Cash.Value)
Cash2.Changed:connect(function()
			ds2:SetAsync(player.UserId, Cash2.Value)
		end)
	end)
end)

game.Players.PlayerRemoving:connect(function(player)
	ds:SetAsync(player.UserId, player.leaderstats.Wins.Value)
	ds2:SetAsync(player.UserId, player.leaderstats.Coins.Value)
end)

Datastore two


local DataStore = game:GetService("DataStoreService")
local ds = DataStore:GetDataStore("Ability")
local ds2 = DataStore:GetDataStore("Ability2")
local ds3 = DataStore:GetDataStore("Ability3")

game.Players.PlayerAdded:connect(function(player)
local leader = Instance.new("Folder",player)
leader.Name = "Abilities"	
local Cash = Instance.new("BoolValue",leader)
	Cash.Name = "Boost"
local Cash2 = Instance.new("BoolValue",leader)
	Cash2.Name = "Heal"
local Cash3 = Instance.new("BoolValue",leader)
Cash3.Name = "Engineer"
	
	Cash.Value = ds:GetAsync(player.UserId) or false
	Cash2.Value = ds2:GetAsync(player.UserId) or false
	Cash3.Value = ds3:GetAsync(player.UserId) or false
	ds:SetAsync(player.UserId, Cash.Value)
	ds2:SetAsync(player.UserId, Cash2.Value)
	ds3:SetAsync(player.UserId, Cash3.Value)
Cash.Changed:connect(function()
		ds:SetAsync(player.UserId, Cash.Value)
Cash2.Changed:connect(function()
			ds2:SetAsync(player.UserId, Cash2.Value)
Cash3.Changed:connect(function()
				ds2:SetAsync(player.UserId, Cash3.Value)
			end)
		end)
	end)
end)

game.Players.PlayerRemoving:connect(function(player)
	ds:SetAsync(player.UserId, player.Abilities.Boost.Value)
	ds2:SetAsync(player.UserId, player.Abilities.Heal.Value)
	ds3:SetAsync(player.UserId, player.Abilities.Engineer.Value)
end)

Thank you.

1 Like

Is you’re code erroring at all? Datastores are meant to be wrapped in a pcall since they can fail.

1 Like

No, my code does not error, it’s confused since i used the exact one for a single datastore and it works like a instant.

1 Like

Hello? Joshument, are you there?

1 Like

well the way you’re using datastores is very weird so I’d just add a bunch of debug statements. Also please don’t reply to me after I haven’t replied in like. 8 minutes lol

1 Like

what do you mean by “Debug Statements?”

1 Like

use a debugger or print intermediary values

1 Like

Now you just made me more confused by “use a debugger or print intermediary values”

1 Like

Are you sure you need 3 data stores for storing 3 values?
Also do not set async data when value is changed, if it does too frequently then it will fail. Instead store it in a table and save the table to one data store when player leaves

1 Like

I searched it up, i will try now.

1 Like

I don’t know how to do tables, you see i’m not the best at datastores. :sweat:

1 Like

Add table like this at the top of your code:

local temporalData = {}

and insert user id when player is added:

game.Players.PlayerAdded:Connect(function(plr)
      temporalData[plr.UserId] = ds:GetAsync(plr.UserId)
      --make all your bool values here
      local cash1 = temporalData[plr.UserId].Cash1
      if cash1 == nil then
            cash1 = false
      end
      Cash.Value = cash1
      Cash.Changed:connect(function()
            temporalData[plr.UserId].Cash1 = Cash.Value
      end)
end)
game.Players.PlayerRemoving:Connect(function(plr)
      --Save it to one data store
      ds:SetAsync(player.UserId, temporalData[plr.UserId])
      temporalData[plr.UserId] = nil
end)
1 Like

Oh, these are tables. Oh… i have lots of questions about theses…
First, what’s the top script aka the TemporalData for?
Second, How would i exactly make all my bool values, the same as before or?
Third, What do you mean by “Save it to one datastore”
Lastly, Can i repeat this for my ability datastore?
Thank you.

1 Like

You edited it, now i’m more confused. Sorry for being very questioning, do i just copy

      local cash1 = temporalData[plr.UserId].Cash1
      if cash1 == nil then
            cash1 = false
      end
      Cash.Value = cash1
      Cash.Changed:connect(function()
            temporalData[plr.UserId].Cash1 = Cash.Value
      end)
end)

and i just change it from there?

1 Like

This part adds player data to table when player is added, so “top script” temporalData is required:

temporalData[plr.UserId] = ds:GetAsync(plr.UserId)
--to make the values same as before set them to loaded data
--whoops
local cash1 = temporalData[plr.UserId].Cash1
--if there's none of whatever you need then set it to false (or 0 if it's NumberValue)
if cash1 == nil then
    cash1 = false
end
Cash.Value = cash1

when player leaves, it will save the table to data store:

--just have one data store like: DataStore:GetDataStore("PlayerData")
ds:SetAsync(player.UserId, temporalData[plr.UserId])
--and set it to nil to save memory
temporalData[plr.UserId] = nil
1 Like

How would i add multiple values to fit it?

1 Like

Yes copy this and change “false” to number if it’s a NumberValue

1 Like

No, i mean how would i add coins and wins values

1 Like

In the table like this?

temporalData[plr.UserId].Wins = 0

Also add or {} to this

temporalData[plr.UserId] = ds:GetAsync(plr.UserId) or {}
1 Like

This really confuses me. So i just add

temporalData[plr.UserId].Wins = 0

to

temporalData[plr.UserId] = ds:GetAsync(plr.UserId)
temporalData[plr.UserId].Wins = 0
--to make the values same as before set them to loaded data
--whoops
local cash1 = temporalData[plr.UserId].Cash1
local win1 = temporalData[plr.UserId].Wins1
--if there's none of whatever you need then set it to false (or 0 if it's NumberValue)
if cash1 == nil then
    cash1 = false
end
Cash.Value = cash1

Yeah this is confusing.

1 Like