.CreateInventory() (method below) gets called whenever a player joins the server. And then it checks the player’s previous save and then puts back all those items back, after that to test the data saving, I added ServerInventoryManager.GiveItem(player, "Slinger", "Plantable", 5) to add a new item with a new GUID.
But whenever I play test again, my items gets duplicated and when I rejoin, those duplicated items will be duplicated indefinitely.
HandledItems[player.Name] = data.Inventory
task.spawn(function()
local items = table.clone(HandledItems[player.Name])
for guid, item in items do
ServerInventoryManager.GiveItem(player, item.Name, item.Type, item.Quantity, item.Size)
end
ServerInventoryManager.GiveItem(player, "Slinger", "Plantable", 5)
end)
function ServerInventoryManager.GiveItem(player: Player, itemName: string, typeOfTool: TOOLS, initialValue: number?, size: number?)
--...
if inventory then
--...
-- Adding items into array
local playerItems = HandledItems[player.Name]
if playerItems then
local data: ItemData.Item_Data = {
Name = itemName,
Quantity = initialValue,
Size = size or 1,
Type = typeOfTool,
}
playerItems[guid] = data
else
warn("Tried to add item, but player was not initialized in HandledItems.")
end
end
end
local Players = game:GetService("Players")
local ServerScriptService = game:GetService("ServerScriptService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Template = require(script.Template)
local ProfileStore = require(ServerScriptService.Libraries.ProfileStore)
local Leaderstat = require(ServerScriptService.Modules.Leaderstat)
local ServerInventoryManager = require(ServerScriptService.Modules.Managers.ServerInventoryManager)
local INDEX = 14
local DS_KEY = `Prod_{INDEX}`
if RunService:IsStudio() then
DS_KEY = `Studio_{INDEX}`
end
local PlayerStore = ProfileStore.New(DS_KEY, Template.SHARED_TEMPLATE)
local DataManager = {}
DataManager.Profiles = {} :: {[Player]: typeof(PlayerStore:StartSessionAsync())}
function DataManager.LoadProfile(player: Player)
local profile = PlayerStore:StartSessionAsync(`{player.UserId}`, {
Cancel = function()
return player.Parent ~= Players
end,
})
if profile == nil then
return player:Kick("Unable to load profile")
end
profile:AddUserId(player.UserId)
profile:Reconcile()
profile.OnSessionEnd:Connect(function()
DataManager.Profiles[player] = nil
player:Kick("Ended session")
end)
local isInGame = player.Parent == Players
if isInGame then
DataManager.Profiles[player] = profile
else
profile:EndSession()
end
local data = DataManager.GetData(player)
Leaderstat.Create(player, data)
ServerInventoryManager.CreateInventory(player, data)
end
function DataManager.GetData(player: Player) : Template.PLAYER_DATA?
local profile = DataManager.Profiles[player]
if not profile then return end
return profile.Data
end
function DataManager.RemoveProfile(player: Player)
local profile = DataManager.Profiles[player]
if profile ~= nil then
profile:EndSession()
end
end
function DataManager.Start()
for _, player in Players:GetPlayers() do
task.spawn(DataManager.LoadProfile, player)
end
Players.PlayerAdded:Connect(DataManager.LoadProfile)
Players.PlayerRemoving:Connect(DataManager.RemoveProfile)
end
DataManager.Start()
return DataManager
But reading what you sent, that’s literally what you’re designing it to do though?
-------- [ Top part ] --------
-- Your data was already set to that same spot
HandledItems[player.Name] = data.Inventory
-- // Right below
-- Cloning it here, which doesn't seem to be doing much
local items = table.clone(HandledItems[player.Name])
for guid, item in items do
ServerInventoryManager.GiveItem(
player,
item.Name,
item.Type,
item.Quantity,
item.Size
)
end
-------- [ Bottom part ] --------
-- Which is currently your data.Inventory
local playerItems = HandledItems[player.Name]
-- // Little further down
-- new guid, not the same as previous guid came from nowhere
-- global/outside variable it's not passed through giveItem function
playerItems[guid] = data
So when you say you’re “putting it back”, it was already there in the first place. I don’t think profile service clears the profile.Data when it saves, so you’re just duplicating your data when you join. Or save, idk when this occurs in your code.