Looking for Feedback on my Player Data Management System

Hi everyone,

I’ve been working on a system to manage player data using ProfileStore by loleris, and I’d love some feedback on it. The system handles things like saving/loading inventory data and managing player sessions. It works, but I feel like there’s room for improvement, and I want to make sure I’m doing things the right way.

What I Need Help With:

  • Better Practices: Am I using ProfileStore the way it’s meant to be used?
  • General Feedback: Anything else you see that could be improved or cleaned up?
--<Services>--
local runService = game:GetService("RunService")
local players = game:GetService("Players")

--<Modules>--
local profileStoreModule = require(script.Parent:FindFirstChild("ProfileStore"))
local defaultData = require(script.Parent.Default_Data)

--<Variables>--
local playersInventoryFolder = script.Parent.Parent.Parent.Players_Inventories
local inventoryTemplate = playersInventoryFolder:FindFirstChild("Inventory_Temp")


local key = "MainKey"
if runService:IsStudio() then
	key = "StudioKey"
end

local profileStore = profileStoreModule.New(key, defaultData)
local Profiles: {[player]: typeof(playerStore:StartSessionAsync())} = {}



local Player = {}
Player.__index = Player

function Player.new(newPlayer: Player)
	local self = setmetatable({}, Player)
	
	self.Player = newPlayer
	self.Character = newPlayer.Character
	self.Player.CharacterAdded:Connect(function(character: Model)
		self.Character = character
	end)
	
    --Extra variables
	self.CurrentlySaving = false
	self.CurrentlyLoading = false
	self.UnLoading = false
	
	self.UserId = self.Player.UserId
	
	self:CreateProfile(self.Player)
	
	return self
end

function Player:CreateProfile(player: Player)
	print("Data key name: "..profileStore.Name)
	
	local profile = profileStore:StartSessionAsync(`{player.UserId}`, {
		Cancel = function()
			return player.Parent ~= players
		end,
	})
	
	if profile ~= nil then

		profile:AddUserId(player.UserId) 
		profile:Reconcile() 

		profile.OnSessionEnd:Connect(function()
			Profiles[player] = nil
			player:Kick("Profile session end - Please rejoin")
		end)

		if player.Parent == players then
			Profiles[player] = profile
			print(`Profile loaded for {player.DisplayName}!`)
			
			self:CloneDefaultInventory()
			task.wait()
			self:LoadData(player)
			
		else
			profile:EndSession()
		end

	else
		player:Kick("Profile load fail - Please rejoin")
	end
end

function Player:LoadData(player: Player)
	local playerInventoryModule = require(playersInventoryFolder:FindFirstChild(player.UserId))

	if not playerInventoryModule then
		return false
	end

	local profile = Profiles[player]
	
	if profile and profile.Data then
		local success, errorMsg = pcall(function()
			playerInventoryModule.SendInventoryData(profile.Data.Inventory)
		end)

		if success then
			print(profile.Data)
			--task.wait(3)
			--for _, player in ipairs(players:GetPlayers()) do
			--	playerInventoryModule.AddItem("Wooden Axe")
			--	print(playerInventoryModule["Inventory"])
			--end
		else
			warn("Failed to save data for " .. player.DisplayName .. ": " .. errorMsg)
		end
	else
		warn("No profile found for "..player.DisplayName)
	end
end

function Player:SaveData(player: Player)
	local profile = Profiles[player]

	if profile ~= nil then
		local success, errorMsg = pcall(function()
			profile.Data.Inventory = self:GetPlayerInventory(player)
		end)

		if success then
			profile:EndSession()
			print(player.DisplayName .. "'s data successfully saved!")
		end
	end
end
	
function Player:CloneDefaultInventory()
	if not inventoryTemplate then 
		return
	end
	
	local defaultInventory = inventoryTemplate:Clone()
	defaultInventory.Name = self.UserId
	defaultInventory.Parent = playersInventoryFolder
end

function Player:GetPlayerInventory(player: Player)
	local playerInventoryModule = require(playersInventoryFolder:FindFirstChild(player.UserId))
	
	if not playerInventoryModule then
		return
	end
	
	return playerInventoryModule.GetInventoryData()
end

return Player

I appreciate any tips or suggestions you can provide—I’m continually learning and eager to improve, so your insights would be incredibly valuable.