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

You can access normal datastores of offline players with their key (probably their UserId for example). But DS2 requires the player instance, which makes that not possible

1 Like

Oh sorry I misunderstood your question, I thought you meant the roblox studio offline mode where you dont need wifi

1 Like

oh no, not that lol. Although it is possible, you can simulate local datastores for offline studio there is a thread for it I think :slight_smile:

1 Like

Yes, you just need backtrack the system to determine how it wrote the Scope and the Key to access the datastores you want to see.

This is probably a good thing to know how to do with the new European Data Privacy laws.

2 Likes

If this is your intent:

3 Likes

Hello, I have a question about my code, I’m just trying to verify that this code is correct since I don’t have a way to test if it works. Should my :SetBackup() and IsBackup() work correctly here?

DataStore2.Combine("MasterDataKey","pigment","petTokens","equippedPets","currentGun","currentBackpack","petInv","gunInv","backInv","music","trajectory","othersPaint","currentQuest","doneQuest","newPaint","amountPaint")

local pigmentSave = DataStore2("pigment", player)
local petTokensSave = DataStore2("petTokens", player)
local equippedPetsSave = DataStore2("equippedPets",player)
local currentGunSave = DataStore2("currentGun", player)
local currentBackSave = DataStore2("currentBackpack",player)
local petInvSave = DataStore2("petInv",player)
local gunInvSave = DataStore2("gunInv",player)
local backInvSave = DataStore2("backInv",player)
local musicSave = DataStore2("music",player)
local trajectorySave = DataStore2("trajectory",player)
local othersPaintSave = DataStore2("othersPaint",player)
local currentQuestSave = DataStore2("currentQuest",player)
local doneQuestSave = DataStore2("doneQuest",player)
local newPaintSave = DataStore2("newPaint",player)
local amountPaintSave = DataStore2("amountPaint",player)

pigmentSave:SetBackup(3)

if pigmentSave:IsBackup() then
	--alert player about backup
	player:Kick("Error loading game, please rejoin.")
end
2 Likes

That looks right to me, yeah.

1 Like

hey, since you wrote that function to clear an offline player’s datastore, can you please make one to retrieve an offline players one? I want to see data of offline players for a database lookup, thank you really appreciate it, this is the best module on this forum by far

1 Like

It shouldn’t be hard to slightly tune the script I made to do it. That being said, it’s possible it could be added in the future: https://github.com/Kampfkarren/Roblox/issues/44.

1 Like

Suggestion:
Add DataStore:Subtract(value, defaultValue), which would just be DataStore:Increment(-value)

3 Likes

Should this be only in one, main script.
And then you would normally declare;
DataStore2("Key1", player) ?

It works fine if you spread it across multiple scripts (I do this).

1 Like

Hello, Is it necessary to call :SetBackup every time when you want to retrieve data in different scripts?
Whenever a player joins the game, their data will be retrieved, so if there would be an error retrieving their data, they will get kicked. But is it possible that while playing the game, retrieving data could also fail? even though when the player joined everything went right?

example script1

game.Players.PlayerAdded:Connect(function(plr)
	
	local PointsDatastore = DataStore2("Points", plr) 
	PointsDatastore:SetBackup(5)

    if PointsDatastore:IsBackup() then
       player:Kick("message")
    end											
end)

example script2

game.ReplicatedStorage:WaitForChild("Buy_Item").OnServerInvoke = function(player, itemName)

    local pointsDataStore = Datastore2("Points", player)

    PointsDataStore:SetBackup(5) --is this necessary?

    if PointsDataStore:IsBackup() then
       player:Kick("message")
    end

    --search for item in serverstorage

    if pointsDataStore:Get(0) > item.Value then
         --something to do with the item...
         --return("Succes")
    else 
         --return("fail")
    end
end

1 Like

Retrieving: no, because Get() does not call data store functions after it gets it. It caches.

For calling SetBackup in multiple scripts, this is necessary if you cannot guarantee the order in which Roblox will run your scripts. You want to make sure SetBackup is called somewhere before using Get() if you plan on using it.

1 Like

Wow this is so easy to use and efficient
i will be using Datastore2

So in the example I just wrote :SetBackup wasn’t necessary in script2? Since a player needs to join the game (script1) in order to make a purchase (script2). But it is still safe to do so to minimize the chance of dataloss?

It’s redundant, yes. You could call it anyway but if the other code didn’t work you’re in trouble anyway.

2 Likes

I’m having players report to me that when they leave the game and rejoin, their data is set back to a previous save. Am I doing something wrong and is there anyway I can prevent this from happening? Seems to happen more often when I shutdown servers.

This is a new bug I haven’t heard of, but I have heard recent reports of shutting down games using old data. Can you make an issue on the GitHub about it?

2 Likes

I use DataStore2 and when I shut down game servers to push updates, a lot of people lose data. I assume it’s something I’m doing wrong. Do you know the common mistakes that could lead to this? Thanks

2 Likes