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

datastore2 is just a helpful layer, it still uses the datastore service, so normally you would do this without datastore2

ds:SetASync("Some_Datastore", someTable)

I assume datastore2 is the same way (hopefully), there is no need to loop through multiple datastores nor have more then 1 line of code for it.

I’ve been working on an inventory, and I’m fairly new with tables and such.
When using Datastore2 with a table, I get the error

ServerScriptService.DataStore2:479: DataStore2() API call expected {string dataStoreName, Instance player}, got {table, Instance}

Would it be possible to convert a table into a string, and if so how?

Here is my data handler, line 32 is where the error comes from

local players = game:GetService("Players")

local DS2 = require(game.ServerScriptService.DataStore2)

game.Players.PlayerAdded:Connect(function(player)
	local saveslottimer = Instance.new("NumberValue", player)
	saveslottimer.Name = "SaveSelector"
	saveslottimer.Value = 0
	repeat
		wait()
	until saveslottimer.Value == 1 
	
	wait(2)
	
	local saveslot = player.SaveSlot
	
	
	local stats = Instance.new("Folder", player)
	stats.Name = "Stats"
		
	local money = Instance.new("NumberValue", stats)
	money.Name = "Money"
	
	local inv = Instance.new("Folder", player)
	inv.Name = "Inventory"
	
	local invdata = {inv:GetChildren()}
	
	DS2.Combine(saveslot.Value, "Money", invdata)
	
	local moneystore = DS2("Money", player)
LINE 32	local invstore = DS2(invdata, player)
	
	for i,v in pairs(inv:GetChildren()) do
		table.insert(invdata, v.Value, v.Name)
	end
	
	money.Value = moneystore:Get(500)
	
	money.Changed:Connect(function()
		DS2("Money", player):Set(money.Value)
	end)
end)
1 Like

How do you think you’d use a table as a key? I’m not sure how to help you out other than that this is intentional behavior.

I’ve just realized how dumb I am with this. I still am not sure exactly how to save the table itself, but I think I can figure that out. Sad thing is, I didn’t even know that was the key this whole time (I know, I’m stupid)

Ok, after trying a few things, I’ve decided to return.
I THINK I have saving the table, but there is no way to test because I don’t know how to load the table. I would need some way to load in the value and name of each NumberValue in the inventory, here is the script.

local players = game:GetService("Players")

local DS2 = require(game.ServerScriptService.DataStore2)

game.Players.PlayerAdded:Connect(function(player)
	local saveslottimer = Instance.new("NumberValue", player)
	saveslottimer.Name = "SaveSelector"
	saveslottimer.Value = 0
	repeat
		wait()
	until saveslottimer.Value == 1 
	
	local saveslot = player.SaveSlot
	
	
	local stats = Instance.new("Folder", player)
	stats.Name = "Stats"
		
	local money = Instance.new("NumberValue", stats)
	money.Name = "Money"

	local er = Instance.new("NumberValue", stats)
	er.Name = "Eridium"
	
	local level = Instance.new("NumberValue", stats)
	level.Name = "Level"
	
	local exp = Instance.new("NumberValue", stats)
	exp.Name = "Experience"
	
	local maxexp = Instance.new("NumberValue", stats)
	maxexp.Name = "MaxExperience"
	
	local inv = Instance.new("Folder", player)
	inv.Name = "Inventory"
	
	DS2.Combine(saveslot.Value, "Money", "Eridium", "Level", "Experience", "MaxExperience", "Inventory")
	
	local invholder = {}
	
	local moneystore = DS2("Money", player)
	local erstore = DS2("Eridium", player)
	local levelstore = DS2("Level", player)
	local expstore = DS2("Experience", player)
	local maxexpstore = DS2("MaxExperience", player)
	local invstore = DS2("Inventory", player)
	
	money.Value = moneystore:Get(500)
	er.Value = erstore:Get(0)
	level.Value = levelstore:Get(1)
	exp.Value = expstore:Get(0)
	maxexp.Value = maxexpstore:Get(500)
	
	saveslottimer.Value = 2
	
	money.Changed:Connect(function()
		moneystore:Set(money.Value)
	end)
	er.Changed:Connect(function()
		erstore:Set(er.Value)
	end)
	level.Changed:Connect(function()
		levelstore:Set(level.Value)
	end)
	exp.Changed:Connect(function()
		expstore:Set(exp.Value)
	end)
	maxexp.Changed:Connect(function()
		maxexpstore:Set(maxexp.Value)
	end)
	
	inv.ChildAdded:Connect(function(item)
		table.insert(invholder, item.Name, item.Value)
		invstore:Set(invholder)
	end)
	inv.ChildRemoved:Connect(function(item)
		table.remove(invholder, item.Name, item.Value)
		invstore:Set(invholder)
	end)
end)

simply use :GetTable() 30char

That doesn’t really explain how I would fix it, where would I put :GetTable()? And what would I put inside ()? Just some default Instances?

no the table you are trying to get for example

local TableSave = DataStore2("Table", plr)
local tablelol = {}

TableSave:GetTable(tablelol)

-- try doing something
--then set it

TableSave:Set(tablelol)

my inventory save worked when i did this

Get works perfectly fine with tables. GetTable is for when you want to add new defaults over time. Do not use GetTable if you’re not making use of that functionality.

So how would I do this? I already tried using Get and it didn’t work, I am terrible with tables lol.
My main issue is I don’t know how I would actually make the values from the table it self, would/could I just do

for i,v in pairs(table) do

Or some form of that?

i know how to save tables using DataStore2 and why not try my advice

name your table also different because the script thinks its a service

did u ever try table.insert()

	inv.ChildAdded:Connect(function(item)
		table.insert(invholder, item.Name, item.Value)
		invstore:Set(invholder)
	end)
	inv.ChildRemoved:Connect(function(item)
		table.remove(invholder, item.Name, item.Value)
		invstore:Set(invholder)
	end)

then set it like this YourDataStore:Set(invholder)

before that do this

at the top of your code before the table.insert()

YourDataStore:GetTable(invholder)

you should try a for loop

@Kampfkarren

i cant save any tools unless i add them into the starter pack outside solo play

local DataStore2 = require(game.ServerStorage:WaitForChild("MainModule"))
local DefaultLevel = 1
local DefualtMaxXP = 30

DataStore2.Combine("DATA", "Level", "Gold", "XP", "MaxXP", "Inventory")

function PlrAdded(plr)
	local LevelStore = DataStore2("Level", plr)
	local XPStore = DataStore2("XP", plr)
	local MaxXPStore = DataStore2("MaxXP", plr)
	local GoldStore = DataStore2("Gold", plr)
	local InventorySave = DataStore2("Inventory", plr)
	
	local folder = Instance.new("Folder")
	folder.Parent = plr
	folder.Name = "leaderstats"
	
	local Level = Instance.new("NumberValue")
	Level.Parent = folder
	Level.Name = "Level"
	Level.Value = LevelStore:Get(DefaultLevel)
	
	LevelStore:OnUpdate(function(value)
		Level.Value = value
	end)
	
	local Gold = Instance.new("NumberValue")
	Gold.Parent = folder
	Gold.Name = "Gold"
	Gold.Value = GoldStore:Get(0)
	
	GoldStore:OnUpdate(function(value)
		Gold.Value = value
	end)
	
	local XP = Instance.new("NumberValue")
	XP.Parent = Level
	XP.Name = "XP"
	XP.Value = XPStore:Get(0)
	
	XPStore:OnUpdate(function(value)
		XP.Value = value
	end)
	
	local MaxXP = Instance.new("NumberValue")
	MaxXP.Parent = XP
	MaxXP.Name = "MaxXP"
	MaxXP.Value = MaxXPStore:Get(DefualtMaxXP)
	
	MaxXPStore:OnUpdate(function(value)
		MaxXP.Value = value
	end)
	
	local plr1 = Instance.new("Folder")
	plr1.Name = plr.Name
	plr1.Parent = game.ServerStorage.PlrDATA
	
	local items = Instance.new("Folder")
	items.Parent = plr1
	items.Name = "Items"
	
	local itemstable = {}
	
	InventorySave:GetTable(itemstable)
	
	for i, k in pairs(game.StarterPack:GetChildren() and items:GetChildren()) do
		table.insert(itemstable, k.Name)
	end
	
	InventorySave:Set(itemstable)
	
	for i,v in pairs(itemstable) do
		local cloned = game.ServerStorage.items[v]:Clone()
		
		
		cloned.Parent = plr:WaitForChild("Backpack")
		cloned.Parent = items
		
	end
	
	
end

for _, plr in pairs(game.Players:GetPlayers()) do
	PlrAdded(plr)
end

game.Players.PlayerAdded:Connect(PlrAdded)

Did you mean:

invhold[item.Name] = item.Value

As for removing:

invhold[item.Name] = nil

The ChildAdded and Removed part is where I try to save the inventory, which I don’t even know if that works. Loading would require being able to go through each item in the table, and making a new value for it. The name is the item’s name, and the value is how many you have.

It doesn’t work because you are using table.insert wrong. Please read my reply.

  21:48:57.812 - ServerScriptService.DataHandler:74: attempt to index upvalue 'invholder' (a string value)
	inv.ChildAdded:Connect(function(item)
		invholder[item.Name] = item.Value
		invstore:Set(invholder)
	end)
	inv.ChildRemoved:Connect(function(item)
		invholder[item.Name] = nil
		invstore:Set(invholder)
	end)

Read your error. invholder is a string, not a table. This has nothing to do with DataStore2.