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

And voila, now i can show the characters on their cards properly. WIthout the data not working cause its too much data XD

https://gyazo.com/ff92baaacab1fba871f49d37f4021bc0

1 Like

I need some professional advice regarding what I should do here. I have been experiencing cases of data loss using DS2 when using it properly (combining all stores), but I think the issue is that I’m also using ordered datastores for leaderboards. I sync 1 player’s data in the server from DS2 to ODS every 10 seconds (3 different stores) and update the leaderboards every 4 minutes (there’s 4 of them). Even when I don’t see any throttling messages, sometimes the data still doesn’t save properly. People will just lose a couple of levels and revert back to their previous save before that session. Should I get rid of leaderboards completely? I also read that switching to standard saving method might help as well, but I already have 1 million visits and wouldn’t want to revert all of their data. Any advice is appreciated

This is super frequent considering the harsh limitations of OrderedDataStore writings. You should, at most, be doing it when a player leaves.

If it’s possible (your game isn’t super public yet, for instance) you can change the saving method to Standard, which will clear data. Otherwise, you need to limit your usage of writing to ODS.

1 Like

This is great but I have a 2 questions.

  1. How would I implement this into my game without data loss from switching systems?

and

  1. I have multiple scripts with different things to save for organization. Is it possible if they all went to the same ModuleScript?

You can check if the player has data by checking if :Get() on a store returns nil. Then, you can check if they have data in your old store, and if you do to transfer it over.

Is what possible?

Sorry for the last one being unspecified, I meant if it was possible to have multiple variables sent to the ModuleScript and from multiple Scripts like, for example, Levels and Exp being saved onto here.

You can call data store methods from multiple scripts and get the correct results.

It would be great if this supported global datastores, unless I am missing something. Nevertheless this is a great module!

Data Stores Are Global Data Stores Already. And DataStore2 Actually Uses Data Stores Under The Hood So It Is A Global Data Store Already.

local DataStoreService = game:GetService("DataStoreService")
local MyDataStore = DataStoreService:GetDataStore("MyData")
print(MyDataStore.ClassName)

You Will See GlobalDataStore In The Output.

I know that, but I want to save data that isn’t tied to a user.

1 Like

The Whole Point Of DataStore2 Is For PLAYER Data So This Won’t Be Possible. Just Don’t Use DataStore2 For That. It Is Easy To Implement The Caching Methods Used In The Module And Such. Just Check Out The Source Code I Did It A Few Times And Was Able To Make A DataStore2 That Wasn’t Based On Players. I Don’t Think I Can Share It Here But I Can Tell You In DMs How I Did It.

Alright, I will do that. Thank you for your help, I don’t feel like making my own cache and whatnot

Small question: How do I comply with the GDPR/CPPA using DataStore2 (About GDPR and CCPA | Documentation - Roblox Creator Hub, section “Removing Personal Information”) without the player being in the game upon being requested to remove data?

Search DataStore2 GDPR and you should see the answer.

Oh thanks :slight_smile: (I couldn’t find anything matching on the Wiki that is related to what roblox stated as the example in the link I specified, which is why I asked here)

1 Like

How many datastore requests are you making per minute?

Hi there! I have a quick easy question about the Combine function using tables.
Do I do this:

dataStore2.Combine("Data","userData")

local function setupUserData()
	local userData = {
		Currency = {
			["Coins"] = 0;
			["Gems"] = 0
		};
		Achivements = {
			["AllCoinsCollected"] = 0;
			["AllGemsCollected"] = 0
		}
	}
	return userData
end

Or this:

dataStore2.Combine("Data","Coins", "Gems", "AllCoinsCollected", "AllGemsCollected")

local function setupUserData()
	local userData = {
		Currency = {
			["Coins"] = 0;
			["Gems"] = 0
		};
		Achivements = {
			["AllCoinsCollected"] = 0;
			["AllGemsCollected"] = 0
		}
	}
	return userData
end

Or does it not really mattter? Sorry if you have answered this question before.

Have a great Day! :smile:

You only call Combine with the keys you use. Having one “userData” table is pointless.

In your case, you should just be doing:

DataStore2.Combine("Data", "Currency", "Achievements")

and then later…

DataStore2("Currency", player)

1 Like

I took your advice and changed the ODS to only update when the player leaves. Unfortunately, I’m still experiencing very inconsistent data reversion to the last successful save. The only time I’m writing to ODS is when a player leaves (3 stores), and once every round (~5 minutes) to one store keeping track of map choice. Then 4 leaderboards update every 4 mins. This usage seems rather conservative, so I guess I’m wondering if my only other options are to 1) wipe player data to change save setting (not really an option) 2) delete leaderboards or 3) reduce the number of leaderboards (would that actually help? It doesn’t seem like I’d be hitting limits with this little usage). Alternatively, it could be an issue with something else but from reading, researching, and experimenting, I don’t see what it could be besides this. I’m also getting added to queue warnings when a player leaves sometimes, but to my knowledge this shouldn’t affect DS2 saving since they use different keys? Correct me if I’m wrong.

TLDR: Is my ODS usage still too much, or should I just get rid of them entirely? Is there any other possible cause?

Your best case is probably to remove ODS leaderboards and use this as a lesson for the future on perhaps setting the saving method to standard earlier.

1 Like