How could I save an In-Game Player Character's Accessories?

Hello. This is my first time ever posting here so I sincerely apologize if I do something wrong in any way.

TL;DR at the bottom if you do not want to read explanation.

I am currently creating a game, and within the game the Player plays as an IN-GAME character (a StarterCharacter), whos appearance does not reflect the appearance of the Player’s Roblox Avatar. I currently have a Hair Giver, which will give the Player Hair. (Exactly how it sounds, heh.) I am also working on a Hat Giver as well. What am I trying to achieve here? I want it so that if a Player were to get Hair from the Hair Giver, or get a Hat from the Hat Giver, I want the Accessories (The Hair and Hat[s]) to save onto the Player’s IN-GAME character, so that once they’ve left the game and were to rejoin, or were to just Reset, they would not have to repeat the process of getting Hair and Hats. I know that I could achieve this through DataStores, (or at least I believe that is how I would do it…) so I tried my best to learn about DataStores, however it seems I do not understand it well enough, because I attempted to make an Accessory Saving system with the help of DataStore tutorials and other forum posts related to saving accessories/characters, yet the Accessory Saving System does not work at all. Please explain to me what I did wrong so it can be fixed, so that Player’s Accessories will save onto their In-Game Characters.

TL;DR: Attempting to save Accessories to Player’s In-Game Character using DataStore, but it is not working.

Here is the Code, which is located in a Server Script in ServerScriptService:


local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("DataStore")

game.Players.PlayerRemoving:Connect(function(Player)
	
	pcall(function()
		
		local Accessories = {}

		for _, Item in pairs(Player.Items:GetChildren()) do
			table.insert(Accessories, Item.Name)
		end

		DataStore:SetAsync(Player.UserId, Accessories)
		
	end)
	
end)

game.Players.PlayerAdded:Connect(function(Player)
	
	local Data
	
	local AccessoriesFolder = Instance.new("Folder")
	AccessoriesFolder.Name = "PlayerAccessories" 
	AccessoriesFolder.Parent = Player
	
	pcall(function()
		Data = DataStore:GetAsync(Player.UserId)
		for _,item in pairs(Data) do
			local Value	= Instance.new("StringValue",AccessoriesFolder)
			Value.Name = item
		end
		
	end)
	
	Player.CharacterAdded:Connect(function()
		for i, accessory in pairs(AccessoriesFolder:GetChildren()) do
			game.ServerStorage.AllAccessories[accessory.Name]:Clone().Parent = Player.Character
		end
		
	end)
	
end)

1 Like

add success,errormsg to pcall(function() to check if the datastore is working fine.

local success,errormsg = pcall(function()
		
		local Accessories = {}

		for _, Item in pairs(Player.Items:GetChildren()) do
			table.insert(Accessories, Item.Name)
		end

		DataStore:SetAsync(Player.UserId, Accessories)
		
	end)
if success then
print("Successfully Saved Data Store!")
else
warn(errormsg)

and here

local success,errormsg = pcall(function()
		Data = DataStore:GetAsync(Player.UserId)
		for _,item in pairs(Data) do
			local Value	= Instance.new("StringValue",AccessoriesFolder)
			Value.Name = item
		end
	end)
if success then
print("Success")
else
warn(errormsg)
3 Likes

Hello, I get this error after I did what you said :sweat_smile:
“ServerScriptService.Script:35: invalid argument #1 to ‘pairs’ (table expected, got nil)”
I’m not sure what I am doing wrong.

1 Like

exactly, thats why your script isn’t working

1 Like

so your error is in the local GetAsync part right?

1 Like

Yes, I believe that is where the error is occurring

2 Likes

when you leave the game does it print “Successfully Saved Data Store!”?

2 Likes

Ah, I noticed an error on my part. In Player removing in the pcall when getting the children of folder, I had the wrong name! I changed it to “PlayerAccessories” like it should be, and now I don’t get any errors in the Output. (I get “Successfully Saved Data Store!” printed when leaving, and “Success” printed on joining.) However, when testing both in Studio and In-Game, I tried on a Hair, left, and rejoined yet the Hair was not saved. :confused:

do you have API enabled?
[Char Limits]

1 Like

also in the for _,item in pairs(Data) do loop
add print(item)

1 Like

Yes, API is indeed enabled.
[characters limit]

1 Like

add a print(item) in the loop as i said.

1 Like

I added “print(item)” yet nothing was printed when putting on a hair or anything

1 Like

did you do it like this?

for _,item in pairs(Data) do
                        print(item) -- like that
			local Value = Instance.new("StringValue",AccessoriesFolder)
			Value.Name = item
		end
1 Like

Yes, I put “print(item)” in the script like that. Nothing was printed when putting on an accessory :frowning: Do you think maybe it could be an issue with my game? Or the Hair Giver? I don’t know why this isn’t working :confused:

1 Like

that shouldn’t print when you put on an accessory.
when you join the game get your accessory and rejoin, on rejoining it should print something.

1 Like

Ah, my bad. I tried what you said. Joined the game, put on an accessory, left and joined back and nothing was printed for it

1 Like

“Successfully Saved Data Store!” or “success” Didn’t print?

1 Like

Oh, yes those were both printed, forgive me. The print for “print(item)” was not printed.

1 Like

in the SetAsync() can you print

for _, Item in pairs(Player.Items:GetChildren()) do
            print(Item.Name)
			table.insert(Accessories, Item.Name)
		end
1 Like