My script doesnt always work

I have a big problem. I made this script that teams the player if he is in a group and that makes a folder full of player info that is loaded with data from a data store upon a PlayerAdded function, All of this works well BUT, after this, a CharacterAppearanceLoaded function is called (I use CharacterAppearanceLoaded to make sure the player’s character is fully loaded), and this function basically does various things, like removing some accessories, giving a uniform to the player and welding some meshes to the character as part of the uniform. This function is where the script doesnt always work: First of all, i had to add a debounce to the CharacterAppearanceLoaded because it was to fire twice for some reason. The other problem is that the CharacterAppearanceLoaded function doesnt always fire/work and i really havent been able to identify what the problem is, as the output doesnt show any error.

Please help, i have been struggling and this is the only faulty script in my game that i havent yet been able to fix entirely. Thank you if you read all of this and im really sorry for taking your time.

Here is the full script btw (Server script located in ServerScriptService):

local Repstorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("DataStore")
local LDFolder = Repstorage:WaitForChild("Loadouts")
local GroupID = Repstorage:WaitForChild("GameInfo"):WaitForChild("GroupID")

function onPlayerAdded(Player)
	
	--- TEAM ASSIGN ---
	if Player:IsInGroup(GroupID.Value) then  
		Player.TeamColor = BrickColor.new("Really black")
	end
	-------------------
	
	--- DATA STORE ---
	local PlayerInfo = Instance.new("Folder", Player)
	PlayerInfo.Name = "PlayerInfo"
	local UniformSave = Instance.new("IntValue", PlayerInfo)
	UniformSave.Name = "UniformSave"
	local Balance = Instance.new("IntValue", PlayerInfo)
	Balance.Name = "Balance"
	---chrima---
	local ChriGift = Instance.new("BoolValue", PlayerInfo)
	ChriGift.Name = "GiftClaimed"
	
	local Data
	local success, errormessage = pcall(function()
		Data = DataStore:GetAsync(Player.UserId)
	end)

	if success then
		if Data[1] then
		UniformSave.Value = Data[1]
		Balance.Value = Data[2]
			ChriGift.Value = Data[3]
			end
	else
		error("There was an error while getting Player's data: "..errormessage)
	end
	-------------------
	
db = false
	Player.CharacterAppearanceLoaded:Connect(CharLoaded)		
end

function CharLoaded(char)
	
	if db == false then
		db = true
	
	local plr = Players:GetPlayerFromCharacter(char)
		
		--- SHIRT/PANTS CHECK ---
		local shirt = char:FindFirstChild("Shirt")
		local pants = char:FindFirstChild("Pants")
		
		if not shirt then
			local newshirt = Instance.new("Shirt", char)
			newshirt.Name = "Shirt"
		end
		if not pants then
			local newpants = Instance.new("Pants", char)
			newpants.Name = "Pants"
			end
			-------------------------
			
			--- REMOVE HATS ---
	if plr:IsInGroup(GroupID.Value) then
					local parts = char:GetChildren()
					for i = 1, #parts do
						local instanceA = parts[i]
						if (instanceA.ClassName == "Accessory") then
							if (not instanceA.Handle:FindFirstChild("FaceFrontAttachment")) and (not instanceA.Handle:FindFirstChild("HairAttachment")) then
								parts[i]:Destroy()
							end
						end
					end
				end
		-------------------
		
		wait(0.5)
			
			local NewData = plr.PlayerInfo.UniformSave
			local Loadout = false
		
	if NewData.Value == 0 and plr:IsInGroup(GroupID.Value) then
			Loadout = LDFolder["10001"]
			plr.PlayerInfo.UniformSave.Value = 10001
		elseif NewData.Value ~= 0 then
			Loadout = LDFolder[NewData.Value]
			end
			
			if Loadout ~= false then
			local ChosenHat = Loadout.Uniform.Hat:FindFirstChildOfClass("Model")
				local ChosenBp = Loadout.Uniform.Backpack:FindFirstChildOfClass("Model")
				local ChosenWeapons = Loadout.Tools:GetChildren()
				local shirtid = Loadout.Uniform:WaitForChild("ShirtID")
				local pantsid = Loadout.Uniform:WaitForChild("PantsID")
				local ChosenChantPack = Loadout.Chants:WaitForChild("MaleChants")
			local CUI
				
			if ChosenChantPack:FindFirstChild("ChantPack") then
				CUI = plr.PlayerGui:WaitForChild("ChantUI")
				if CUI:FindFirstChild("ChantPack") then
					CUI.ChantPack:Destroy()
				end
				local ChosenChantPack = ChosenChantPack.ChantPack:Clone()
				ChosenChantPack.Parent = CUI
			end
				
	   if ChosenHat ~= nil then
		local NewHat = ChosenHat:Clone()
		NewHat.Parent = plr.Character
		NewHat.PrimaryPart = NewHat.HEADWELD
		local HeadCFrame = plr.Character.Head.CFrame
		NewHat:SetPrimaryPartCFrame(HeadCFrame)
			
		for i,v in pairs(NewHat:GetChildren()) do
		    if v.Name ~= "HEADWELD" and v.Name ~= "Weld" then
				local Weld = Instance.new("Weld", NewHat.HEADWELD)
		   		Weld.C0 = v.CFrame:inverse() * NewHat.HEADWELD.CFrame
				Weld.Part0 = v
				Weld.Part1 = NewHat.HEADWELD
			
			elseif v.Name == "HEADWELD" then
				local Weld = Instance.new("Motor6D", plr.Character.Head)
				Weld.Name = "HatM6D"
				Weld.Part0 = plr.Character.Head
				Weld.Part1 = v
				end
			v.Anchored = false
		   end
		end
			
	if ChosenBp ~= nil then
		local NewBp = ChosenBp:Clone()
		NewBp.Parent = plr.Character
		NewBp.PrimaryPart = NewBp.TORSOWELD
		local HeadCFrame = plr.Character.Torso.CFrame
		NewBp:SetPrimaryPartCFrame(HeadCFrame)
			
		for i,v in pairs(NewBp:GetChildren()) do
		    if v.Name ~= "TORSOWELD" and v.Name ~= "Weld" then
				local Weld = Instance.new("Weld", NewBp.TORSOWELD)
		   		Weld.C0 = v.CFrame:inverse() * NewBp.TORSOWELD.CFrame
				Weld.Part0 = v
				Weld.Part1 = NewBp.TORSOWELD
			
			elseif v.Name == "TORSOWELD" then
				local Weld = Instance.new("Weld", plr.Character.Torso)
				Weld.Name = "BpM6D"
				Weld.Part0 = plr.Character.Torso
				Weld.Part1 = v
				end
			v.Anchored = false
			end
		end

		    plr.Character.Shirt.ShirtTemplate = shirtid.Value
			plr.Character.Pants.PantsTemplate = pantsid.Value
				
				if ChosenWeapons then
					for i,v in pairs(ChosenWeapons) do
						local t = v:Clone()
						t.Parent = plr.Backpack
				end
			end		
	elseif plr.Team == game.Teams:FindFirstChild("Hostile/Raiders") then
			local clonemusk = game.ServerStorage.Musket:Clone()
			local cloneswab = game.ServerStorage.Swab:Clone()
			clonemusk.Parent = plr.Backpack
		cloneswab.Parent = plr.Backpack
		end
		db = false
	end
end

function onPlayerRemoved(player)
	local datasave = {player.PlayerInfo.UniformSave.Value, player.PlayerInfo.Balance.Value, player.PlayerInfo.GiftClaimed.Value}
	local success, errormessage = pcall(function()
		DataStore:SetAsync(player.UserId, datasave)
	end)

	if success then
		print("Player data was saved succesfuly")
	else
		error("Error when saving Player's data: "..errormessage)
	end
end

Players.PlayerAdded:Connect(onPlayerAdded)
Players.PlayerRemoving:Connect(onPlayerRemoved)

Why not try only fire the on player added function when the character appearance loaded event is fired?

Can you elaborate? i kind of didnt understand what you said there

Instead of firing the onPlayerAdded function when the player joins, fire it when their character’s appearance is loaded.

Well that’s because CharacterAppearanceLoaded needs an specific Player to be defined so the event can be called, and the player is defined by the OnPlayerAdded function

1 Like

I don’t think you get what I mean.

Players.PlayerAdded:Connect(function(plr)
    plr.CharacterAppearanceLoaded:Connect(onPlayerAdded)
end)
1 Like

dude you are a GENIUS, somehow changing the order like you said seems to make it always work, at least for now. Thank you so much for the tip! Tho i still have one problem left to fix and it’s that the the function called by the CharacterAppearanceLoaded event sometimes fire twice, so it creates two PlayerInfo folders, it gives the player the uniform twice, as well as the tool loadout and stuff. Any idea why that happens and how to fix it? (btw it fixes after the player resets)

it happens when you’re in studio mode (assuming you are)

I just tested it in-game and it still happens :confused:

Here’s a simple hack for CharacterAdded to make sure it fires when the player’s character is loaded in the Workspace, also you should give it a try:

local Players = game:GetService("Players")

local function PlayerAdded(Player)
	local function CharacterAdded(Character)
		local Humanoid = Character:WaitForChild("Humanoid")

		if not Humanoid:IsDescendantOf(game) then
			Humanoid.AncestryChanged:Wait()
		end
		
		-- The rest of the code here
	end

	Player.CharacterAdded:Connect(CharacterAdded)
end

Players.PlayerAdded:Connect(PlayerAdded)

for _, Player in pairs(Players:GetPlayers()) do
	PlayerAdded(Player)
end

Another case is maybe the PlayerAdded event is created AFTER the player is spawned in, so I suggest you put the for loop in the last line that plays the PlayerAdded event for the rest of the players in the server once the event is loaded.

1 Like

This seems to work too, but the problem is that my script removes some accessories from the player’s character, that’s why i use CharacterAppearanceLoaded, to make sure all of the player’s accessories have loaded. With your script it doesnt do that so the script ends up not removing any of the character’s accessories. Thanks for the help tho!

Maybe try using CharacterAppearanceLoaded on that script? I don’t really know how to fix so the event fires the the character’s appearance are fully loaded, though

I just tried replacing CharacterAdded in the script you gave me with CharacterAppearanceLoaded and confirmed that is where the problem is, it works and all but the CharacterAppearanceLoaded event fires twice when the player joins for some reason… So bruh.

Is it because that the character respawns when they got joined into the game?

You probably have another script that spawns the player, try disabling CharacterAutoLoads from game.Players properties, and see if you still spawn (which means you have a script to spawn the player, search all scripts for :LoadCharacter())

I tried disabling what you said and it seems to do the trick! Thank you all so much for your help! i have learnt a lot and im really grateful. @Xapelize @ItzMeZeus_IGotHacked @Winbloo Thank you a lot guys, really. I will keep this updated in case the problem ever appears again.

1 Like