Datastore in one value doesn't work properly

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    Working datastore in one value
  2. What is the issue? Include screenshots / videos if possible!
    Okay so how i made a shop, and every item has a ID. This is saved in the server storage. The ID is just a identifier and the data is stored as children.
    The ID and its data
    Here are the scripts that handle it:
local ItemClass = "Boosters"

This script requests all the data for the shop

ReplicatedStorage.ClientEvents.GetItems.OnServerEvent:Connect(function(plr, ItemClass)
	local count = 100
	for _,v in pairs(ServerStorage.ShopItems:GetChildren()) do
		if v.ItemClass.Value == ItemClass then
			local Clone = plr.PlayerGui.GarageUI:FindFirstChild(ItemClass).ScrollingFrame.ExampleButton:Clone()
			Clone.Name = v.ItemName.Value
			Clone.ID.Value = string.gsub(v.Name, "ID", "")
			Clone.Parent = plr.PlayerGui.GarageUI:FindFirstChild(ItemClass).ScrollingFrame
			Clone.Visible = true
			Clone.Image = "" ..v.ItemImage.Value
			count = count - 1

This is the script that gets all the information and sends it to the player.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local BuyButton = script.Parent.BuyButton
local BoostAmounte = script.Parent.BoostAmount
local CloseButton = script.Parent.CloseButton
local ItemName = script.Parent.ItemName
local ItemDescription = script.Parent.ItemDescription
local Preview = script.Parent.ViewportFrame
local frame = script.Parent
local Id = 0
local Classname = ""
frame.Visible = true
frame.Position =, 0,1.2, 0)
ReplicatedStorage.ClientEvents.ReturnItemData.OnClientEvent:Connect(function(Price, Name, Description, ID, ClassName, MeshId, MeshTexture, Orientation, BoostAmount)
	Classname = ClassName
	Id = ID
	BoostAmounte.Text = "Boost Amount: " .. tostring(BoostAmount)
	Preview.PreviewPart.Orientation = Orientation
	--Preview:FindFirstChild("Camera").CFrame =, 0, 0),,))
	Preview.PreviewPart.Mesh.MeshId = MeshId
	Preview.PreviewPart.Mesh.TextureId = MeshTexture
	frame:TweenPosition(, 0,0.274, 0))
	BuyButton.Text = "Buy for ".. Price .."$"
	ItemName.Text = Name
	ItemDescription.Text = Description

This is the script that gets the item data and shows a buy popup.

ReplicatedStorage.ClientEvents.BuyItem.OnServerEvent:Connect(function(plr, ID, ItemClass)
	local Name = "ID" .. ID
	local Item = ServerStorage.ShopItems:FindFirstChild(Name)
	print("Requested to buy item: " .. Item.ItemName.Value .. ". The ID is: " .. tostring(ID) .. ". The item costs: " .. tostring(Item.ItemPrice.Value).. " coins. The item is in the ".. Item.ItemClass.Value .. " Class.")
	local boostervalue = game:GetService("ServerStorage").PlayerData:WaitForChild(plr.Name):FindFirstChild(ItemClass)
	local Equipped = game:GetService("ServerStorage").PlayerData:WaitForChild(plr.Name):FindFirstChild("EquippedBoosters")
	if boostervalue.Value:match(tostring(1) .. ",") or boostervalue.Value:match("," .. tostring(ID) .. ",") then
			print("Already owned!")
		Equipped.Value = ID
			print("Not owned!")
			local Name = "ID" .. ID
			local Item = ServerStorage.ShopItems:FindFirstChild(Name)
			local Price = Item.ItemPrice.Value
			if plr.leaderstats.Coins.Value >= Price then
				print("Player has enough coins!")
				plr.leaderstats.Coins.Value = plr.leaderstats.Coins.Value - Price
				print("Transaction made!")
				Equipped.Value = ID
					boostervalue.Value = boostervalue.Value .. ID .. ","
			if Equipped then
				Equipped.Value = ID
				print("Not enough coins!")

This is the script that detects if the item is already owned or not. Its this one i need help with because sometimes if you already have for example item 2 and you try to buy it then it just makes the datastore value 1,22 (every comma is a new ID)

You shouldn’t rely on value objects. It’s better to use tables and have the table indexed as an associative array, also known as a dictionary.

The dictionary key would for example be [“1”] and the value would be a dictionary containing its own keys with values. All it requires from you then is to store it all in a ModuleScript and call the right keys to access each pairs information.


I already fixed it, i removed the boostervalue.Value:match(tostring(1) .. ",")