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

You’re probably right about that, but I’m using regular datastores and that’s what worked for me.

Autosaving still isn’t a bad idea though, regardless if you have backups of the players’ data or not.

1 Like

I’m not sure I understand how backups work. From reading this thread, I’ve gathered that setting a store’s backup also sets the entire combined store’s backup with the same number of retries.

During Roblox outages, sometimes I test the game on studio to see if it works as it should when DataStores are down. Instead of DataStore2 flagging stores as a backup when it can’t get the data, I get an error and none of my data loads:

502: API Services rejected request with error. HTTP 500 (Internal Server Error)

Not sure if I’m using backups wrong, using DataStore2 wrong, or just misunderstanding something. I think that maybe this error only occurs in Studio and in-game would flag stores as a backup when this happens, but I’m not sure.

I’m using the ‘Standard’ data-saving method, but this has happened before while using the ‘OrderedBackups’ method.

local DataStore2 = require(1936396537)
local defaultValue = 100
local plr = game.Players.LocalPlayer
local Text = plr.PlayerGui.ScreenGui.TextLabel.Text

DataStore2.Combine("DATA", "cash")

game.Players.PlayerAdded:Connect(function(plr)
	
	local cashDataStore = DataStore2("cash",plr)
	
	local stats = Instance.new("Folder",plr)
	stats.Name = "stats"
	
	local cash = Instance.new("IntValue",stats)
	cash.Name = "cash"
	cash.Parent = stats
	
	local function cashUpdate(updatedValue)
		cash.Value = cashDataStore:Get(updatedValue)
		Text = cash.Value
	end
	
	cashUpdate(defaultValue)
	
	cashDataStore:OnUpdate(cashUpdate)
	
end)

game.Workspace:WaitForChild("Part").ClickDetector.MouseClick:Connect(function(player)
	--add 50 to current points balance
	local cashDataStore = DataStore2("cash",player)
	cashDataStore:Incrememnt(50,defaultValue)
end)

what am i doing wrong here? The text label doesn’t change when i click on the block

2 Likes

try it on a roblox game or try requiring module from a copy of it. it sometimes happens when you require the module through the id it sometimes doesn’t load in on studio.

1 Like

I thought DataStore2 is no longer supported with the requiring method and you would have to download a copy to use it?

3 Likes

I test it ingame. I also switched back to requiring the module but it still doesnt work

1 Like

I switched back to requiring the module but it still doesnt work

1 Like

If you read the documentation, you will see this method is not supported anymore, you are going to be running on an ancient version.

This won’t work, because there is no LocalPlayer on the server.

This isn’t how you set text, this is just updating your own copy.

I recommend learning RemoteEvents and what a LocalScript is before trying to use DataStore2.

i got a normal datastore working so i’m just gonna use that and maybe return to datastore 2 later

I don’t really know what you’re asking, your video doesn’t really show anything to me.

1 Like

I am asking how to fix OnUpdate not being called and therefore the gui does not show the currency data of the player.

Could you provide some code? OnUpdate works fine for me.

Hey. Firstly thank you for this module. I’m trying to use data store 2 on my game but i have a problem. I have a dedicated script on all npcs as a child. I’m rewarding players depending on the damage to the npc. Script is working fine and i can see correct updated value on leaderboard. Data store 2 looks like can’t catch it up with increment method. When i quit and rejoin my gold is less then it should be. Here is my script. Should i change the way i do this or there is another problem?

local npc = script.Parent
local hum = npc:WaitForChild("Humanoid")
local npcInfo = require(game:GetService("ReplicatedStorage"):WaitForChild("NpcInfo"))

local goldReward = npcInfo[npc.Name].GoldReward

--Data Sore 2
local ServerScriptService = game:GetService("ServerScriptService")
local DataStore2 = require(ServerScriptService.DataStore2)
DataStore2.Combine("DATA", "temp_gold")

--Create variables
local statusFolder = Instance.new("Folder")
statusFolder.Name = "Attackers"
statusFolder.Parent = npc

local debounce = false

hum.Died:Connect(function()
	if debounce then return end
	debounce = true
	local attackers = statusFolder:GetChildren()
	
	for _, attacker in pairs(attackers) do
		local gold = game.Players:WaitForChild(attacker.Name):WaitForChild("leaderstats").Gold
		if gold == nil then return end
		local maxHealth = hum.MaxHealth
		if attacker.Value > maxHealth then attacker.Value = maxHealth end
		--Add actual gold to leaderboard
		gold.Value = gold.Value + ((attacker.Value/maxHealth) * goldReward)
		--Save the gold
		local goldStore = DataStore2("temp_gold", player)
		goldStore:Increment((attacker.Value/maxHealth) * goldReward)
	end
end)

It seems to me that you are only incrementing the datastore whenever the NPC dies (hum.Died), you could make it so that if the player leaves, it rewards them the amount they are owed.

So i should just update the leaderboard and listen for PlayerRemoving event to actually update it on datastore? There will be a server crash and data will be lost. I can save it on exact intervals but i don’t think it’s a correct way. I want to update it when gold is gained and spent.

What do you mean? DataStore2 doesn’t use a datastore API call whenever you use :Increment, it’s changed locally in the player cache, then saved whenever the player leaves.

Oh i don’t know actually how DataStore2 is working. As i know it should automatically save value when player leaves as you said. Could you give me a code sample to do what you said earlier and i can try it. I don’t know all methods of DataStore2 and i couldn’t find anything on documentation. Can i read the cached value with a method ?

You’d probably do something along the lines of this…

--your npc script

local PLRS = game:GetService("Players")
PLRS.PlayerRemoving:Connect(function(removingPlayer) -- when a player leaves
    -- check if plr is an attacker
    local isAttacker = statusFolder:FindFirstChild(removingPlayer.Name)
    if (isAttacker) then
        -- reward gold
    end
end)

Thanks for your help! I should try different ways to do it i guess.

1 Like

How can i use a custom key instead of a player to store data?

local BuildStore = DataStore2("BuildData", "server")