Wait for DataStores to load before running HumanoidDescription script

  1. What do you want to achieve? I want to have the HumanoidDescription to wait for the datastore values to load before it runs

  2. What is the issue? without a wait function of some sort it works fine alot of the time but sometimes the HumanoidDescription loads before the datastore values causing the game to never load

  3. What solutions have you tried so far?
    I tried adding a “wait(3)” (and trying other numbers) at the beginning of the HumanoidDescription but that’s not a really good solution

HumanoidDescription script

 -- Stop automatic spawning so it can be done in the "PlayerAdded" callback
game.Players.CharacterAutoLoads = false

local function onPlayerAdded(player)
-- Create a HumanoidDescription
--wait (3)
	local humanoidDescription = Instance.new("HumanoidDescription")
	humanoidDescription.HatAccessory = player.AvatarConf.Hat.Value
	humanoidDescription.Face = player.AvatarConf.Face.Value
	humanoidDescription.GraphicTShirt = player.AvatarConf.Shirt.Value
	humanoidDescription.LeftLegColor = player.AvatarConf.Legs.Value
	humanoidDescription.RightLegColor = player.AvatarConf.Legs.Value
	humanoidDescription.TorsoColor = player.AvatarConf.Torso.Value
	humanoidDescription.RightArmColor = player.AvatarConf.Arms.Value
	humanoidDescription.LeftArmColor = player.AvatarConf.Arms.Value
	humanoidDescription.HeadColor = player.AvatarConf.Head.Value
	-- Spawn character with the HumanoidDescription
	player:LoadCharacterWithHumanoidDescription(humanoidDescription)
end
 
-- Connect "PlayerAdded" event to "onPlayerAdded()" function
game.Players.PlayerAdded:Connect(onPlayerAdded)

DataStore script

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("AvatarData")
local RunService = game:GetService("RunService")

local Data = {
	Face = 0;
	Shirt = 0;
	Pants = 0;
	Hat = 0;
	Torso = {5, 105, 174};
	Arms = {245, 206, 44};
	Head = {245, 206, 44};
	Legs = {165, 190, 69}
}


local playersavetable = {};

local function loadStarterData(Player)
		local CharData = Instance.new("Folder")
		CharData.Name = "AvatarConf"
		CharData.Parent = Player
		for statname, statvalue in pairs(Data) do
			if type(statvalue) == 'number' then
			local intvalue = Instance.new("IntValue")
			intvalue.Name = statname
			intvalue.Value = statvalue
			intvalue.Parent = CharData
			else
			local colorvalue = Instance.new("Color3Value")
			colorvalue.Name = statname
			colorvalue.Value = Color3.fromRGB(statvalue[1],statvalue[2],statvalue[3])
			colorvalue.Parent = CharData
		end
	end
end

local function loadData(player)
	local Data
	local s, e = pcall(function()
	Data = DataStore:GetAsync('UserId'..player.UserId)
	end)
	
	if s then 
		print (player.Name.."Data loaded")
	else
		print(player.Name.."Data failed to load")
	end
	
	if Data then
		for statname, statvalue in pairs(Data) do
			player.stats[statname].Value = statvalue
		end
		print(player.Name.."Data has been loaded")
	else
		print(player.Name.."No data found! generating..")
		end
	end

local function saveData(player)
	if RunService:IsStudio() then return end
	local Data = {}
	for _, stat in pairs(player.Stats:GetChildren())do
		Data[stat.Name] = stat.Value
	end
	local s, e = pcall(function()
		DataStore:SetAsync('UserId'..player.UserId)
	end)
	 if s then 
		print(player.Name.."Data has been saved")
	else
		warn (player.Name.."Data failed to save")
	end
end

Players.PlayerAdded:Connect(function(player)
	playersavetable[player] = tick()
	loadStarterData(player)
	loadData(player)
end)

Players.PlayerRemoving:Connect(function(player)
	saveData(player)
end)

If anyone has any questions then feel free to ask! :smiley:

1 Like

I think you could try to use this:

repeat wait() until player:FindFirstChild("AvatarConf")
1 Like

strange now it seems to load my normal avatar in sometimes, rather then crashing

 -- Stop automatic spawning so it can be done in the "PlayerAdded" callback
game.Players.CharacterAutoLoads = false

local function onPlayerAdded(player)
	-- Create a HumanoidDescription
	repeat wait() until player:FindFirstChild("AvatarConf")
	local humanoidDescription = Instance.new("HumanoidDescription")
	humanoidDescription.HatAccessory = player.AvatarConf.Hat.Value
	humanoidDescription.Face = player.AvatarConf.Face.Value
	humanoidDescription.GraphicTShirt = player.AvatarConf.Shirt.Value
	humanoidDescription.LeftLegColor = player.AvatarConf.Legs.Value
	humanoidDescription.RightLegColor = player.AvatarConf.Legs.Value
	humanoidDescription.TorsoColor = player.AvatarConf.Torso.Value
	humanoidDescription.RightArmColor = player.AvatarConf.Arms.Value
	humanoidDescription.LeftArmColor = player.AvatarConf.Arms.Value
	humanoidDescription.HeadColor = player.AvatarConf.Head.Value
	-- Spawn character with the HumanoidDescription
	player:LoadCharacterWithHumanoidDescription(humanoidDescription)
end
 
-- Connect "PlayerAdded" event to "onPlayerAdded()" function
game.Players.PlayerAdded:Connect(onPlayerAdded)

edit: it could be because the folder has been created but not the children (data)?
edit 2: ill try adding in the wait() until functions for all the data

Try to use WaitForChild instead of FindFirstChild.

that has the same result, sometimes it works properly and other times it doesn’t. I’m trying to find a way to make the game wait for descendants as well as the folder

It seems using that and disabling “LoadCharacterAppearance” (under StarterPlayer) causes the script to work 100% of the time :smiley:

2 Likes