Since Roblox put the following restriction on HumanoidDescriptions:
The type of the asset ID provided must be for a Face type asset and not a Decal or Image type asset.
Here is a function that will pass a decalID through a HumanoidDescription and set the newly-updated character’s Head.face.Texture to the decalID
local function applyDescription(humanoid, description) --I hate Roblox
pcall(function()
humanoid:ApplyDescription(description)
humanoid.Parent:FindFirstChild("Head"):FindFirstChild("face").Texture = "rbxassetid://"..description.Face
end)
end
Just realized they also don’t let you do custom shirts, etc, here is an updated script:
local function applyDescription(humanoid, description) --I hate Roblox
pcall(function()
humanoid:ApplyDescription(description)
for i, v in pairs(humanoid.Parent:GetChildren()) do
pcall(function()
if v.Name == "Head" then
v:FindFirstChild("face").Texture = "rbxassetid://"..description.Face
end
if v:IsA("Shirt") then
v.ShirtTemplate = description.Shirt
end
if v:IsA("ShirtGraphic") then
v.Graphic = description.ShirtGraphic
end
if v:IsA("Pants") then
v.PantsTemplate = description.Pants
end
end)
end
end)
end
Why do you use findfirstchild if you dont do safe checking anyways?
Just index face normally at this point.
Also man…Creating anonimous function and a pcall each iteration is just bonkers.
pairs/ipairs is not relevant in Luau since like 2023 i belive.
What in the OOP paradigm did you just say about my code, you little junior scripter? I’ll have you know I was handpicked for the Roblox Dev Hub’s Top Creators program, optimized 17 legacy Rthro bundles with 99.9% backward compatibility, and authored scalable systems serving 2M+ MAU. My Lua patterns are so refined that David Baszucki once DM’d me “pls fix” during a LiveOps incident.
You dare question my use of FindFirstChild without explicit nil-checking? Do you even comprehend the sheer velocity required when iterating 143 descendant objects across 16 replicated humanoids? That nested pcall structure exists because someone thought it’d be funny to upload a 4K texture to the “face” property last sprint.
And lecturing me about pairs? My 'bloxian, I was writing Luau before your first LocalScript even connected to the DataStore. While you were busy making 2D obbies, I single-handedly debugged the 2023 GC overhaul that made your ipairs flex even possible.
As we speak, my custom Studio plugin is auto-formatting your spaghetti code into a Model/View/Controller paradigm so clean it passes the Roblox C++ linter. Your “feedback” will be memory-leaked into the void where Instance.new("Part") without Parent assignment belongs.
I deploy systems with atomicity guarantees that’d make Cloud Engineer IIIs weep. Your ShirtGraphic hotfix wouldn’t survive a 10-user load test. Prepare for the asset ID storm, “Lua learner”—when my next game update ships, your critique will render slower than a 10K-part UnionOperation on mobile.
Regards,
The dev who actually read the Humanoid:ApplyDescription() API docs (and 37 dependent RFCs)
considering your bio states that you’re primarily a builder learning scripting (not a lot of those get far) most people would assume you are if not stated otherwise
Heh, no need to be so mad over one’s post. But he actually got a point. Keeping the FindFirstChild when you don’t use it to explicitly check if the instance exists is just a performance loss. Use v[“face”] or v.face. It will be faster.
If you haven’t read this I’ll explain that, technically speaking, pairs, ipairs, or any other iterator aren’t really required to write anymore unless you explicitly want to simulate original Lua 5.1 behavior. Luau decides for you what the best iterator to use, so for i,v in humanoid.Parent:GetChildren() do is not only a valid syntax but also a better option nowadays.
And yes, such usage of anonymous functions is not recommended. The reason being, for each of the for loop entries, you will not only create a brand new for loop stack but also a brand new function stack. This is unnecessary and can be avoided if you were to make your code more static.
Here is the version of the code that I consider improved:
local function applyDescription(humanoid:Humanoid,description:HumanoidDescription) : ()
pcall(humanoid.ApplyDescription,humanoid,description) -- sick 1 liner
for i,v in humanoid.Parent:GetChildren() do
if v.Name == "Head" then
local face = v:FindFirstChild("face")
if face then
face.Texture = `rbxassetid://{description.Face}`
end
elseif v:IsA("Shirt") then
v.ShirtTemplate = description.Shirt
elseif v:IsA("ShirtGraphic") then
v.Graphic = description.ShirtGraphic
elseif v:IsA("Pants") then
v.PantsTemplate = description.Pants
end
end
end
local function applyDescription(humanoid:Humanoid,description:HumanoidDescription) : () pcall(humanoid.ApplyDescription,humanoid,description) for i,v in humanoid.Parent:GetChildren() do if v.Name == "Head" then local face = v:FindFirstChild("face") if face then face.Texture = `rbxassetid://{description.Face}` end elseif v:IsA("Shirt") then v.ShirtTemplate = description.Shirt elseif v:IsA("ShirtGraphic") then v.Graphic = description.ShirtGraphic elseif v:IsA("Pants") then v.PantsTemplate = description.Pants end end end -- sick 1 liner
This is not a place for being right. People share their solutions to problems and improve them according to the criticism. Instead of mocking my code, you might actually try to actually listen to feedback and improve your own code?