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

This is the code i use, is it incorrect?

cashStore:Increment(100,starterValueC) -- starterValueC is 100

DataStore2 Got broke

i simply get this error

if u want my code just ask me but i promise its innocent im legit 100% know that ur code is broken

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", "Capacity")

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 folder = Instance.new("Folder")
	folder.Name = "leaderstats"
	folder.Parent = player
	
	-- 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)

For now, ill wait for you and wait for solutions

On its own, no, this is correct.

2 Likes

You are not using Combine right. You need a master key as the first argument, but you don’t have one.

It’s not.

it would be clear that number value was the error

i used this without master keys and works but now it gets errors

And if placed in a module and called everytime a purchase receipt is finished? Would that break it?

I’m not sure what you mean, but if you call that in a process receipt code it’ll be fine.

When I add new stuff into my table, how I can make so existing players in datastore, gets the new key in table? If you can, could you please provide an example

Read the documentation for GetTable. Remember that using one key that’s a large table is an anti pattern and should not be used in DataStore2, if that’s your use case.

So, like instead of using get(table) I should use :GetTable(table). Correct me if I am wrong.

Yes, that is correct.

1 Like

That is what i am doing, although another function for another kind of currency is also in the same module. Would this effect it? And would you like to see the source code?

That doesn’t sound like it should affect anything. You should just test it and see what happens.

Hello @Kampfkarren,

I have a question about the DataStore2 Combine.

Do DataStore2.Combine() have maximum amounts of keys like I can add more individual keys without worried about the limits or slowing the DataStore2 down?

For example, this has 19 keys combined with the master key
Also it is necessary to combine the tables as well?

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

The limit is just until your total data hits the 260k characters limit. That being said, that happening is extremely rare unless you’re doing something crazy.

2 Likes

I understand, thank you.
I’m going to adding more data with int values etc.

I have. Here are some screenshots.

Before tokens purchase:
Screen Shot 2020-02-18 at 2.29.37 PM Screen Shot 2020-02-18 at 2.29.47 PM

After tokens purchase:
Screen Shot 2020-02-18 at 2.30.00 PM

Before cash purchase:
Screen Shot 2020-02-18 at 2.30.14 PM Screen Shot 2020-02-18 at 2.30.19 PM

After cash purchase:
Screen Shot 2020-02-18 at 2.30.29 PM

Source code(Main Script):

local MPS = game:GetService("MarketplaceService")
local Module = require(script.Module)

MPS.ProcessReceipt = function(receiptInfo)

 local plr = game.Players:GetPlayerByUserId(receiptInfo.PlayerId)

if receiptInfo.ProductId == 956944872 then 
    Module.Buy100(plr,"Cash")
elseif receiptInfo.ProductId == 953110738 then
    Module.Buy100(plr,"Tokens")
end
end

Source code(Module Script):

local DataStore2 = require(game.ServerScriptService.DataStore2)
local starterValueT = 5
local starterValueC = 100
DataStore2.Combine("MainStats","tokens", "cash")
local module = {}
 module.Buy100 = function(plr,currency)

local tokensStore = DataStore2("tokens",plr)

local cashStore = DataStore2("cash",plr)

if currency == "Cash" then
	cashStore:Increment(100,starterValueC) -- starterValueC is 100
elseif currency == "Tokens" then
	tokensStore:Increment(100,starterValueT)
end
end
return module
2 Likes

Sorry if there was any confusion. I meant to report a bug.

You never return Enum.ProductPurchaseDecision.PurchaseGranted on success, or Enum.ProductPurchaseDecision.NotProcessedYet on failure. Roblox will keep calling your function for 3 days until it returns PurchaseGranted.

Not sure what else is up but, with indentation, you can see an issue better.

local Players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
local module = require(script.Module)

local products =
{
    [956944872] = "cash",
    [953110738] = "tokens"
}

function MarketplaceService.ProcessReceipt(receipt)
    local client = Players:GetPlayerByUserId(receipt.PlayerId)
    if not client then -- Probably left/disconnected
        return Enum.ProductPurchaseDecision.NotProcessedYet
    end

    module.Buy100(client, products[receipt.ProductId])
    return Enum.ProductPurchaseDecision.PurchaseGranted
end

Also notice I put the product ID’s in a mapping of the ID to what currency they correspond to. It is there to prevent hardcoding elseif’s.

You would do similar for the buy 100 module.

local starting_values =
{
    coins = 100,
    tokens = 5
}
module.Buy100 = function(client, currency)
    DataStore2(currency, client):Increment(100, starting_values[currency])
end

Again, used tables to avoid hardcoding.

2 Likes

Thank you so much. I will test this later :slight_smile:

1 Like