Saving multiple values to one Datastore?

Hello,

I’m very new to backend programming and I have an issue that I can’t seem to get my head around.

In my game, I have 3 developer products that gives players a speed boost. The difference between the products are the timers. Meaning the first product can have a 30 seconds timer, second product can have 1 minute timer and the third can have a 2 minute timer.

The point of me trying to save these products in a datastore is so players can purchase the developer products and use them whenever they feel like it. (so the timer doesn’t active instantely)

I do have a setup when players join the game:

if not DataStore:GetAsync(Plr.UserId) then 
	DataStore:SetAsync(Plr.UserId, {})
end

Using SetAsync overrides the previous save, but how would I go on and save multiple values in the same datastore so when players use one of the developer products, I can just remove it from the datastore?

There are probably more efficient ways to pull the saving methods off but I am still trying to get my head around on how all of this works.

2 Likes

DataStore:SetAsync(Plr.UserId, table) --saves “table” to the player’s data
data = DataStore:GetAsync(Plr.UserId, table) --retrieves the table and sets it to “data”

then you can do:

data[1] --retrieves first value in the saved table
data[2] --retrieves second value
etc

What I like doing is to use attributes when saving/loading data, so for example when someone leaves the server it takes all their attributes, saves it to a table, and then saves that table to the player’s data. Then when they join the game again it takes that tables, and you can do:

player:SetAttribute(“AttributeName”, data[1])

2 Likes

Datastore saving is all about giving a table to roblox server. And loading is to get the table you have saved before. A table is container that can store multiple values, but you can’t store objects(Instances). Also, you will have to make your table readable. Or the table will just look like a messy list and don’t know what each data stands for.

This is a table(Dictionary) that shows you how to make a readable table data:

local Data =
{Score = 0,
Lifes = 0,
HighScore = 0}

This is a unreadable table data that will make you go crazy to find what does each value stand for.

local Data = {0,0,0}

The readable table(Dictionary) data allows you to find the exact data you need directly.

If you want to read the Score data you just need to write:

local Score = 0
Score = Data[Score]
1 Like

Just do it simple.

local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("DataStoreValues")
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(Player)
	
	local leaderstats = Instance.new("Folder", Player) --making leaderstats
	leaderstats.Name = "leaderstats"

	local Value1 = Instance.new("NumberValue", leaderstats) --making value1
	Value1.Name = "Value1"

	local Value2 = Instance.new("NumberValue", leaderstats) --making value2
	Value2.Name = "Value2"

	local value1Data --giving them a variable
	local value2Data --giving them a variable
	
	local s, e = pcall(function()
		value1Data = DataStore:GetAsync(Player.UserId.."-Value1") or 0 --check if they have data, if not it'll be "0"
		value2Data = DataStore:GetAsync(Player.UserId.."-Value2") or 0--check if they have data, if not it'll be "0"
	end)
	
	if s then
		Value1.Value = value1Data --setting data if its success
		Value2.Value = value2Data --setting data if its success
	else
		game:GetService("TestService"):Error(e)  --if not success then we error it to the console
	end
	
end)

Players.PlayerRemoving:Connect(function(Player)
	local s, e = pcall(function()
		DataStore:SetAsync(Player.UserId.."-Value1", Player.leaderstats.Value1.Value) --setting data
		DataStore:SetAsync(Player.UserId.."-Value2", Player.leaderstats.Value2.Value) --setting data
	end)
	if not s then game:GetService("TestService"):Error(e) end --if not success then error
end)

Otherwise, use GreenwichDB.

1 Like

Something like this?

local function SaveV9(Plr,Item)
	local Data = V9DataStore:GetAsync(Plr.UserId)
	local s,e = pcall(function()
		Data[Item.Name] = Data[Item.Value] 
		V9DataStore:SetAsync(Plr.UserId,Data)
	end)
	if not s then 
		TestService:Error(e)
	else
		print("Success!")
	end
end

local function CreateV9Item(Plr,Time)
	local v9Value = CreateValue("V9",Time)
	local v9Folder = Plr:WaitForChild("PlayerStats"):WaitForChild("V9")
	v9Value.Parent = v9Folder
	SaveV9(Plr,v9Value)
end

What I do is I create IntValues in the CreateV9Item function, place them in a folder and then go on with the saving process. So pretty much I give the table the Value name and the actual value from the IntValue

For clarification, V9 is just the name of the IntValue.

1 Like

Well, you should try it and see if it works.

1 Like

Yeah, didn’t work. It’s not saving the data. Really strange.

1 Like

Have you enabled Studio Access to API Services in game settings? If your code is written correctly, this might be the cause when you try to test the datastore in studio.

If you want to try your datastore in studio, you have to enabled Studio Access to API Services in game settings.

1 Like

Are you sure you activated the function? Please show us your whole code and your errors if you have any.

1 Like

Absolutely.

Here is the full code.
What I am trying to do is whenever a product is purchased, an IntValue gets added to the player.
Name of the intValue is the product name and the value is the actual timer since each product have different timers.

function CreateValue(Name,Value) -- I create the actual IntValue
	local intValue = Instance.new("IntValue")
	intValue.Name = Name
	intValue.Value = Value
	return intValue
end

local function SetData(Plr,Value) -- I apply the IntValue name & value to the Datastore
	local Data = V9DataStore:GetAsync(Plr.UserId)
	Data[Value.Name] = Value.Value
	V9DataStore:SetAsync(Plr.UserId,Data)
end

local function ValueSetup(Plr,Value) -- This happens when a product is purchased. Value = time of the product (the timer)
	local v9Value = CreateValue("V9",Value)
	local playerStats = Plr:WaitForChild("PlayerStats")
	v9Value.Parent = playerStats:WaitForChild("V9")
	SetData(Plr,v9Value)
end

Now what the issue is that, the latest saved data overwrites by the new data. So when I use SetAsync, whatever previous data was there before gets swapped out by the new data.

1 Like

Yeah. It seems to be saving now, looks like it was a glitch before but I still have the original issue.
I posted it here: Saving multiple values to one Datastore? - #10 by ProZealous

1 Like