Need help for custom spawning system

So im developing a game, and i need to manually respawn player, to do so i disabled the character auto load and used a 15 lines of code to make players spawn, it worked but it gives some problem with the character, it somehow was loading character and then player or something like that and it’s not the best thing to have to be honest. So, i want to make a custom spawn system that follows the roblox spawning process or similar so i dont have problems with character and stuff, but i don’t know how to, or where to start from.

(P.S. I don+t have the old script since i was gonna remake it.)

heres an idea, does it make sense to have the characteraoutload disabled until needed? So like, it doesnt load the character until i enabled it back and then disable it again?

I think LoadCharacter will come in to clutch here for you, you can spawn a player’s character into the game based on your game logic.

Hopefully this is what you are looking for.

old script used loadcharacter, and it broke some of my scripts that where waiting for characteradded, thats the whole issue, and idk why, even my npcs that used humanoid takedamage broke and sometime wroked sometime not

I might have found the old script.

local Players = game:GetService("Players")

Players.CharacterAutoLoads = false

local function onPlayerAdded(player)
	local function onCharacterAdded(character)
		local humanoid = character:WaitForChild("Humanoid")
	end

	player.CharacterAdded:Connect(onCharacterAdded)

	player:LoadCharacter()
end

Players.PlayerAdded:Connect(onPlayerAdded)

it was taken from a documentation i found about spawning and stuff

As mentioned in the documentation, Player.CharacterAdded fires when you call LoadCharacter on the player, I have tested this myself to see if I would run into any issues however, and it worked just fine.

I’m not sure why any script that is using CharacterAdded would break, could you show your script that breaks when using LoadCharacter.

Here is my code

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		-- Respawning player after they die and character gets destroyed
		character.Destroying:Once(function()
			player:LoadCharacter()
		end)
	end)
	
	-- Spawning player after 5 seconds
	task.delay(5, function()
		player:LoadCharacter()
	end)
end)

i have an updated version of this one and it works, but here it is:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local weaponModule = require(ReplicatedStorage.Modules.WeaponModule)

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		character.ChildAdded:Connect(function(child)
			if child:IsA("Tool") and child:FindFirstChild("Shoot") then
				local tool = child

				local shootEvent = tool:WaitForChild("Shoot")
				if shootEvent then
					print("event found")
				end
				shootEvent.OnServerEvent:Connect(function(player, mousePosition)
					print("shot event from server fired")
					weaponModule.Shoot(player, tool, mousePosition)
				end)
			end
		end)
	end)
end)

it stops at player added, doesnt go through the characteradded.
It worked fine before i added the character load script

I believe that your script is running just fine, perhaps it’s getting rejected on the if statement, try printing in the console and see if that’s the case.

bear in mind everytime the character gets resetted (i.e: character dies) the characteradded event gets triggered

OOOOH WAIT, i got it, yes it’s the if cuz i moved the event to another folder and forgot to edit the script, man i feel so dumb rn, i’ve been reading this code for days

Now i might have another issue, and it’s about the npcs, sometime they stop working for some reason, they don’t deal dmg

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

local humanoid = script.Parent
local root = humanoid.Parent.PrimaryPart
root:SetNetworkOwner(nil)

local targetDistance = script:GetAttribute("TargetDistance")
local stopDistance = script:GetAttribute("StopDistance")
local damage = script:GetAttribute("Damage")
local attackDistance = script:GetAttribute("AttackDistance")
local attackWait = script:GetAttribute("AttackWait")
local lastAttack = tick()

local animator = humanoid:WaitForChild("Animator")
local idleAnimation = script:WaitForChild("Idle")
local walkingAnimation = script:WaitForChild("Walking")
local attackAnimation = script:WaitForChild("Attack")

local idleTrack = animator:LoadAnimation(idleAnimation)
local walkingTrack = animator:LoadAnimation(walkingAnimation)
local attackTrack = animator:LoadAnimation(attackAnimation)

idleTrack:Play()

function findNearestPlayer()
	local playerList = Players:GetPlayers()

	local nearestPlayer = nil
	local distance = nil
	local direction = nil
	local position = nil

	for _, player in pairs(playerList) do
		local character = player.Character
		if character and character.Humanoid.Health > 0 then
			local distanceVector = (player.Character.HumanoidRootPart.Position - root.Position)
			if not nearestPlayer then
				nearestPlayer = player
				distance = distanceVector.Magnitude
				direction = distanceVector.Unit
				position = player.Character.HumanoidRootPart.Position
			elseif distanceVector.Magnitude < distance then
				nearestPlayer = player
				distance = distanceVector.Magnitude
				direction = distanceVector.Unit
				position = player.Character.HumanoidRootPart.Position
			end	
		end
	end

	return nearestPlayer, distance, direction, position
end

RunService.Heartbeat:Connect(function()
	local nearestPlayer, distance, direction, position = findNearestPlayer()

	if nearestPlayer and distance < targetDistance and distance > stopDistance then
		local path : Path = PathfindingService:FindPathAsync(root.Position, position)
		if path.Status == Enum.PathStatus.Success then
			local waypoints = path:GetWaypoints()
			if not walkingTrack.IsPlaying then
				walkingTrack:Play()
			end

			if humanoid.FloorMaterial ~= Enum.Material.Air then
				for w, waypoint : PathWaypoint in ipairs(waypoints) do
					local waypointPosition = waypoint.Position
					local waypointAction = waypoint.Action
					if waypointAction == Enum.PathWaypointAction.Jump then
						humanoid.Jump = true
					end
					humanoid:MoveTo(waypointPosition)
					humanoid.MoveToFinished:Wait()
				end
			end
		end
	elseif (nearestPlayer and (distance <= stopDistance or distance > targetDistance)) or not nearestPlayer then
		humanoid:MoveTo(root.Position)
		walkingTrack:Stop()
	end

	if nearestPlayer and distance <= attackDistance and tick() - lastAttack >= attackWait then
		lastAttack = tick()
		local humanoid = nearestPlayer.Character.Humanoid
		if humanoid and humanoid.Health > 0 and humanoid:GetAttribute("Block") == 0 then
			print("tryna deal some dmg bruh")
			attackTrack:Play(0.5,100,1)
			humanoid:TakeDamage(damage)
			task.wait(attackTrack.Length)
		end
	end
end)

script started doing this after the char load script

here, 2 different runs

this is new one, never seen this problem with npcs

Can you show when did the error occur? When you reset, when you walk near them, or when they start attacking.

doesn’t pop up anymore. Seen it as soon as i stopped the test.

well, i don’t need it anymore, thx for everyone for helping somehow, ill close this topic now