How to add array compatability in Storage System?

Hello! For my game I have implemented a DataStorage system. How it works is that it has a folder of the User’s data, with ValueObjects to hold the parameters. Here is a visualization of it:
image
Each ‘attribute’ is stored as its own Instance. However, that is not ideal for what I am planning for: An Inventory System.

Here is the source of my DataManager script:

local RepStore = game:GetService("ReplicatedStorage")
local SvrStore = game:GetService("ServerStorage")
local DatStore = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local PlayerDataFolder = RepStore.PlayerData

local InfoStore = DatStore:GetDataStore("PlayerData")
local ToCall = game.ServerStorage.Events.DataCall

local ServerStore = DatStore:GetDataStore("ServerStore")

local CurFormat = {"Level","Token","Xp","Coin","Playtime","Streak"} -- the default storage variables
local Conversions = {Score="Xp"} -- converts old storage system into new

function UnloadPlayerData(Player)
	
	local IDList = ServerStore:GetAsync("IDlist")
	if not IDList then IDList = {} end
	if not table.find(IDList,Player.UserId) then
		table.insert(IDList,Player.UserId)
		ServerStore:SetAsync("IDlist",IDList)
	end
	local PlayerID = Player.UserId
	local suc, err = pcall(function()
		local PlayerData = InfoStore:GetAsync(PlayerID)
		if not PlayerData then
			warn("data empty")	
			PlayerData = {}		
			for i, v in pairs(CurFormat) do
				PlayerData[v] = 0
			end
		end
		local PlayerFolder = Instance.new("Folder")
		PlayerFolder.Name = PlayerID
		PlayerFolder.Parent = PlayerDataFolder
		
		
		for i, v in pairs(CurFormat) do
			if not PlayerData[v] then
				PlayerData[v] = 0
			end
		end
		for i, v in pairs(PlayerData) do
			if Conversions[i] then
				local Conv = Conversions[i]
				PlayerData[Conv] = v
				PlayerData[i] = nil
			end
			if not table.find(CurFormat,i) then
				PlayerData[i] = nil
			end
		end



		for store, data in pairs(PlayerData) do
			local IntHolder = Instance.new("IntValue")
			IntHolder.Name = store
			IntHolder.Value = data
			IntHolder.Parent = PlayerFolder
		end

	end) if not suc then warn(err) end
end

function PackPlayerData(Player)
	local PlayerID = Player.UserId
	if PlayerID then
		local PlayerFolder = PlayerDataFolder:FindFirstChild(PlayerID)
		local success, err = pcall(function()
			if PlayerFolder then
				local PlayerData = {}

				for i, v in pairs(PlayerFolder:GetChildren()) do
					PlayerData[v.Name] = v.Value
				end

				InfoStore:SetAsync(PlayerID,PlayerData)
			end
		end)
		if success then
			PlayerFolder:Destroy()
		else
			warn(err)
		end
	end
end

function TranslateCall(callData)
	local suc, err = pcall(function()
		for i, v in pairs(callData) do
			local PlrId = v.PlrId
			local Ttype = v.Type
			local value = v.Value
			local LPlrFol = PlayerDataFolder[PlrId]
			local SVal = LPlrFol[Ttype]
			SVal.Value += value
		end
	end) if not suc then warn(err) end
end

Players.PlayerAdded:Connect(UnloadPlayerData)
Players.PlayerRemoving:Connect(PackPlayerData)
ToCall.Event:Connect(TranslateCall)

I have a few ideas on how this may work. Having an ‘Inventory’ folder under the Player’s Data Folder that stores the ID and amount of the objects that the User has in their inventory. But I am sure there is an easier way to store it.

1 Like

I have rewritten my code in a new format. Now in the Player’s data folder, two folders are stored; Currency and Inventory, Curreny includes the IntValues of each currency type, it holds the amount of that Currency that the player has. Inventory includes a list of IntValues of what the Player has, the IntValue names are the name of the object (just like currency IntValue names) and stores the amount of the object the player has in that IntValue.

I gone through all my scripts that rely on the Data Format and re-scripted them to support the new format. Of course I made it so players with out-dated Data Formats have their data reformated with minimal to zero data loss.