How to use DataStore2 - Data Store caching and data loss prevention

You don’t need to pass in the default value every time. Checking the cache is free–there’s no real reason to bypass it for this use case.

Sidenote: The signature is actually :Get(nil, true), not :Get(true).

Okay thank you!
I have a couple more questions I made a separate Post because I didnt want to spam this page.

Perhaps I am misunderstanding something in your code and with the cache, but I’m having issues with delayed data updates. If I start in a lobby, go to a level, and go back to the lobby in a somewhat short amount of time (~1-2 minutes), the lobby will seem to still have the cache of my old data the first time I joined the lobby. If I leave and wait long enough my updated data from the level will eventually restore itself. I figure it has something to do with this…

delay(40, function() --Give a long delay for people who haven't figured out the cache :^(
	DataStoreCache[player] = nil
end)

I made my own small function specifically to get rid of any cached values when a player joins the lobby, however it doesn’t seem to help.

function DataStore2.ClearPlayerCache(player)
	DataStoreCache[player.Name] = nil
end

Any suggestions?

Cache is keyed with player instances (which are recreated when a player connects)–not names or user IDs, so whatever is happening is not the fault of DataStore2.

2 Likes

For some reason the data won’t save in my game.

Script of leaderstats:

local Players = game:GetService("Players")
local DataStore2 = require(game.ServerScriptService.Modules.DataStore2)

DataStore2.Combine("DATA","points","wins","nextApplication")

local function OnPlayerAdded(plr)
	if (plr:FindFirstChild("leaderstats")) then return end
	
	local l = Instance.new("Folder")
	l.Name = "leaderstats"
	
	local points,wins = Instance.new("IntValue"),Instance.new("IntValue")
	local pointsStore,winsStore = DataStore2("points",plr),DataStore2("wins",plr)
	
	points.Value = pointsStore:Get(0)
	wins.Value = winsStore:Get(0)
	
	local function updateWins(newWins)
		wins.Value = newWins
	end
	local function updatePoints(newPoints)
		points.Value = newPoints
	end
	
	pointsStore:OnUpdate(updatePoints)
	winsStore:OnUpdate(updateWins)
	
	points.Name = "Points"
	wins.Name = "Wins"
	
	points.Parent = l
	wins.Parent = l
	
	l.Parent = plr
end

for _,plr in pairs(Players:GetPlayers()) do
	OnPlayerAdded(plr)
end

Players.PlayerAdded:Connect(OnPlayerAdded)

DataStore2:

local dataStore2 = require(1936396537)

return dataStore2

Help is appreciated.

EDIT: Just found out the problem was in my awarder module.

1 Like

So whether you combine one large dictionary or not, it won’t affect any throttling?

1 Like

If you use more than one DataStore2 key without combining, you will throttle.

2 Likes

Make sure to follow the tutorial, you’re doing the updateWins and other update functions wrong.

1 Like

Hello, I am seeming to run into trouble using DS2.
I’ve heard its an excellent way to save Boolean values, as well as currencies. So I’ve been trying to do just that. But have seemed to run into some trouble in regards to the UpdateSaving section of my script. (Lines 51 and 56)

As far as my knowledge goes, which is limited of course, I don’t exactly understand this problem. And cannot seem to find a solution myself, or when searched. What exactly am I running into here as an error?

Here is an image of the “OutPut”
https://gyazo.com/be15b2c6e13dd55fbc730e8c7c9fdf84

Here is my ServerScript.

local DataStore2 = require(game.ServerScriptService.MainModule)
local MainKey = "MainKey"
DataStore2.Combine(MainKey, "Stats", "Hats")

local function SetDataTable()
	local UserData = {
		Stats = {
			["Starcoins"] = 0,
			["minplay"] = 0,
		},
		
		Hats = {
			["OrangeHalo"] = false,
			["YellowHalo"] = false,
		},	
	}
	return UserData
end

game.Players.PlayerAdded:Connect(function(plr)
	local UserData = DataStore2(MainKey,plr):Get(SetDataTable())
	
	--// Folders \\--
	local Stats = Instance.new("Folder")
	Stats.Name = "stats"
	local hats = Instance.new("Folder")
	hats.Name = "Hats"
	
	--// Numbers \\--
	local Starcoins = Instance.new("IntValue")
	Starcoins.Name = "Starcoins"
	local minplay = Instance.new("IntValue")
	minplay.Name = "minplay"
	
	--// Bools \\--
	local OrangeHalo = Instance.new("BoolValue")
	OrangeHalo.Name = "OrangeHalo"
	local YellowHalo = Instance.new("BoolValue")
	YellowHalo.Name = "YellowHalo"
	--// End Bools \\--
	
	local StatsData = DataStore2("Stats", plr)
	local HatsData = DataStore2("Hats", plr)
	
	local function UpdateStats(UpdatedValue)
		Starcoins.Value = StatsData:Get(UpdatedValue).Starcoins
		minplay.Value = StatsData:Get(UpdatedValue).minplay
	end
	
	local function UpdateHats(UpdatedValue)
		OrangeHalo.Value = HatsData:Get(UpdatedValue).OrangeHalo
		YellowHalo.Value = HatsData:Get(UpdatedValue).YellowHalo
	end
	
	UpdateStats(UserData.stats)
	UpdateHats(UserData.hats)
	
	StatsData:OnUpdate(UpdateStats)
	HatsData:OnUpdate(UpdateHats)
	
	Stats.Parent = plr
	hats.Parent = plr
	Starcoins.Parent = Stats
	minplay.Parent = Stats
	OrangeHalo.Parent = hats
	YellowHalo.Parent = hats
	
end)
1 Like

Using DataStore2 with the master key is undefined behavior and is not supported.

1 Like

Hello, could I fix this? And allow this script to work with a fixed line there?

1 Like

From your Backups documentation:

How will you know when to use a backup? If it is successful before the first 5 tries, it won’t set a backup? Will DataStore2 :Get throw an exception when data stores are down? I’m probably missing something here.

1 Like

You just use the data stores with their default values instead of putting them all in one table. I recommend reading the documentation if you haven’t already.

2 Likes

Correct.

:Get() will repeat over and over again until it doesn’t get an error, or if you have backups set until the backups count is reached. :Get() only ever calls the DataStoreService API the first time you use it.

Will do! Thank you for your assistance!

1 Like

What am i doing wrong

local module = {}

local datatable = {}
local DefaultXash = (1000)
local DefaultDeaths = (0)
local DefaultLevel = (1)
function module.Data(plr)
	
local dataStore2 = require(script.Parent.DataStore2)
dataStore2.Combine("XashKey","DeathKey","LevelKey")

setmetatable(datatable,{
	__index = function(t,k)
		
		local folder = Instance.new("Folder")
		folder.Parent = plr
		folder.Name = "leaderstats"
		
		local Xash = Instance.new("IntValue")
		Xash.Parent = folder
		Xash.Name = "Xash"
		
		local Deaths = Instance.new("IntValue")
		Deaths.Parent = folder
		Deaths.Name = "Death"
		
		local Levels = Instance.new("IntValue")
		Levels.Parent = folder
		Levels.Name = "Level"
		
		return t
	end
})
print(datatable.t)
local XashDataStore = dataStore2("XashKey",plr)
local DeathDataStore = dataStore2("DeathKey",plr)
local LevelDataStore = dataStore2("LevelKey",plr) 

local function xashSave(update)
	plr.leaderstats.Xash.Value = XashDataStore:Get(update)
end

local function deathSave(update)
	plr.leaderstats.Death.Value = DeathDataStore:Get(update)
end
local function levelSave(update)
	plr.leaderstats.Level.Value = LevelDataStore:Get(update)
end

xashSave(DefaultXash)
deathSave(DefaultDeaths)
levelSave(DefaultLevel)

XashDataStore:OnUpdate(xashSave)
DeathDataStore:OnUpdate(deathSave)
LevelDataStore:OnUpdate(levelSave)

end

return module

what am i doing wrong, keep getting an error saying
[ ServerScriptService.Script.DataStore2:372: attempt to index local ‘tableResult’ (a number value)]

1 Like

As I’ve said above:

You are using the master key as a DataStore2 key, which is undefined and could cause issues.

2 Likes

Thank you, i was stuck on this.

1 Like

@Kampfkarren Is there a way to retrieve all the players data that have saved data in the game into a list in context of an applications list that i can look at later?

1 Like

No, there is no way to do this with default data stores either.

1 Like