player.CharacterAdded not responding for whatever reason

Hi there,
I have problems with some things recently and I want to make this topic so it could be fixed.

1} I am trying to create a framework for Coercion, so it would be easier to manage things.
Right now, I am working on the multiplayer functionality (just in case the game gets more popular).

2} The problem is somehow, “player.CharacterAdded” doesn’t seem to respond at all.
The local script that handles all multiplayer events is located inside StarterPlayerScripts.

3} I’ve tried making a custom characterChecker which didn’t work, and at one point used ChatGPT (gpt 3) as a last resort, but nothing worked.

No, that doesn’t mean the respawn mechanic doesn’t work. It works, but I have to use commands to get it to work.
No, the player respawn time isn’t set to infinity or deactivated in some way. It automatically detects if the respawn time is math.huge to it basically deactivates the respawn mechanic.

Client code:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local SpawnPlayerEvent = ReplicatedStorage:WaitForChild("SpawnPlayerEvent")
local PlayerDiedEvent = ReplicatedStorage:WaitForChild("PlayerDiedEvent")

local function characterChecker(plr: Player)
	if workspace:FindFirstChild(plr.Name) then
		return workspace:FindFirstChild(plr.Name)
	else
		task.wait(0.1) -- so it doesn't crash studio
		characterChecker(plr) -- in case the character is still loading
	end
end

Players.PlayerAdded:Connect(function(player)
	if characterChecker(player) then
		print("character loaded", game.HttpService:GenerateGUID(false))
	end
end)

SpawnPlayerEvent:FireServer()

module code:

local SilencingEngine = require(script.Parent)
local TimerService = SilencingEngine:GetModule("TimerService")

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local function AddItem(name, classname, parent)
	local item

	if not parent:FindFirstChild(name) then
		item = Instance.new(classname)
		item.Parent = parent
		item.Name = name

		return item
	else
		item = parent:FindFirstChild(name)
		return item
	end
end

-- for multiplayer functionality
local SpawnPlayerEvent
local PlayerDiedEvent

if RunService:IsServer() then
	SpawnPlayerEvent = AddItem("SpawnPlayerEvent", "RemoteEvent", ReplicatedStorage)
	PlayerDiedEvent = AddItem("PlayerDiedEvent", "RemoteEvent", ReplicatedStorage)
end

if RunService:IsClient() then
	SpawnPlayerEvent = ReplicatedStorage:WaitForChild("SpawnPlayerEvent")
	PlayerDiedEvent = ReplicatedStorage:WaitForChild("PlayerDiedEvent")
end

local module = {}

function module:LoadCharacter(plr, customCharacter, character)
	customCharacter = customCharacter or false

	local function tptoSpawn(plr)
		if workspace:FindFirstChild("SpawnLocation") then
			plr.Character:SetPrimaryPartCFrame(CFrame.new(workspace:WaitForChild("SpawnLocation").Position + Vector3.new(0, workspace:WaitForChild("SpawnLocation").Size.Y / 2, 0)))
		else
			plr.Character:SetPrimaryPartCFrame(CFrame.new(workspace:WaitForChild("Baseplate").Position + Vector3.new(0, workspace:WaitForChild("Baseplate").Size.Y / 2, 0)))
		end
	end

	local function createChar(plr)
		if customCharacter then
			plr:LoadCharacter()
			TimerService:Delay() -- adds a very small delay since it's using os.clock
			local Ccharacter = character:Clone()
			Ccharacter.Name = plr.Name

			plr.Character = Ccharacter
			Ccharacter.Parent = workspace

			tptoSpawn(plr)
		else
			plr:LoadCharacter()
			tptoSpawn(plr)
		end
	end

	local function respawnChar(plr)
		plr.CharacterAdded:Connect(function(char)
			tptoSpawn(plr)
			char:WaitForChild("Humanoid").Died:Connect(function()
				PlayerDiedEvent:FireServer()
			end)
		end)
	end

	if RunService:IsClient() then
		Players.PlayerAdded:Connect(function(plr)
			SpawnPlayerEvent:FireServer()

			local char = plr.CharacterAdded:Wait()

			if char then
				char:WaitForChild("Humanoid").Died:Connect(function()
					PlayerDiedEvent:FireServer()
				end)
			end
		end)
	end

	if RunService:IsServer() then
		SpawnPlayerEvent.OnServerEvent:Connect(function(lplr)
			createChar(lplr)
			print("player spawned")
		end)

		PlayerDiedEvent.OnServerEvent:Connect(function(lplr)
			print("player died")
			if Players.RespawnTime < math.huge then
				TimerService:Delay(Players.RespawnTime)
				createChar(lplr)
				print("player respawned")
			end
		end)
	end
end

function module:SetAttribute(plr, Attribute, value)
	if plr:GetAttribute(Attribute) then
		plr:SetAttribute(Attribute, value)
	else
		plr:SetAttribute(Attribute, value) -- creates an attribute if it doesn't already exist.
	end
end

function module:SetStat(plr, Stat, value)
	local function changeStat(plr, Stat, value)
		local function hasProperty(object, prop)
			local t = object[prop] -- this is just done to check if the property existed, if it did nothing would happen, if it didn't an error will pop, the object[prop] is a different way of writing object.prop, (object.Transparency or object["Transparency"])
		end

		if plr.Character then
			local success = pcall(function()
				hasProperty(plr.Character:WaitForChild("Humanoid"), Stat)
			end)

			if success then
				plr.Character:WaitForChild("Humanoid")[Stat] = value
			end
		else
			TimerService:Delay(0.1) -- small delay so it doesn't crash studio, might change later.
			changeStat(plr, Stat, value) -- retry until there is a character found.
		end
	end

	changeStat(plr, Stat, value)
end

return module

Thank you for reading.

youve got to
call the function
in order for it to set up the connection

youre just defining the function, and telling it what to do
youre not really
telling it to run

the rest of the functions are inside the module, waiting to be called by a singular remote event
the spawnplayerevent gets called in a local script which in turn activates some sort of a system that awaits a call for when the player dies.
you’re not exactly helping me with those replies.

When you mentioned local script I immediately knew:

its likely that when loading in, PlayerAdded doesn’t connect until after you the player, have already loaded in

you will need to utilize the method OnPlayerAdded

function OnPlayerAdded(player)

if characterChecker(player) then
		print("character loaded", game.HttpService:GenerateGUID(false))
	end

end

for i, plr in pairs (Players:GetPlayers()) do
OnPlayerAdded(plr)
end

Players.PlayerAdded:Connect(function(player)
	OnPlayerAdded(player)
end)
game.Players.PlayerAdded:Connect(function(player)
    player.CharacterAdded:Connect(function(character)
        -- stuff
    end)
end)

i wanted a custom character detector, since characteradded doesn’t always work at times (tho rare.)

you made a function called respawnchar

where are you calling it???

if you dont call respawnchar, player.CharacterAdded will also never call
because you have to call a function to run its code