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

Value objects are never used in DataStore2 except for the SaveInStudio flag.

This is not an issue related to the module. I’d recommend starting from the Roblox Developer Hub.

I’m currently working on a new project and I was wondering if its recommended to use the OrderedBackups or Standard setting.

Personally, I haven’t had any problems using OrderedBackups, and it’s saved me a few times when players report data loss (because I use the module incorrectly) and I can easily revert their data back. It’s also battle tested, I’m not sure if any high profile games use Standard. My suggestion is if you use plenty of other ordered data stores, Standard is your only choice. Otherwise, use OrderedBackups.

2 Likes

Is it ok if I take some data (value, string, bool) a few times (more than usual). Will that cause lag? By “more than usual” I mean, if somebody clicks a button, it would request data, if someone dies and respawns, etc. What’s suggested limit if so?
2nd: Is there still chance that users lose their data?

2 Likes

:Get() only calls a data store request the first time you use it, and :Set() calls data store requests never. Using methods frequently is essentially the same as just setting a variable, so you’ll be fine.

1 Like

@Kampfkarren
Is there any function that is similar to this

local DataStore = game:GetService("DataStoreService"):GetOrderedDataStore()
local 1To100 = DataStore:GetSortedAsync(false, 10)

What I mean is
I’m trying to get the data from the server and transfer it to the client and my issue will be fixed if there is a similar function like :GetOrderedDataStore() I need a similar function for this to function my leaderboard.

EDIT: Using The :Get() Function Will Not Work I need the function to be global not local and is there a Similar Function Like :GetSortedAsync().

Sorry for the bad English.

Reminder: Check the code for better towards on understanding my problem

Thanks.

DataStore2 does not provide ordered data stores, use normal data stores for that anyway.

Hmm Well Does DataStore2 Work With Normal DataStore Functions?

Yes it is a wrapper for regular data stores

I’ve recently just switched to datastore2 and its amazing!
So I have this harvesting system in my game - harvesting trees to earn the currency “Lemons”. You can only do so every 2 hours.

However, when I update the time and day the player harvests, I get this error:

ServerScriptService.mainCode.saveData:147: attempt to index field 'InitialData' (a nil value)

And here’s the code where the error comes from

local players = game:GetService("Players")
local dataStore2 = require(game.ServerStorage.MainModule)
local userDataStoreName = "UserDataStore"

local function setupUserData()
	local  userData = {
	
	Currency = {	
	["Lemons"] = 500;
	};
	InitialData = {
	["wday"] = 1; --the day today
	["stamina"] = 1; 
	["nightslumber"] = "n";
	["lastTick"] = 0; -- last harvest time
	["season"] = "Spring";
	};
}
	return userData
end
local tree = game.Workspace.LemonTree
local timeModule = require(game.ReplicatedStorage.GetDate)

local function get24()
	local date = timeModule()
	return date:format("#h")
end

local function getDay()
	local date = os.date("*t")
	return date.wday
end

game.Players.PlayerAdded:Connect(function(player)
    --setting up the player's data
	local userDatastore = dataStore2(userDataStoreName, player)
	local userData = userDatastore:Get(setupUserData())
	print(userData["Currency"]["Lemons"])
	
	local last = userData["InitialData"]["lastTick"]
	local day = userData["InitialData"]["wday"]
             --checking if the player is able to harvest the tree(s)
		local date = get24()
		if (date - last) >= 2 or (last - date) >= 2 or (getDay()) ~= day or userData:Get(0) then
			print("ready")
			player.PlayerGui:WaitForChild("status").TextLabel.Text = "Lemon Tree - Ready!"
		elseif (date - last.Value) < 2 then
			print("not ready")
			player.PlayerGui.status.TextLabel.Text = "Lemon Tree"
		end
end)
--remote
game.ReplicatedStorage.remotes.harvestHandler.OnServerEvent:Connect(function(player)
	local userData = dataStore2(userDataStoreName, player)
	
	if userData["InitialData"]["wday"] ~= getDay() then --error line, where "InitialData", which is the dictionary for the data, is a nil value
			userData["InitialData"]["wday"]  = getDay()
		print("change day")
		end
	
	userData["InitialData"]["lastTick"] = tonumber(get24())

	userData["Currency"]["Lemons"] = userData["Currency"]["Lemons"] + 50 --adding of stats
	userData["InitialData"]["stamina"]  = userData["InitialData"]["stamina"] - 30
    dataStore2(userDataStoreName, player):Set(userData)
	print(userData["Currency"]["Lemons"])
	print("set")
end)

You aren’t calling :Get here. You’re indexing the DataStore2 instance directly.

1 Like

I forgot to add that I only use 1 key :sweat:. If that is the case, do I still use :Get()?

But if then, how would I write it to get "InitialData" to retrieve "wday"? Would it be like this?

if userData:Get(0)["InitialData"]["wday"] ~= getDay() then --Is this the correct way of using :Get() for the situation? Or is there a better way?
		userData["InitialData"]["wday"]  = getDay()
	print("change day")
	end

If you don’t call :Get(), then you’re just acting on the DataStore2 instance instead of the actual data.

In any case, it’s non idiomatic to have one table key and put all your data in there in the first place. Combined data stores do a better job, you see this pattern in Roblox normally to avoid throttling, so as long as you combine all your keys, there’s no longer a point to doing it this way.

1 Like

Is it okay if I use more Combined datastores?
Basically, I have like “different cetegories”. (Currently 4 combined DS2’s)
Is this okay? Or bad for saving data?

How to transfer all datas in my old datas and convert them to this?

1 Like

If you use more than one combined key (the first parameter), it misses the point of combining them in the first place.

Assuming you were doing it idiomatically in the first place, where the keys are just user IDs, you can just set the saving method to Standard.

https://kampfkarren.github.io/Roblox/advanced/saving_methods/

Since data can’t be set in PlayerRemoving, how can I add a way to track when a player was last in game?

You can use BeforeSave to add a new key before it saves.

Hi, I’ve been using DataStore2 for a while, and its really good - thank you very much for the module!

I was just wondering, is there a way to disable saving player data when users join Private/VIP servers - I still want to load a players current progress/data when they are in a VIP server, but I don’t want to save it when they leave the game. Is there something similar to how you have SaveInStudio?