Let him go and After Him Protagonist Morph
Key RequiredUniversal

Let him go and After Him Protagonist Morph

Universal Scriptimdisplayimdisplay 2.2K views 770 executesUpdated Dec 10, 2025
5.0/ 5(3 votes)
30100% Positive
Lua Script•450 lines (12390 chars)
local plr = game.Players.LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()
local hum = char:WaitForChild("Humanoid")
local noHealthFX = false --false or true, change this to true if you only want the morph and no additional stuff like face changes depending on health, firering's desaturating when health lowers, etc.
local chosenFace = "Default"
local variantName = "brokenspawn" --brokenspawn or firering
local subvariantName = "Default"
local officialShirt = false --false or true. change this to true if you want After Him Firering to use the cape thingy in the official sneakpeek render

--brokenspawn's subvariant: Default, MarthyrSpawn, or Day4Spawn

--firering's subvariant: Default or AfterHim 

local function wipeOutStuff()
	if not char then return end
	for _, v in pairs(char:GetChildren()) do
		if v:IsA("Accessory") or v:IsA("Shirt") or v:IsA("Pants") or v:IsA("ShirtGraphic") then
			v:Destroy()
		end
	end
end

local function safeColor3FromFloats(r, g, b)
	local function clamp(x) 
		if x < 0 then return 0 
		elseif x > 255 then return 255 
		else return math.floor(x + 0.5) 
		end 
	end
	return Color3.fromRGB(clamp(r), clamp(g), clamp(b))
end

local function lerpColor(color1, color2, t)
	return Color3.new(
		color1.R + (color2.R - color1.R) * t,
		color1.G + (color2.G - color1.G) * t,
		color1.B + (color2.B - color1.B) * t
	)
end

local function recolorParts()
	if not char then return end
	
	if variantName == "brokenspawn" then
		if subvariantName == "MarthyrSpawn" then
			for _, bp in ipairs(char:GetDescendants()) do
				if bp:IsA("BasePart") then
					bp.Color = Color3.fromRGB(17, 17, 17)
				end
			end
			
			local existingPants = char:FindFirstChildOfClass("Pants")
			if not existingPants then
				local p = Instance.new("Pants", char)
				p.PantsTemplate = "rbxassetid://18819882074"
			end
		elseif subvariantName == "Day4Spawn" then
			local hp = hum.Health
			local desat = 1 - math.clamp(hp / 100, 0, 1)
			
			for _, bp in ipairs(char:GetDescendants()) do
				if bp:IsA("BasePart") then
					if bp.Name == "Torso" or bp.Name == "UpperTorso" or bp.Name == "LowerTorso" then
						local gray = 202 - (52 * desat)
						bp.Color = Color3.fromRGB(gray, gray, gray)
					else
						local gray = 248 - (88 * desat)
						bp.Color = Color3.fromRGB(gray, gray, gray)
					end
				end
			end
			
			local existingShirt = char:FindFirstChildOfClass("Shirt")
			local existingPants = char:FindFirstChildOfClass("Pants")
			
			if hp <= 50 then
				if not existingShirt then
					local s = Instance.new("Shirt", char)
					s.ShirtTemplate = "rbxassetid://91229862386616"
				end
				if not existingPants then
					local p = Instance.new("Pants", char)
					p.PantsTemplate = "rbxassetid://91229862386616"
				end
			else
				if existingShirt then existingShirt:Destroy() end
				if existingPants then existingPants:Destroy() end
			end
		else
			for _, bp in ipairs(char:GetDescendants()) do
				if bp:IsA("BasePart") then
					if bp.Name == "Torso" or bp.Name == "UpperTorso" or bp.Name == "LowerTorso" then
						bp.Color = Color3.fromRGB(202, 203, 209)
					else
						bp.Color = Color3.fromRGB(248, 248, 248)
					end
				end
			end
			
			local existingPants = char:FindFirstChildOfClass("Pants")
			if not existingPants then
				local p = Instance.new("Pants", char)
				p.PantsTemplate = "rbxassetid://18812715099"
			end
		end
	else
		if subvariantName == "AfterHim" then
			if noHealthFX then
				for _, bp in ipairs(char:GetDescendants()) do
					if bp:IsA("BasePart") then
						if bp.Name == "Torso" or bp.Name == "UpperTorso" or bp.Name == "LowerTorso" then
							bp.Color = safeColor3FromFloats(229, 174, 46)
						else
							bp.Color = safeColor3FromFloats(208, 123, 55)
						end
					end
				end
			else
				local hp = hum.Health
				local mod = math.clamp(hp / 100, 0, 1)
				local desat = 1 - mod
				
				if desat > 0 then
					local torsoColor = Color3.fromRGB(229, 174, 46)
					local limbColor = Color3.fromRGB(208, 123, 55)
					local grayTorso = Color3.fromRGB(140, 140, 140)
					local grayLimb = Color3.fromRGB(70, 70, 70)
					
					for _, bp in ipairs(char:GetDescendants()) do
						if bp:IsA("BasePart") then
							if bp.Name == "Torso" or bp.Name == "UpperTorso" or bp.Name == "LowerTorso" then
								bp.Color = lerpColor(torsoColor, grayTorso, desat)
							else
								bp.Color = lerpColor(limbColor, grayLimb, desat)
							end
						end
					end
				else
					local bodyR, bodyG, bodyB = 208, 123, 55
					local torR, torG, torB = 229, 174, 46
					
					for _, bp in ipairs(char:GetDescendants()) do
						if bp:IsA("BasePart") then
							if bp.Name == "Torso" or bp.Name == "UpperTorso" or bp.Name == "LowerTorso" then
								bp.Color = safeColor3FromFloats(torR * mod, torG * mod, torB * mod)
							else
								bp.Color = safeColor3FromFloats(bodyR * mod, bodyG * mod, bodyB * mod)
							end
						end
					end
				end
			end
			
			local existingShirt = char:FindFirstChildOfClass("Shirt")
			local existingShirtGraphic = char:FindFirstChildOfClass("ShirtGraphic")
			
			if officialShirt then
				if existingShirt then existingShirt:Destroy() end
				if not existingShirtGraphic then
					local sg = Instance.new("Shirt", char)
					sg.ShirtTemplate = "rbxassetid://79082321877257"
					local sp = Instance.new("ShirtGraphic", char)
					sp.Graphic = "rbxassetid://79353463316783"
				end
			else
				if existingShirtGraphic then existingShirtGraphic:Destroy() end
				if not existingShirt then
					local s = Instance.new("Shirt", char)
					s.ShirtTemplate = "rbxassetid://100658100237731"
				end
			end
		else
			if noHealthFX then
				for _, bp in ipairs(char:GetDescendants()) do
					if bp:IsA("BasePart") then
						if bp.Name == "Torso" or bp.Name == "UpperTorso" or bp.Name == "LowerTorso" then
							bp.Color = safeColor3FromFloats(239, 184, 56)
						else
							bp.Color = safeColor3FromFloats(218, 133, 65)
						end
					end
				end
			else
				local hp = hum.Health
				local mod = math.clamp(hp / 100, 0, 1)
				local desat = 1 - mod
				
				if desat > 0 then
					local torsoColor = Color3.fromRGB(239, 184, 56)
					local limbColor = Color3.fromRGB(218, 133, 65)
					local grayTorso = Color3.fromRGB(150, 150, 150)
					local grayLimb = Color3.fromRGB(80, 80, 80)
					
					for _, bp in ipairs(char:GetDescendants()) do
						if bp:IsA("BasePart") then
							if bp.Name == "Torso" or bp.Name == "UpperTorso" or bp.Name == "LowerTorso" then
								bp.Color = lerpColor(torsoColor, grayTorso, desat)
							else
								bp.Color = lerpColor(limbColor, grayLimb, desat)
							end
						end
					end
				else
					local bodyR, bodyG, bodyB = 218, 133, 65
					local torR, torG, torB = 239, 184, 56
					
					for _, bp in ipairs(char:GetDescendants()) do
						if bp:IsA("BasePart") then
							if bp.Name == "Torso" or bp.Name == "UpperTorso" or bp.Name == "LowerTorso" then
								bp.Color = safeColor3FromFloats(torR * mod, torG * mod, torB * mod)
							else
								bp.Color = safeColor3FromFloats(bodyR * mod, bodyG * mod, bodyB * mod)
							end
						end
					end
				end
			end
			
			local existingPants = char:FindFirstChildOfClass("Pants")
			if not existingPants then
				local p = Instance.new("Pants", char)
				p.PantsTemplate = "rbxassetid://18816502690"
			end
		end
	end
end

local brokenspawnFaces = {
	Smile = "rbxassetid://119843958411585",
	Happy = "rbxassetid://82047519860108",
	Wow = "rbxassetid://107872884101860",
	Shocked = "rbxassetid://127527512989972",
	Default = "rbxassetid://18812397563",
	Scared = "rbxassetid://18950168467",
	Unwell = "rbxassetid://106051826391565",
	Tired = "rbxassetid://18950162865"
}

local fireringFaces = {
	Shocked = "rbxassetid://89565910291159",
	Default = "rbxassetid://121665781026929",
	Mad = "rbxassetid://90449712627006",
	Happy = "rbxassetid://109330527602031",
	Sad = "rbxassetid://138220398125082",
	VerySad = "rbxassetid://137894662752659"
}

local function applyChosenFace()
	if not char then return end
	local h = char:FindFirstChild("Head")
	if h then
		local d = h:FindFirstChildWhichIsA("Decal")
		if d then
			d.Texture = chosenFace
		end
	end
end

local function pickFace(name)
	if variantName == "brokenspawn" then
		if subvariantName == "MarthyrSpawn" then
			chosenFace = "rbxassetid://125021660606176"
		else
			chosenFace = brokenspawnFaces[name] or brokenspawnFaces.Default
		end
	else
		chosenFace = fireringFaces[name] or fireringFaces.Default
	end
end

local healthConn
local diedConn

local function disconnectConns()
	if healthConn then
		healthConn:Disconnect()
		healthConn = nil
	end
	if diedConn then
		diedConn:Disconnect()
		diedConn = nil
	end
end

local function updateFaceBasedOnHealth(x)
	if noHealthFX then return end
	
	local hd = char:FindFirstChild("Head")
	if not hd then return end
	
	local dec = hd:FindFirstChildWhichIsA("Decal")
	if not dec then return end
	
	if variantName == "brokenspawn" then
		if subvariantName == "MarthyrSpawn" then
			dec.Texture = "rbxassetid://125021660606176"
		elseif subvariantName == "Day4Spawn" then
			if x <= 50 then
				dec.Texture = "rbxassetid://105104796113792"
			else
				dec.Texture = "rbxassetid://18950175783"
			end
		else
			if x < 40 then
				dec.Texture = brokenspawnFaces.Unwell
			elseif x < 60 then
				dec.Texture = brokenspawnFaces.Tired
			elseif x < 80 then
				dec.Texture = brokenspawnFaces.Scared
			elseif x < 99 then
				dec.Texture = brokenspawnFaces.Default
			else
				dec.Texture = brokenspawnFaces.Smile
			end
		end
	else
		if subvariantName == "AfterHim" then
			if x < 20 then
				dec.Texture = fireringFaces.Shocked
			elseif x < 35 then
				dec.Texture = fireringFaces.VerySad
			elseif x < 50 then
				dec.Texture = fireringFaces.Sad
			elseif x < 70 then
				dec.Texture = fireringFaces.Mad
			elseif x < 99 then
				dec.Texture = fireringFaces.Default
			else
				dec.Texture = "rbxassetid://114605237546200"
			end
		else
			if x < 20 then
				dec.Texture = fireringFaces.Shocked
			elseif x < 35 then
				dec.Texture = fireringFaces.VerySad
			elseif x < 50 then
				dec.Texture = fireringFaces.Sad
			elseif x < 70 then
				dec.Texture = fireringFaces.Mad
			elseif x < 99 then
				dec.Texture = fireringFaces.Default
			else
				dec.Texture = fireringFaces.Happy
			end
		end
	end
end

local function connectHealthEvents()
	disconnectConns()
	
	healthConn = hum.HealthChanged:Connect(function(x)
		if noHealthFX then
			applyChosenFace()
		else
			updateFaceBasedOnHealth(x)
			recolorParts()
		end
	end)
	
	diedConn = hum.Died:Connect(function()
		if variantName == "brokenspawn" and subvariantName == "Default" then
			local existingPants = char:FindFirstChildOfClass("Pants")
			if existingPants then
				existingPants:Destroy()
			end
			local existingShirt = char:FindFirstChildOfClass("Shirt")
			if existingShirt then
				existingShirt:Destroy()
			end
			
			local p = Instance.new("Pants", char)
			p.PantsTemplate = "rbxassetid://18985713079"
			local s = Instance.new("Shirt", char)
			s.ShirtTemplate = "rbxassetid://18985709128"
		end
	end)
end

local function setupCharacter()
	wipeOutStuff()
	recolorParts()
	pickFace("Default")
	
	if noHealthFX then
		applyChosenFace()
	else
		updateFaceBasedOnHealth(hum.Health)
	end
	
	connectHealthEvents()
end

setupCharacter()

plr.CharacterAdded:Connect(function(nc)
	char = nc
	hum = char:WaitForChild("Humanoid")
	
	task.wait(0.1)
	setupCharacter()
end)

local function setNoHealthFX(v)
	noHealthFX = v and true or false
	recolorParts()
	if noHealthFX then
		applyChosenFace()
	else
		updateFaceBasedOnHealth(hum.Health)
	end
end

local function setVariant(v)
	if v == "brokenspawn" or v == "firering" then
		variantName = v
		subvariantName = "Default"
		setupCharacter()
	end
end

local function setSubvariant(v)
	if v == "MarthyrSpawn" or v == "Day4Spawn" or v == "AfterHim" or v == "Default" then
		subvariantName = v
		setupCharacter()
	end
end

local function setFaceByName(name)
	chosenFace = name or "Default"
	pickFace(chosenFace)
	if noHealthFX then
		applyChosenFace()
	end
end

local function setOfficialShirt(v)
	officialShirt = v and true or false
	if variantName == "firering" and subvariantName == "AfterHim" then
		recolorParts()
	end
end

return {
	setNoHealthFX = setNoHealthFX,
	setVariant = setVariant,
	setSubvariant = setSubvariant,
	setFaceByName = setFaceByName,
	setOfficialShirt = setOfficialShirt
}

Features & Information

HEY YOU, YES, YOU, READ THE ENTIRE DESCRIPTION BEFORE MINDLESSLY EXECUTING THE SCRIPT This script changes you into the protagonist and main character from Let Him Go, and After Him. Play Let Him Go. https://www.roblox.com/games/102259817027922/Let-Him-Go noHealthFX if false, enables face changes depending on health, firering's color desaturating depending on health, etc, set it to true if you only want the morph officialshirt is for firering only, if on, makes him use the cape similar to After Him render sneakpeek playable morphs: brokenspawn or firering morphs subvariants brokenspawn: Default, MarthyrSpawn, or Day4Spawn firering: Default or AfterHim brokenspawn's appearance default: standard appearance from Let Him Go. Day4 Spawn: deteriorated, desaturated form from the final day and death scene, including face changes below 50 HP. MarthyrSpawn: nightmare/dream sequence version. firering Default: his appearance during the events of Let Him Go. AfterHim: Post-Let Him Go design from After Him/You’ll Never Let Him Go. treat your brokenspawn and firering well, give them bloxy colas and take care of them, also don't let firering be in a loud crowd or hug him often, he dislikes it.

Community Comments (8)

blepblepDec 10, 2025

nga who the fuhh drew that in the thumbnail

Supervolla4Supervolla4Dec 10, 2025

DEW ☠️

Replying to @Supervolla4
imdisplayimdisplayDec 11, 2025

Mountain Dew

imdisplayimdisplayDec 11, 2025

hi i added more brokens*'s healthfaces and fixed AfterHim firering's shirt texture.

Supervolla4Supervolla4Dec 16, 2025

Bro why kiss? 🥀💔

Replying to @Supervolla4
imdisplayimdisplayDec 17, 2025

❤️

Supervolla4Supervolla4Dec 16, 2025

Sybau 🥀🥀

Supervolla4Supervolla4Dec 18, 2025

@imdisplay look Photo kiss Bro 💀🙏

More Scripts for Universal Scripts