I have been trying to make HowToRoblox's Armor system to Save the Armors player has obtained in-season, but the armors they obtained would not save

Hello there, if anyone here is seeing my Topic post, let me explain about myself, I have been trying to improve the roblox developer youtuber named HowToRoblox’s Armor System for over couple Months now, I’ve revamped the Script to be compatible with R6 player model instead of R15 thanks to that one other kind user I’ve found in this forum channel a months ago, and also added an feature where player can Buy an Armor with their in-game currency in leaderstats,

but the major problem is, that when Player buys an Armor in-game and leave the server, the Armor they have bought does Not even Save at all, I have tried many solutions that ChatGpt has provided me because I am actually an Peanut brain when it comes to scripting and I couldn’t hire an Scripter to Fix this error, but none of these solutions ChatGpt has provided me has ever worked, of course it is an AI program that doesn’t attempt running something in roblox’s instances or something in order to actually test out that their generated Script does works…

So I am posting an Main ArmorServer Script code I used for the Roblox game I am building on so peoples could find my Topic post and help me figure out how to make it function properly, assuming if this Topic is going to get noticed in a first place… :sweat:

I will show the Script code and some couple Screenshots alongside with this Topic post, so it would be very convenient if you could help me out with Fixing this error that has lasted for couple months…

-- Types of armor
local armorTypes = {
	"Head";
	"Torso";
	"LeftArm";
	"Legs";
	"RightArm";
}

-- Modules
local equipFunc = require(script:WaitForChild("EquipArmor"))
local removeFunc = require(script:WaitForChild("RemoveArmor"))
local deleteFunc = require(script:WaitForChild("DeleteArmor"))

-- RemoteEvents
local remotes = game:GetService("ReplicatedStorage"):WaitForChild("RemoteEvents")
local equipRE = remotes:WaitForChild("EquipArmor")
local removeRE = remotes:WaitForChild("RemoveArmor")
local deleteRE = remotes:WaitForChild("DeleteArmor")

-- Other variables
local armorpieces = game:GetService("ReplicatedStorage"):WaitForChild("ArmorPieces")

-- Data handling
local dss = game:GetService("DataStoreService")
local ds = dss:GetDataStore("PLAYER_ARMOR_DATA")
local inventoryDs = dss:GetDataStore("PLAYER_INVENTORY_DATA")

-- Function to save player data
local function saveData(plr) -- saveData function Saves whole other things other then inventory and inventory itself in two different datastores, but it doesn't save inventoryDs at all...
	if not plr:FindFirstChild("DATA_FAILED_TO_LOAD") then
		local attack = plr:FindFirstChild("Attack") and plr.Attack.Value or 0
		local defense = plr:FindFirstChild("Defense") and plr.Defense.Value or 0
		local luck = plr:FindFirstChild("Luck") and plr.Luck.Value or 0

		local inventory = {} -- I can't figure out how to make this section does inserts an Array of Armor models/armor.Name's that were inside ArmorInventory Folder into local inventory Folder and save them...
		if plr:FindFirstChild("ArmorInventory") then
			local count = 1
			for _, armor in pairs(plr.ArmorInventory:GetChildren()) do
				table.insert(inventory, armor.Name)
				inventory[count] = armor.Name
				count = count + 1
			end
		end

		local equipped = {}
		if plr:FindFirstChild("ArmorEquipped") then
			for _, armor in pairs(plr.ArmorEquipped:GetChildren()) do
				if armor.Value ~= nil then
					equipped[armor.Name] = armor.Value.Name
				else
					equipped[armor.Name] = nil
				end
			end
		end

		local compiledData = {
			Equipped = equipped;
			Attack = attack;
			Defense = defense;
			Luck = luck;
		}

		local success, err = nil, nil
		while not success do
			success, err = pcall(function()
				ds:SetAsync(plr.UserId, compiledData)
				inventoryDs:SetAsync(plr.UserId .. "_inventory", inventory)
				print("Player data saved successfully for: " .. plr.Name)
				print("Inventory: ", inventory)
			end)
			if not success then
				warn("Failed to save data for player: " .. plr.Name .. ". Error: " .. err)
				task.wait(0.02)
			end
		end
	end
end

-- Handle player removal
game.Players.PlayerRemoving:Connect(function(plr)
	saveData(plr)
end)

-- Function to load player data
local function loadData(plr)
	local dataFailedWarning = Instance.new("StringValue")
	dataFailedWarning.Name = "DATA FAILED TO LOAD"
	dataFailedWarning.Parent = plr

	local attack = Instance.new("IntValue")
	attack.Name = "Attack"
	attack.Parent = plr

	local defense = Instance.new("IntValue")
	defense.Name = "Defense"
	defense.Parent = plr

	local luck = Instance.new("IntValue")
	luck.Name = "Luck"
	luck.Parent = plr

	local success, armorData = pcall(function()
		return ds:GetAsync(plr.UserId)
	end)

	local inventorySuccess, inventoryData = pcall(function()
		return inventoryDs:GetAsync(plr.UserId .. "_inventory")
	end)

	if success then
		dataFailedWarning:Destroy()

		local attackValue = armorData and armorData.Attack or 0
		local defenseValue = armorData and armorData.Defense or 0
		local luckValue = armorData and armorData.Luck or 0

		plr.Attack.Value = attackValue
		plr.Defense.Value = defenseValue
		plr.Luck.Value = luckValue

		local inv = Instance.new("Folder")
		inv.Name = "ArmorInventory"
		inv.Parent = plr
		
		if not inventoryData then
			armorData = {
				Inventory = {"Spiky Feelings"}; --Armor you will start with
				Equipped = {};
				Attack = 0;
				Defense = 0;
				Luck = 0;
			}
		end

		if inventoryData then
			for _, armorName in pairs(inventoryData) do
				for __, armorpiece in pairs(armorpieces:GetDescendants()) do
					if armorpiece.Name == armorName and armorpiece.Parent.Parent == armorpieces then
						armorpiece:Clone().Parent = inv
						break
					end
				end
			end
		else
			warn("Failed to load inventory for player: " .. plr.Name)
			return
		end

		local equipped = Instance.new("Folder")
		equipped.Name = "ArmorEquipped"
		equipped.Parent = plr

		for _, armorType  in pairs(armorTypes) do
			local armorValue = Instance.new("ObjectValue")
			armorValue.Name = armorType
			armorValue.Parent = equipped
		end

		for armortype, armorname in pairs(armorData.Equipped) do
			if armorname then
				equipFunc(plr, armortype, armorname)
			end
		end

		plr.CharacterAdded:Connect(function()
			for _, armorValue in pairs(equipped:GetChildren()) do
				if armorValue.Value ~= nil then
					equipFunc(plr, armorValue.Name, armorValue.Value.Name, true)
				end
			end
		end)
	else
		warn("Failed to load data for player: " .. plr.Name)
	end
end

-- Handle player joining
game.Players.PlayerAdded:Connect(loadData)

-- Listening to RemoteEvents
equipRE.OnServerEvent:Connect(equipFunc)
removeRE.OnServerEvent:Connect(removeFunc)
deleteRE.OnServerEvent:Connect(deleteFunc)

-- Save data periodically
while true do
	wait(30)
	for _, plr in pairs(game.Players:GetPlayers()) do
		saveData(plr)
		print("Player's Armor Data Has Been Saved Successfully")
		plr.PlayerGui.AutoSavePopUpGui.TextLabel.AutoSaveFade:FireClient(plr)
	end
end


I attempted to Fix the Script of HowToRoblox’s Armor System with only ChatGPT because he hasn’t been active for 9 months in youtube with no signs of activity, I’ve added couple fixes by myself including making the whole Script be compatible with R6 and even an other system where player can Buy Armors and add it into ArmorInventory Folder, but contents inside ArmorInventory wouldn’t save at all… :sob:

thank you for reading my Topic Post as always. - Yurim

no one is noticing my forum post yet :face_holding_back_tears:

1 Like

im going to attempt to be of use… let me read this

okay so first of all if inventory isnt printing anything its because there is an issue on this part of the script

if plr:FindFirstChild("ArmorInventory") then
			local count = 1
			for _, armor in plr.ArmorInventory:GetChildren() do
				table.insert(inventory, armor.Name)
				inventory[count] = armor.Name
				count = count + 1
			end
		end

Either ArmorInventory doesn’t exist in the player(because its typed wrong. or its just not there)
or theres no children inside armor Inventory.

try replacing the function saveData with this:

local function saveData(plr) -- saveData function Saves whole other things other then inventory and inventory itself in two different datastores, but it doesn't save inventoryDs at all...
	if not plr:FindFirstChild("DATA_FAILED_TO_LOAD") then
		local attack = plr:FindFirstChild("Attack") and plr.Attack.Value or 0
		local defense = plr:FindFirstChild("Defense") and plr.Defense.Value or 0
		local luck = plr:FindFirstChild("Luck") and plr.Luck.Value or 0
		local Armorcount = 1

		local inventory = {} -- I can't figure out how to make this section does inserts an Array of Armor models/armor.Name's that were inside ArmorInventory Folder into local inventory Folder and save them...
		local AmorInventory =plr:FindFirstChild("ArmorInventory")
		if not AmorInventory then
			warn("Armor inventory isnt found in the player")
		end
		
		for _, armor in AmorInventory:GetChildren() do
			table.insert(inventory, armor.Name)
			inventory[Armorcount] = armor.Name
			Armorcount += 1
		end

		local equipped = {}
		if plr:FindFirstChild("ArmorEquipped") then
			for _, armor in pairs(plr.ArmorEquipped:GetChildren()) do
				if armor.Value ~= nil then
					equipped[armor.Name] = armor.Value.Name
				else
					equipped[armor.Name] = nil
				end
			end
		end

		local compiledData = {
			Equipped = equipped;
			Attack = attack;
			Defense = defense;
			Luck = luck;
		}

		local success, err = nil, nil
		while not success do
			success, err = pcall(function()
				ds:SetAsync(plr.UserId, compiledData)
				inventoryDs:SetAsync(plr.UserId .. "_inventory", inventory)
				print("Player data saved successfully for: " .. plr.Name)
				print("Inventory: ", inventory)
			end)
			if not success then
				warn("Failed to save data for player: " .. plr.Name .. ". Error: " .. err)
				task.wait(0.02)
			end
		end
	end
end

and show us the error

Overnight Guardence Experience - Test Build made for Fix the inventory Not Saving.rbxl (735.9 KB)
hello there, thank you for replying to my forum post, I did added your code suggestion to my ArmorServer Script, but it did not Warned “(“Armor inventory isnt found in the player”)” on the OutPut as there is Armor Inventory Folder being created inside Player Properly, but this is rather an issue where the Script does not insert the Armor Model’s Name into Table’s Array at all, so I will try to show you the Testing Copy of the Roblox Place File so you could try to Fix the issue if that is possible for you, sorry for the inconveniences… :sweat: