My module script causes everything to lag once a the Follower.new is done

I’ve never had a crash in a long time but seems this script wanted to turn that around. Why does it cause the follower (the one that is cloned) to have ALL its scripts say this?:

Script:

local RS = game:GetService("ReplicatedStorage")
local FollowerFolder = RS:WaitForChild("Followers")

local physicsService = game:GetService('PhysicsService')

physicsService:CreateCollisionGroup("Follower") 

physicsService:CollisionGroupSetCollidable('Follower', 'Default', false)
physicsService:CollisionGroupSetCollidable('Follower', 'Follower', false)

local Follower = {}

local function SetCollision(follower : Model)
	for i,v in ipairs(follower:GetDescendants()) do
		if not v:IsA('BasePart') then
			continue
		end
		physicsService:SetPartCollisionGroup(v, "Follower")
	end
end

function Follower.New(Player, Follower, Force)
	if Player then
		local character = Player.Character
		if character then
			local humanrootpart = character.HumanoidRootPart
			local newFollower = FollowerFolder:FindFirstChild(Follower):Clone()
			newFollower.Parent = workspace.Effects
									
			SetCollision(newFollower)
			
			newFollower.PrimaryPart.Active:Play()
			newFollower.PrimaryPart.Moving:Play()
						
			local bodyPos = Instance.new("BodyPosition", newFollower.PrimaryPart)
			bodyPos.MaxForce = Vector3.new(Force / 4, Force, Force / 4)

			local bodyGyro = Instance.new("BodyGyro", newFollower.PrimaryPart)
			bodyGyro.MaxTorque = Vector3.new(Force / 4, Force, Force / 4)

			while true do
				task.wait(0.1)
				bodyPos.Position = humanrootpart.Position + Vector3.new(-50, 0, 0)
				bodyGyro.CFrame = humanrootpart.CFrame
			end
		end
	end
end

function Follower.Destroy(Player, Follower)
	if Player then
		local character = Player.Character
		if character then
			local humanrootpart = character.HumanoidRootPart
			local currentFollower = workspace.Effects:FindFirstChild(Follower)
			currentFollower:Destroy()
		end
	end
end

return Follower

I have three questions,

  • A: is Follower in the function a string
  • B: does SetCollision(follower : Model) deal with many descendants
  • C: If all the followers have the same collisionGroup, why edit it on creation.

Follower is classed as a string, I fixed the collision groups and will test that now.

EDIT: It still crashes:

local RS = game:GetService("ReplicatedStorage")
local FollowerFolder = RS:WaitForChild("Followers")

local physicsService = game:GetService('PhysicsService')

local Follower = {}

function Follower.New(Player, Follower, Force)
	if Player then
		local character = Player.Character
		if character then
			local humanrootpart = character.HumanoidRootPart
			local newFollower = FollowerFolder:FindFirstChild(Follower):Clone()
			newFollower.Parent = workspace.Effects
												
			newFollower.PrimaryPart.Active:Play()
			newFollower.PrimaryPart.Moving:Play()
						
			local bodyPos = Instance.new("BodyPosition", newFollower.PrimaryPart)
			bodyPos.MaxForce = Vector3.new(Force / 4, Force, Force / 4)

			local bodyGyro = Instance.new("BodyGyro", newFollower.PrimaryPart)
			bodyGyro.MaxTorque = Vector3.new(Force / 4, Force, Force / 4)

			while true do
				task.wait(0.1)
				bodyPos.Position = humanrootpart.Position + Vector3.new(-50, 0, 0)
				bodyGyro.CFrame = humanrootpart.CFrame
			end
		end
	end
end

function Follower.Destroy(Player, Follower)
	if Player then
		local character = Player.Character
		if character then
			local humanrootpart = character.HumanoidRootPart
			local currentFollower = workspace.Effects:FindFirstChild(Follower)
			currentFollower:Destroy()
		end
	end
end

return Follower

Remove the while loop at the end and see if it still crashes.

The one that moves the follower as that is the one that moves the ghost?

EDIT: It is not the module that causes the error, heres one of the scripts that sorts out the main stuff:

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

local Remotes = ReplicatedStorage:WaitForChild("Remotes")
local Modules = ReplicatedStorage:WaitForChild("Modules")

local FollowerModule = require(Modules:WaitForChild("Follower"))

local Event = Remotes:WaitForChild("AddBomb")
local TransitionRE = Remotes:WaitForChild("TransitionRE")

Event.OnServerEvent:Connect(function(player, Type)
	if player ~= nil then
		local Character = player.Character or player.CharacterAdded:Wait()
		local Target = Character.HumanoidRootPart	
		
		if Type == "START" then
			local Bomb = ReplicatedStorage.Bomb:Clone()
			--TransitionRE:FireClient(player, "RUN FOR YOUR LIFE! BIG GREG IS HAUNTING", string.upper(player.DisplayName), 5) -- name of ghost that chases you lol
						
			Bomb.Parent = Character
			--Bomb.CFrame = Character.Back_1.Handle.CFrame
			FollowerModule.New(player, "BigGreg", 10000000)
			
			local StorageFolder = Instance.new("Folder", Lighting.Storage)
			StorageFolder.Name = player.UserId
			Character.Back_1.Parent = StorageFolder

			local ActualPlayer = game.Players:GetPlayerFromCharacter(Character)
			local PlayerUI = ActualPlayer.PlayerGui
			local Timer = PlayerUI.Timer.TimerHolder

			if Timer:FindFirstChild("DeathTimer") then
				local UI = Timer.DeathTimer

				UI.Timer.Changed:Connect(function()
					if Timer.Text <= 60 then
						Bomb.Handle.Beeper.ParticleEmitter.Rate += 0.75
					else
						Bomb.Handle.Beeper.ParticleEmitter.Rate = 0.5
					end
				end)
			end
		elseif Type == "END" then
			if Character:FindFirstChild("Bomb") then
				Character:FindFirstChild("Bomb"):Destroy()
				if Lighting.Storage:FindFirstChild(tostring(player.UserId)) then
					Lighting.Storage:FindFirstChild(tostring(player.UserId)):Destroy()
					
					FollowerModule.Destroy(player, "BigGreg")
									
					ReplicatedStorage.Remotes.TimerRE:Fire(0, "FixGUIs")
					Lighting.Storage:FindFirstChild(tostring(player.UserId)).Back_1.Parent = Character		
				end
			end
		end
	end
end)

isn’t this the only loop?

char limit

1 Like

I don’t see any loops here, unless an event fires one, and most likely the other loop I mentioned is fine, so any other loops might be a problem.

I figured out what happens, my script seems to break ONCE I fire the bomb event. Are too many things happening and if so how could I simplify my code?

The main cause could be this painful script that I need to sort out:

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

local Player = game:GetService("Players").LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()

local Lighting = game:GetService("Lighting")
local DeathwishMusic = Lighting:WaitForChild("DeathWish"):WaitForChild("DeathwishMusic")

function StartTimer(startValue, Type)

	if Type == nil then return end

	local tweenInfo = TweenInfo.new(startValue)

	local Timer

	if Type == "Death" then
		Timer = script.DeathTimer:Clone()
		local FX = script.Flash:Clone()
		FX.Parent = Timer
		FX.Enabled = true
	else
		Timer = script.CircleTimer:Clone()
	end


	Timer.Parent = script.Parent.TimerHolder

	--print("timer started")

	local TextLabel = Timer.Timer

	for i, ui in pairs(Timer:GetDescendants()) do
		if ui:IsA("ImageLabel") then
			ui.ImageTransparency = 1
			TweenService:Create(ui, TweenInfo.new(0.5), {ImageTransparency = 0}):Play()
		end
	end

	local leftFrame = Timer:WaitForChild("LeftBG"):WaitForChild("LeftFrame")
	local rightFrame = Timer:WaitForChild("RightBG"):WaitForChild("RightFrame")

	local LColor = leftFrame:WaitForChild("LeftBG")
	local RColor = rightFrame:WaitForChild("RightBG")

	local ColorTween1 = TweenService:Create(LColor, TweenInfo.new(0.5), {ImageColor3 = Color3.fromRGB(255,255,255)})
	local ColorTween2 = TweenService:Create(RColor, TweenInfo.new(0.5), {ImageColor3 = Color3.fromRGB(255,255,255)})

	local numValue = Instance.new("NumberValue")

	numValue.Changed:Connect(function()

		local rightRot = math.clamp(numValue.Value - 180, -180, 0)

		rightFrame.Rotation = rightRot


		if numValue.Value <= 180 then
			leftFrame.Visible = false
		else

			local leftRot = math.clamp(numValue.Value - 360, -180, 0)
			leftFrame.Rotation = leftRot
			leftFrame.Visible = true
		end
	end)

	local function progressBar()
		numValue.Value = 0
		local progressTween = TweenService:Create(numValue, tweenInfo, {Value = 360})
		progressTween:Play()
	end

	spawn(function()
		progressBar()

		for i= startValue, 0, -1 do
			task.wait(Timer.TickAmount.Value)
			Timer.Tick:Play()
			TextLabel.Text = string.format("%02d", i)
			if not Character:FindFirstChild("Bomb") then
				for i, ui in pairs(Timer:GetDescendants()) do
					if ui:IsA("ImageLabel") then
						ui.ImageTransparency = 1
						TweenService:Create(ui, TweenInfo.new(0.5), {ImageTransparency = 1}):Play()
					end
					task.wait(0.65)
					Timer:Destroy()
				end
				break
			end
		end
	end)

	TextLabel:GetPropertyChangedSignal("Text"):Connect(function()
		local Bomb = nil
		local Signal = nil
		local Emitter = nil

		local Fast = nil
		local Slow = nil
		local Medium = nil

		if Type == "Death" then
			Bomb = Character.Bomb
			Signal = Bomb.Handle.Signal
			Emitter = Bomb.Handle.Beeper.ParticleEmitter

			Fast = Signal.Fast
			Slow = Signal.Slow
			Medium = Signal.Medium
			
			if TextLabel.Text == "20" then
				script.DeathEnd:Play()
				--
				Fast.Enabled = true
				Slow.Enabled = false
				Medium.Enabled = false
				--
				Emitter.Rate = 15
				TweenService:Create(DeathwishMusic, tweenInfo, {Volume = DeathwishMusic.Volume / 2}):Play()
				task.wait(3)
				script.Laugh:Play()

			elseif TextLabel.Text < "60" then
				Emitter.Rate = 10
				--
				Fast.Enabled = false
				Slow.Enabled = false
				Medium.Enabled = true
				--
			end

			if TextLabel.Text == "00" or Character.Humanoid.Health == 0 then
				Emitter.Rate = 20
				script.Death:Play()
				script.Fail:Play()
				DeathwishMusic:Stop()

				local Explosion = Instance.new("Explosion", Character.HumanoidRootPart)
				game:GetService("Debris"):AddItem(Explosion, 1.25)
				ReplicatedStorage.Remotes.Explosion:FireServer()

				Character.Humanoid.Health = 0

				for i, ui in pairs(Timer:GetDescendants()) do
					if ui:IsA("ImageLabel") then		
						TweenService:Create(ui, TweenInfo.new(0.5), {ImageTransparency = 1}):Play()
					elseif ui:IsA("TextLabel") then
						TweenService:Create(ui, TweenInfo.new(0.5), {TextTransparency = 1}):Play()
					end
				end
			end
		end

		if TextLabel.Text == "00" and Type == "Normal" then
			ColorTween1:Play()
			ColorTween2:Play()
			ColorTween2.Completed:Wait()

			local TextTween = TweenService:Create(TextLabel, TweenInfo.new(0.5), {TextTransparency = 1})
			TextTween:Play()

			for i, ui in pairs(Timer:GetDescendants()) do
				if ui:IsA("ImageLabel") then		
					TweenService:Create(ui, TweenInfo.new(0.5), {ImageTransparency = 1}):Play()
				end
			end

			TextTween.Completed:Wait()
			Timer:Destroy()
		end
	end)
end

ReplicatedStorage.Remotes.TimerRE.Event:Connect(function(timerValue, Type)
	if Type == "Death" then
		StartTimer(268, "Death")
		script.DeathStart:Play()
		task.wait(0.5)
		DeathwishMusic:Play()
		task.wait(3.5)
		script.Laugh:Play()
	elseif Type == "Normal" then
		StartTimer(timerValue, Type)
	end
end)


How long is the Timer.TickAmount.Value, becasue I cannot see any other issue with this code.

Have you tried setting the loop in a different thread?

Try using task.spawn instead of the old spawn function, it could have something to do with that, and nonetheless a good practice.

1 Like

I mostly see it as untidy due to the whole, if statement spam.