Struggling on what to find as the "Perfect Index"

I’m trying to make a data saving system that will save which tools players have equipped and which attributes each tool has(only attributes im saving are upgrades.)

local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local CollectionService = game:GetService("CollectionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Data = DataStoreService:GetDataStore("monke_d")

local Remotes = ReplicatedStorage.Remotes
local Functions = ReplicatedStorage.Functions
local Items = ReplicatedStorage.Items
local Tools = Items.Tools

local sessionData = {}

local DataStore = {}

function DataStore:Start(player)
	sessionData[player] = {}
	sessionData[player]["Tools"] = {}
end

local function GetParent(tool)
	if tool.Parent:IsA("Model") and Players:GetPlayerFromCharacter(tool.Parent) then
		return Players:GetPlayerFromCharacter(tool.Parent)
	elseif tool.Parent.Parent:IsA("Player") then
		return tool.Parent.Parent
	end
end


local function Upgrades(tool)
	return function(attributeName)
		if attributeName ~= "CurrentUpgrade" then return end
		local att = tool:GetAttribute(attributeName)
		local player = GetParent(tool)
		sessionData[player]["Tools"][1] = {att,tool.Name}
	end
end

function DataStore:CS()
	for i,tool in CollectionService:GetTagged("Tool") do
		tool.AttributeChanged:Connect(Upgrades(tool))
	end
	CollectionService:GetInstanceAddedSignal("Tool"):Connect(function(tool)
		tool.AttributeChanged:Connect(Upgrades(tool))
	end)
end

function DataStore:Init() -- All our tools should save and we should save our upgrade number in sessionData and in attributes
	Players.PlayerAdded:Connect(function(player)
		self:Start(player)
		local key = tostring(player.UserId)
		
		local folder = Instance.new("Folder")
		folder.Name = "leaderstats"
		
		local money = Instance.new("IntValue")
		money.Name = "Money"
		
		local bananas = Instance.new("IntValue")
		bananas.Name = "Bananas"
		
		local fish = Instance.new("IntValue")
		fish.Name = "Fish"
		
		CollectionService:AddTag(fish,"Currency")
		CollectionService:AddTag(bananas,"Currency")
		
		local successFish,resultFish = pcall(function()
			return Data:GetAsync("fish"..key)
		end)
		if successFish and resultFish then
			fish.Value = resultFish
		end
		local successBananas,resultBananas = pcall(function()
			return Data:GetAsync("bananas"..key)
		end)
		if successBananas and resultBananas then
			bananas.Value = resultBananas
		end
		local successMoney,resultMoney = pcall(function()
			return Data:GetAsync("money"..key)
		end)
		if successMoney and resultMoney then
			money.Value = resultMoney
		end
		local successTools,resultTools = pcall(function()
			return Data:GetAsync("tools"..key)
		end)
		if successTools and resultTools then
			print(resultTools)
			for i,v in pairs(resultTools) do print(i,v) end
			for i,v in resultTools do
				sessionData[player]["Tools"][i] = v
			end
			for i,v in pairs(resultTools) do
				local tool = Tools:FindFirstChild(sessionData[player]["Tools"][i][2]):Clone()
				tool:SetAttribute("CurrentUpgrade",sessionData[player]["Tools"][i][1])
				tool.Parent = player.Backpack
			end
		end
		player.CharacterRemoving:Connect(function(character)
			if character.Humanoid.Health <= 0 then return end
			local function FindTools()
				for i,v in player.Backpack:GetChildren() do
					sessionData[player]["Tools"][i] = {v:GetAttribute("CurrentUpgrade"),v.Name}
				end
				local tool = character:FindFirstChildOfClass("Tool")
				if tool then
					sessionData[player]["Tools"][1] = {tool:GetAttribute("CurrentUpgrade"),tool.Name}
				end
				table.sort(sessionData[player]["Tools"],function(a,b) return a < b end)
			end
			FindTools()
			
			local successTools,resultTools = pcall(function()
				return Data:SetAsync("tools"..key,sessionData[player]["Tools"])
			end)
		end)
		bananas.Parent = player
		fish.Parent = player
		money.Parent = folder
		folder.Parent = player
	end)
	Players.PlayerRemoving:Connect(function(player)
		local key = tostring(player.UserId)
		local successMoney,resultMoney = pcall(function()
			return Data:SetAsync("money"..key,player.leaderstats.Money.Value)
		end)
		local successBananas,resultBananas = pcall(function()
			return Data:SetAsync("bananas"..key,player.Bananas.Value)
		end)
		local successFish,resultFish = pcall(function()
			return Data:SetAsync("fish"..key,player.Fish.Value)
		end)
	end)
	self:CS()
end

return DataStore

In a character removing event below I am trying to set the tools in the sessionData table and I’m attempting to sort them.

When I print through the table of tools when I am setting them(SetAsync), it shows all the tools. For example if I have 4 hammers, It will show 4 hammers in the table. The problem is though, when I am getting them(GetAsync), it only shows 1 of that tool(shows if sessionData[player][“Tools”] index is the actual tool when sending to SetAsync).

I know that this is happening because the index for sessionData[player][“Tools”] was a tool(in the script now it is an index. The problem is though when I am setting or changing an upgrade a player has made, I need access to the table index which I can’t use with a number and if I use a tool, only 1 of that tool will show because the instance has been turned into a string in which each tool has the same index.

Update: I’m planning on using serial numbers, I’ll bump this post again if my idea succeeds.

I would personally have one key handle all inventory data (and maybe other general data) and it can have a table of each item in the form of another table that contains full data like item-type and upgrade level. I tend to use ModuleScripts to handle importing and exporting of data as it is more streamlined. I know I did not say a lot but I hope this helps.

I’m thinking of creating serial numbers as indices and adding them onto tools as attributes when they are cloned in the game.

Highly unlikely, but any ideas on how I would counter an issue where an index in sessionData[player][“Tools”] is the same(Runs on server but basically every serial number is local to every player). I am using tool:SetAttribute(“SerialNumber”,math.random(0,1e7)) to create my serial-specific number.

So I just use math.random(0,1e7) and it worked but I’ll make another post on the slight inconvenience that 2 serial numbers for a player’s tools are the same.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.