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

Thanks. Would it be possible to save multiple data in a table instead of saving them individually?

2 Likes

I’m not sure what you mean, you just use :Set with a table as the argument and it’ll just save that.

2 Likes

Thank you for this! My game Ore Tycoon 2 is now using DataStore2 :smiley:

4 Likes

@Kampfkarren
Quick question, so when attempting to add data to a table I noticed that when using set it removes the original value from a table. I’ll have a example below:

game.Players.PlayerAdded:Connect(function(Player)
	DataStore2.Combine("DJLKAJDLAJDLKASJ%_1212_123293W_#w204", "Cash", "Candy", "Costumes", "Bags", "Pets")

-- Add item to players inventory
local newTable = DataStore2("Costumes", Player):Get({"Costume1"})
table.insert(newTable, "Costume3")
DataStore2("Costumes", Player):Set(newTable)

print(unpack(DataStore2("Costumes", Player):Get({"Costume1"})))

The output prints:

"Costume3"

(Where did Costume1 go?)

5 Likes

I have code that looks just like that to no issue. Can you try using table.foreach(ds2:Get(), print) instead of the unpack and see if it does the same thing?

2 Likes

Important bug fix

It’s been found that DataStore2’s data store error recovery was buggy and broken. It is highly recommended you update your DataStore2.

New version (but you can also just get the file from GitHub): Release DataStore2 v1.1.2 · Kampfkarren/Roblox · GitHub

The free model is being updated now.

4 Likes

Sorry for the late reply, but thanks this helped. I had a temporary fix of just using the :GetTable() method.

1 Like

Added Dungeon Quest by vCaffy as a success story!

3 Likes

Whats the best way to wipe a players data or reset ALL of the data for all players? In another module i used, there was a string that served as the “version” and by changing that string, all the data would be stored under that scope. Do we have something like this for DataStore2?

thanks!

2 Likes

To reset all data for all players, just change the names of the keys. If you use combined data stores, you can just change the master key and you’re done.

5 Likes

Got it now, thanks so much! Appreciate all you have done here and the support you give :slight_smile:

2 Likes

OnUpdate method does not seem to be firing when the Increment method is called.

2 Likes

Are you sure? I just tested and it works fine for me.

3 Likes

I wish I had a cleaner example to share, but this is my code as it is:

--// INITIALIZE OBJECTVALUE
function GuiService:InitilizeValue(player,key)
  local playerFolder = ReplicatedStorage.GuiObjectValues:FindFirstChild(player.UserId)

  local thisStore = DataStore2(key,player)
  local thisValue = thisStore:Get()

  print("Creating new ObjectValue: ")
  local newValue = Instance.new("NumberValue")
  newValue.Parent = playerFolder
  newValue.Name = key
  newValue.Value = thisValue

  thisStore:OnUpdate(print(key,"updated")) -- for testing, doesnt fire when i use :Increment elsehere in the code, though the DataStore does update
end

the goal of this code is to take any key passed to it, then create a ObjectValue in ReplicatedStorage whose value is updated whenever the DataStore key is updated. The print is just for testing, I have another function that will do the work if I can get it to fire.

This OnUpdate method does fire once when this function is called, but after that when Increment the store elsewhere in the code, it does not fire.

For reference here is the code that uses :Increment on those keys:

--// CHECK IF BACK IS FULL AND ADD ITEM IF NOT
function Backpack:CheckAddItem(key,value)
    local backpackKey = ("backpack_" .. key)
    local backpack_Max = DataStore2("backpack_Max",self.Player):Get(BackpackDefs.Defaults.Max)
    local backpack_Total = DataStore2("backpack_Total",self.Player):Get()

	local isAdded
    if backpack_Total < backpack_Max then
        DataStore2(backpackKey,self.Player):Increment(value)
		isAdded = true
    else
		isAdded = false
    end
    return isAdded
end

Sorry if I did this completely wrong, learning how to use DataStore2 as I go.

Thanks!

6 Likes

Your issue is this:

thisStore:OnUpdate(print(key,"updated"))

You’re calling OnUpdate with the return of print, not an actual function. Change that to:

thisStore:OnUpdate(function()
    print(key, "updated")
end)
8 Likes

thanks for your patience, works perfectly now :slight_smile:

4 Likes

I have a question Kampfkarren:

in my game I use various scripts to get my code more organized, so to avoid all the hassle of repeating over and over again DataStore2.Combine in each file, I have done the following:

-In a “Datastores” script I declare all the combinations in a global variable:

_G.DataStore2 = require(game.ServerStorage.MainModule)
_G.DataStore2.Combine(“AntsMasterKey”, “Cash”) – player money
_G.DataStore2.Combine(“AntsMasterKey”, “Gems”) – player’s gems (premium money)
_G.DataStore2.Combine(“AntsMasterKey”, “Sugar”) – sugar (what you sell for money)

-Then in another script file (like the one that takes care of setting the player when he connects) I can use this:

Players.PlayerAdded:Connect(function(player)
–set the datastore value
local coinStore = _G.DataStore2(“Cash”, player)
etc…

My question is: Is this right, or can it lead to problems? Is there a more efficient way to do it?

Thank you very much :smiley:

5 Likes

_G is almost always wrong, you can use it before it is initialized, it causes coupling, it obfuscates definitions, etc. The best way is just requiring DataStore2 directly. You only need to call Combine for a key once, and you can even have each script call Combine for what they need. For example, in a coins script you might have:

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

In another script for inventories, you might have:

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

etc

8 Likes

What if i have two scripts touching the same value? Should i call .Combine on each script that touches the value?

2 Likes

You only need to call Combine on a key once, but it wouldn’t hurt.

4 Likes