DataStore Saving

I was wondering how I would save say a title that the player has bought from a shop to the datastore, and every time the player joins back whatever items they had equipped are put back on the player.

I was thinking of putting a folder in every player and having a bool value of every item and if they have bought the item then I would change the bool value to true, and save the bool values to the data store, would this work and is there a better way to do this.

2 Likes

Well assuming you are buying the item as in a gamepass cant you just check if the user owns that gamepass?

1 Like

its not a gamepass its from a ingame shop

2 Likes

its like epic minigames, where you buy the titles from the shop, and it will save it

1 Like

The BoolValue method would be relatively inefficient. Instead, I’d recommend doing this:

Create a folder inside of the player called OwnedTitles, and do the following:

When the player buys a title, create a StringValue. Then, set its Value property to the title’s Text, e.g “Adventurer”, or “Epic”. Then put this value inside of the OwnedTitles folder. I’d create a function to simplify this process, as you’ll need to create a TitleName value again later on in this post. It would look like this:

local function createTitleName(folder, nameOfTitle)
	local titleName = Instance.new("StringValue")
	
	titleName.Value = nameOfTitle
	titleName.Parent = folder
end

Now, whenever the player leaves, use :GetChildren() on their folder, and add each of the StringValue’s Value properties to a table, like this:

local ownedTitles = {}

for _, obj in ipairs(OwnedTitlesFolder:GetChildren()) do
	table.insert(ownedTitles, obj.Value)
end

Now save this table using DataStoreService.

When the player joins, load this table using DataStoreService. Loop through the table like this:

for _, titleName in ipairs(loadedOwnedTitlesTable) do
    createTitleName(ownedTitlesFolder, titleName)
end

Keep in mind that most of this code has undefined variables, so you’ll need to define them yourself.

3 Likes

sry for not replying for a while, I was wondering if there was any way to test the datastore service in studio instead of ingame, also I was hoping you could help me solve this bug, so what the script does right is it will give the player a folder then when they walk on a part it will put a string value in the folder, then when they leave it should save and then when they join it should load the string value again, but either the saving or the loading isn’t working, do you see what could be the problem?

local titles

local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("dataStore")

local function createTitleName(folder, value, name)
	local titleName = Instance.new("StringValue")

	titleName.Value = value
	print(titleName.Value)
	titleName.Name = name
	print(titleName.Name)
	titleName.Parent = folder
	print("Created Title")
end

game.Players.PlayerAdded:Connect(function(player)
	titles = Instance.new("Folder")
	titles.Name = "Titles"
	titles.Parent = player
	print(titles.Name)

	local data
	local success, errormessage = pcall(function()
		data = dataStore:GetAsync(player.UserId.."-Titles")
		print(data)
	end)

	if success then
		titles = data
		print(data)
		
		for i, v in ipairs(data) do
			createTitleName(titles, data(i).Value, data(i).Name)
		end
	else
		print("There was an error whilst getting your data")
		warn(errormessage)
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	local ownedTitles = {}

	for i, v in ipairs(titles:GetChildren()) do
		table.insert(ownedTitles, v.Value)
	end
	
	local success, errormessage = pcall(function()
		dataStore:SetAsync(player.UserId.."-Titles", ownedTitles:GetChildren())
	end)

	if success then
		print("Player Data successfuly saved!")
	else
		print("There was an error when saving data")
		warn(errormessage)
	end
end)

Click “Game Settings”, then “Security” (or permissions, not sure), and then “Enable Studio Access to API Services”.

There are a few problems.

image

This will error, because ownedTitles is a table that doesn’t have a GetChildren function. If you remove the :GetChildren() call, the saving will be good to go.

Screenshot 2021-07-23 at 22.59.27

You should also remove this, because titles is the Title folder, and data is the retrieved data, either being an array of strings or nil. You’ll need the title folder in the following loop, so replacing it with an array would mean that you’re not going to be able to refer to it.

Before running this loop, check that the data isn’t nil to avoid errors. As for data(i).Value, you shouldn’t use normal brackets for indexing a table. Instead you should do data[i].Value, however, in this case you shouldn’t be indexing.

(Recap: data is a numerical array of strings)
i, v in pairs loops’ i is the index (in this case a number, in the order of 1, 2, 3, etc), and v is the value (in this case a string - a title).

This means that you can simply pass v to the createTitleName function instead of data[i]. As for data[i].Name, you can remove that.

Also remove the part of the createTitleName function that sets the name - setting the name of the values isn’t important, it’s essentially just for decoration.

1 Like