Help with ProfileService and saving player inventory

  1. What do you want to achieve? Keep it simple and clear!
    I am currently developing a survival game and am currently stuck with getting ProfileService to work with saving and loading the player’s inventory to the server.
  2. What is the issue? Include screenshots / videos if possible!
    I tried using this post to adapt the profile service to work, but the game skips the For loops entirely due to the inventory table being empty in the template script. So I would like to ask for help with solutions for this please!

Data script:

local Players = game:GetService("Players")
local SSS = game:GetService("ServerScriptService")
local SStorage = game:GetService("ServerStorage")

local tools = SStorage.Tools
local inventories = SStorage.Inventories

local Template = require(script.Parent.Template)
local ProfileService = require(SSS.Libs.ProfileService)
local Manager = require(script.Parent.Manager)

-- Set to Production before publishing
local ProfileStore = ProfileService.GetProfileStore("Test2", Template)

local function GiveLeaderstats(player: Player)
	local profile = Manager.Profiles[player]
	if not profile then return end
	
	local leaderstats = Instance.new("Folder", player)
	leaderstats.Name = "leaderstats"
	
	local Money = Instance.new("NumberValue", leaderstats)
	Money.Name = "Money"
	Money.Value = profile.Data.Money
	
	local XP = Instance.new("NumberValue", leaderstats)
	XP.Name = "XP"
	XP.Value = profile.Data.XP
	
end

local function LoadPlayerInv(player: Player)
	local profile = Manager.Profiles[player]
	if not profile then return end
	
	local inventory_folder = Instance.new("Folder")
	inventory_folder.Name = player.Name
	inventory_folder.Parent = inventories
	
	wait(8)
	
	local test = {}
	for index = 1, #test do
		print(index, test[index])
		print("inside loop")
	end
	
	for _, name in ipairs(profile.Data.Inventory) do
		print("started for loop")
		wait(1)
		print(tools[name])
		
		tools[name]:Clone().Parent = player.Backpack -- For the player to use
		tools[name]:Clone().Parent = inventory_folder -- For saving and loading
	end
end

local function SavePlayerInv(player: Player)	
	local profile = Manager.Profiles[player]
	if not profile then return end
	
	local cloudInventory = profile.Data.Inventory
	print(cloudInventory)
	local inventory_folder = inventories[player.Name]
	

	for _, item in ipairs(inventory_folder:GetChildren()) do
		print("inside save method")
		table.insert(cloudInventory, item.Name)
	end

	inventory_folder:Destroy()
end

local function PlayerAdded(player: Player)
	local profile = ProfileStore:LoadProfileAsync("Player_" .. player.UserId)
	if profile == nil then
		player:Kick("Data issue, try again shortly.")
		return
	end
	
	profile:AddUserId(player.UserId)
	profile:Reconcile()
	profile:ListenToRelease(function()
		Manager.Profiles[player] = nil
		player:Kick("Data issue, try again shortly.")
	end)
	
	if player:IsDescendantOf(Players) == true then
		Manager.Profiles[player] = profile
		GiveLeaderstats(player)
		LoadPlayerInv(player)
	else
		profile:Release()
	end
end

for _, player in Players:GetPlayers() do
	task.spawn(PlayerAdded, player)
end

Players.PlayerAdded:Connect(PlayerAdded)
Players.PlayerRemoving:Connect(function(player: Player)
	local profile = Manager.Profiles[player]
	if not profile then return end
	SavePlayerInv(player)
	profile:Release()
end)

Template Script:

local module = {
	Money = 0,
	XP = 0,
	DelverLevel = 0,
	Inventory = { }
}

return module

Manager Script:

local module = {}

module.Profiles = {}

return module

Hierarchy:
image

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    As mentioned before, I’ve tried using that linked post before, as well as youtube videos explaining ProfileService.
2 Likes

I’ve experienced a similar problem but with loading cars for a driving game I’m working on.

I also use ProfileService under a similar format to you. Yes, I have experienced this issue as well.

The Solution
In your Template script make another table with a starter item or something similar so that you have something to load, since ipairs only iterates through results that are not == nil. If you do want the player to start with nothing, I recommend changing ipairs to just pairs, as pairs does iterate through nil items.

I’m not entirely sure of any other fix, and I’m not sure whether this will work for you but let me know if this has helped at all.

1 Like

I did think about having the player have a starter item to just “force” the loop to go through, but I would like for the player to start with nothing for the game, although I think I will leave that as a last case scenario kind of thing. As for the ipairs and pairs, I did try changing it to pairs but it still wouldn’t loop through nil unfortunately.

Unfortunately, I’m not very sure of any other fix currently, you could create a placeholder item like “empty slot” to force the loop to go through, then just delete the empty slot from their inventory once they start

Another more screwy way to do it, but I guess it should work

1 Like

Yeah I guess so unfortunately. Maybe I’ll just make an item that makes sense for the player to always have in their inventory.

But thank you for the help!

1 Like

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