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

It works! Thank you everybody for your help. Have a nice day!

Did you mean :Save() here?

just trying to clear any confusion

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local ServerScriptService = game:GetService("ServerScriptService")
local DataStore2 = require(game.ServerScriptService.DataStore2)
DataStore2.Combine("DATA", "Stats", "Inventory")

local Stats = {
	Strength = 0;
	Rebirths = 0;
	Cash = 1000;
	Speed = 20
}

local Inventory = {
	Cat = false;
	BigGear = false
	}



local playersavetable = {};

local function loadStarterData(Player)
		local leaderstats = Instance.new("Folder")
		leaderstats.Name = "leaderstats"
		leaderstats.Parent = Player
		local Inv = Instance.new("Folder")
		Inv.Name = "Inventory"
		Inv.Parent = leaderstats
		for statname, statvalue in pairs(Stats) do
			if type(statvalue) == 'number' then
			local intvalue = Instance.new("IntValue")
			intvalue.Name = statname
			intvalue.Value = statvalue
			intvalue.Parent = leaderstats
			end
			for statname, statvalue in pairs(Inventory) do
			if type(statvalue) == 'boolean' then
			local intvalue = Instance.new("BoolValue")
			intvalue.Name = statname
			intvalue.Value = statvalue
			intvalue.Parent = Inv
			end
		end
	end
		end

local function loadData(player)
	local Data
	local s, e = pcall(function()
	Data = DataStore2:GetAsync('UserId'..player.UserId)
	end)
	
	if s then 
		print (player.Name.."Data loaded")
	else
		print(player.Name.."Data failed to load")
	end
	
	if Data then
		for statname, statvalue in pairs(Data) do
			if type(statvalue) == "number" then
			player.leaderstats[statname].Value = statvalue
			else if type(statvalue) == "boolean" then
			player.leaderstats.Inventory[statname].Value = statvalue
			end
			end
		end
		print(player.Name.."Data has been loaded")
	else
		print(player.Name.."No data found! generating..")
		end
	end

local function saveData(player, Stats)
	--if RunService:IsStudio() then return end
	local Data = {}
	for _, stat in ipairs(Stats:GetChildren()) do
   if not stat:IsA("Folder") then
       Data[stat.Name] = stat.Value
   end
end
	local s, e = pcall(function()
		DataStore2:SetAsync('UserId'..player.UserId, Data)
	end)
		if s then 
	print(player.Name.."Data has been saved")
		else
	warn (player.Name.."Data failed to save"..e)
	end
end

ReplicatedStorage.SaveEvent.OnServerEvent:Connect(function(player)
 saveData(player)	
end)

Players.PlayerAdded:Connect(function(player)
	playersavetable[player] = tick()
	loadStarterData(player)
	loadData(player)
end)

Players.PlayerRemoving:Connect(function(player)
	saveData(player)
end)

On attempt to save I get the error " [ServerScriptService.datastore:78: attempt to index local ‘Stats’ (a nil value"

Yes, I did, my bad.

You are not using DataStore2 right at all. GetAsync in DataStore2 is not like it in normal data stores–it returns a promise. It also never errors. Please read the examples in the documentation.

Why’d you reply to my comment?

Mobile forum UI got in my way, I think. Whoops. That was in reply to @Quoteory

2 Likes

1 Question I’m a little bit confused on saving data on tables using DataStore2

Mind if u help me out?

The other u answered fixed my problem

Now I need to save items from the table

Help me on how to save tables in DataStore2

You save them like any other value. ds2:Set({ })

i cant understand on how to get the table

You save and get them like any other value. There is nothing special about tables.

local DataStore2 = require(game.ServerStorage:WaitForChild("DataStore2"))
local DefaultRank = "Noob"
local DefaultCapacity = 15
local DefaultRankBoost = 1
DataStore2.Combine("Sticks", "Coins", "Kills", "X2Sticks", "Class", "ClassBoost", "Kill Streak", "Inventories","Capacity")

local Tables = {}

function plrAdded(player)
	local SticksStore = DataStore2("Sticks", player)
	local CoinsStore = DataStore2("Coins", player)
	local KillStore = DataStore2("Kills", player)
	local ClassStore = DataStore2("Class", player)
	local ClassBoostStore = DataStore2("ClassBoost", player)
	local X2Sticks = DataStore2("X2Sticks", player)
	local X2Coins = DataStore2("X2Coins", player)
	local KillCombos = DataStore2("Kill Streak", player)
	local CapacityStore = DataStore2("Capacity", player)
local InvSaves = DataStore2("Capacity", player)
	
	local folder = Instance.new("Folder")
	folder.Name = "leaderstats"
	folder.Parent = player
	

-- In Saving
local folderofplr = Instance.new("Folder")
folderofplr.Name = player.Name
folderofplr.Parent = game.ServerStorage

InvSaves:Get(function()
for i, items in pairs(game.ServerStorage[player.Name]:GetChildren) do
table.insert(Tables, items)
end
end)

InvSaves:Set(Tables)
	-- Get the stats
	
	local Sticks = Instance.new("NumberValue")
	Sticks.Parent = folder
	Sticks.Name = "Sticks"
	Sticks.Value = SticksStore:Get(0)
	
	SticksStore:OnUpdate(function(value)
		Sticks.Value = value
	end)
	
	local Coins = Instance.new("NumberValue")
	Coins.Name = "Coins"
	Coins.Parent = player
	Coins.Value = CoinsStore:Get(0)
	
	CoinsStore:OnUpdate(function(value)
		Coins.Value = value
	end)
	
	
	local Kills = Instance.new("NumberValue")
	Kills.Parent = player
	Kills.Name = "Deaths"
	Kills.Value = KillStore:Get(0)
	
	KillStore:OnUpdate(function(value)
		Kills.Value = value
	end)
	
	local KillStreaks = Instance.new("NumberValue")
	KillStreaks.Name = "Kill Streaks"
	KillStreaks.Parent = folder
	KillStreaks.Value = KillCombos:Get(0)
	
	KillCombos:OnUpdate(function(value)
		KillStreaks.Value = value
	end)
	
	local Rank = Instance.new("StringValue")
	Rank.Name = "Class"
	Rank.Parent = folder
	Rank.Value = ClassStore:Get(DefaultRank)
	
	ClassStore:OnUpdate(function(value)
		Rank.Value = value
	end)
	
	local RankBoost = Instance.new("NumberValue")
	RankBoost.Name = "ClassBoost"
	RankBoost.Parent = Rank
	RankBoost.Value = ClassBoostStore:Get(DefaultRankBoost)
	
	ClassBoostStore:OnUpdate(function(value)
		Rank.Value = value
	end)
	
	local Caps = Instance.new("NumberValue")
	Caps.Name = "MaxCapacity"
	Caps.Parent = Sticks
	Caps.Value = CapacityStore:Get(DefaultCapacity)
	
	CapacityStore:OnUpdate(function(value)
		Caps.Value = value
	end)
end

for _, player in pairs(game.Players:GetPlayers()) do
	plrAdded(player)
end

game.Players.PlayerAdded:Connect(plrAdded)

you meant this

if u are wondering why my code format is broken im using the forums code sorry i cant use studio yet

I’m having trouble saving a value in datastor2, I’ve worked with it a few times, but I don’t know what I’m doing wrong here are some scripts that I use the sited value (StageSave_v3)

Sctipt of DevProduct:

local DataStore = require(1936396537)

DataStore.Combine("SkipsSave_V3")

local MarketplaceService = game:GetService("MarketplaceService")

function getPlayerFromId(id)
for i,v in pairs(game.Players:GetChildren()) do
	if v.userId == id then
		return v
	end
end
return nil
end

MarketplaceService.ProcessReceipt = function(receiptInfo)
local productId = receiptInfo.ProductId
local playerId = receiptInfo.PlayerId
local player = getPlayerFromId(playerId)
local productName 

local SkipsSave  = DataStore("SkipsSave_V3", player)

if productId == 955834342 then
SkipsSave:Increment(1,0)
end

if productId == 955834530 then
SkipsSave:Increment(5,0)
end

if productId == 955835662 then
SkipsSave:Increment(10,0)
end

return Enum.ProductPurchaseDecision.PurchaseGranted		
end

Script of TextLabel in StarterGui (Script):

local DataStore = require(1936396537)

local StageText = script.Parent

local player = script.Parent.Parent.Parent.Parent.Parent.Parent

DataStore.Combine("SkipsSave_V3")

local SkipsSave = DataStore("SkipsSave_V3", player)

local function UpdateSkips(Value)

StageText.Text = "Skips: "..Value

end

UpdateSkips(SkipsSave:Get(0))

SkipsSave:OnUpdate(UpdateSkips)

Script To Do “Skip Stage”:

local DataStore = require(1936396537)

local player = script.Parent.Parent.Parent.Parent.Parent.Parent
local Bases =  workspace:WaitForChild("Bases")

DataStore.Combine("SkipsSave_V3","StageSave_V3")

local SkipsSave  = DataStore("SkipsSave_V3", player)
local StageSave  = DataStore("StageSave_V3", player)

for i,v in pairs(Bases:GetChildren()) do
NumberOfStages = i
end

local Debaunce = false
script.Parent.MouseButton1Click:Connect(function()
if Debaunce == false then
Debaunce = true
if SkipsSave:Get(0) > 0 then 
if StageSave:Get(1)<= NumberOfStages then
	SkipsSave:Increment(-1,0)
	StageSave:Increment(1,1)
end
else
	local ItemID = 955834342
	game:GetService("MarketplaceService"):PromptProductPurchase(player,ItemID)
end
wait(1)
Debaunce = false
end
end)

the datastore2 mentioned are working correctly, only the one (SaveStage_V3) that is not saving correctly, when I’m in the game it adds the value correctly (Updates the text) but when I leave and enter the game again it simply resets the value

sorry if this is difficult to understand, is that I really can’t explain it very well …

  1. You are not using Combine right. You are just listing the keys you use, but are not providing a master key. Please read the documentation.
  2. The DataStore2 model is deprecated. Please use the GitHub release.

umm @Kampfkarren how do u save items in table

does this how it works

1.do a for loop in the Get() function
2.the loop check every item in the folder
3.inserts the items in the table inside the loop
4. simply set the table

I cannot insert the github file
I tried dragging it in studio but the cursor changes to :x: icon
I have also tried opening it as a file

Edit: nvm it worked by changing the extension of the file to .rbxl

do you save tables in datastore2 like saving it from datastores?

This was already stated, yes you can

Is it stated that string values can be saved like normal values but i would like to put the items name in to the value

1 Like

I got some questions. I’m pretty insecure in some points.

  1. Do you have to use :Increment() when updating Coins? I normally just do something like Coins.Value = Coins.Value + Increment(When using this method Coins don’t seem to be saved, when not using any other function)
  2. When do I have to use :Save(), .SaveAll()? It seems like data is also saving when not using this function (When e.g. using :Increment())
  3. :Set() sets you stat to a specific amount, :Increment() adds a specific amount, right?
  4. When is it recommended to make a backup and how to use it?
  5. I made a simple leaderstat script that adds 50 Coins every time the player joins.
local SStorage = game:GetService("ServerStorage")

local Modules = SStorage:WaitForChild("Modules")
local DataStore2 = require(Modules.DataStore2)

local StarterCoins = 0

DataStore2.Combine("Data","Coins","Speed")

local function LoadLeaderstats(Player)
	local CoinsData = DataStore2("Coins",Player)
	local SpeedData = DataStore2("Speed",Player)
	
	local Leaderstats = Instance.new("Folder")
	Leaderstats.Name = "leaderstats"
	Leaderstats.Parent = Player
	 
	local Speed = Instance.new("NumberValue")
	Speed.Name = "Speed" 
	Speed.Parent = Leaderstats
	
	local Coins = Instance.new("IntValue")
	Coins.Name = "Coins"
	Coins.Parent = Leaderstats

	local function UpdateCoins(UpdatedValue)
		Coins.Value = CoinsData:Get(UpdatedValue)
	end
	
	local function UpdateSpeed(UpdatedValue)
		Speed.Value = CoinsData:Get(UpdatedValue)
	end
	
	UpdateCoins(StarterCoins)
	UpdateSpeed(0)
	
	CoinsData:OnUpdate(UpdateCoins)
	SpeedData:OnUpdate(UpdateSpeed)
	
	CoinsData:Increment(50)
end

game.Players.PlayerAdded:Connect(LoadLeaderstats)

Am I using DataStore2 correctly? Can I somehow put UpdateCoins() and UpdateSpeed() in one function or do I have to write such a function for every single stat?

  1. How to save tables, strings etc.

Any help is appreciated :smiley:

1 Like