Trying to combine 4 scripts into one script to reduce lag

I have 4 scripts all about character movement. And my game lags after a certain amount of time, my first thought was there being 4 different scripts managing movement, so I chose to combine them into one but I can’t do it despite there being no errors.
Is there a way to achieve my goal?

Here’s the sliding script

local player = game:GetService("Players").LocalPlayer
local UIS = game:GetService("UserInputService")
local char = player.Character or player.CharacterAdded:Wait()
repeat wait() until char:FindFirstChild("Humanoid")
local hum = char.Humanoid

local slideAnim = Instance.new("Animation")
slideAnim.AnimationId = "rbxassetid://138198101465383" -- Enter your AnimtionID

local keybind = Enum.KeyCode.LeftShift -- between the key for ability
local canslide = true

function slide()
		if canslide == true then
		hum.JumpPower = 0
		canslide = false
		script.SFX:Play()
		local playAnim = char.Humanoid:LoadAnimation(slideAnim)
		playAnim:Play()

		local slide = Instance.new("BodyVelocity")
		slide.MaxForce = Vector3.new(1,0,1) * 10000
		slide.Velocity = char.HumanoidRootPart.CFrame.lookVector * char.Humanoid.WalkSpeed
		slide.Parent = char.HumanoidRootPart

		for count = 1, 8 do
			wait(0.1)
			slide.Velocity*= 1.100
		end
		playAnim:Stop()
		slide:Destroy()
		canslide = true
		hum.JumpPower = 50
	end
end

UIS.InputBegan:Connect(function(i, c)
	if i.KeyCode == Enum.KeyCode.LeftShift then
		if c then return end
		slide()
	end
end)

Here’s the vaulting script

local plr = game:GetService("Players").LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()
local HRP = char:WaitForChild("HumanoidRootPart")
local Hum = char:WaitForChild("Humanoid")
local CA = Hum:LoadAnimation(script:WaitForChild("ClimbAnim"))
local ledgeavail = true

while game:GetService("RunService").RenderStepped:Wait() do
	local r = Ray.new(HRP.Position, HRP.CFrame.LookVector * 5 + HRP.CFrame.UpVector * -3)
	local part = workspace:FindPartOnRay(r,char)

	if part and ledgeavail then
		if part.Name == "Vault" then
			if Hum.FloorMaterial ~= Enum.Material.Air then
				ledgeavail = false
				local Vel = Instance.new("BodyVelocity")
				Vel.Parent = HRP
				Vel.Velocity = Vector3.new(0,0,0)
				Vel.MaxForce = Vector3.new(1,1,1) * math.huge
				Vel.Velocity = HRP.CFrame.LookVector * 20 + Vector3.new(0,22.5,0)
				CA:Play()
				game.Debris:AddItem(Vel, .15)
				wait(0.75)
				CA:Stop()
				ledgeavail = true
				Vel:Destroy()
			end
		end
	end
end

Here’s the wallrun script

local c = script.Parent

local holdingKey = false
local jumped = false

local uis = game:GetService("UserInputService")

local leftAnim = c.Humanoid:LoadAnimation(script:WaitForChild("WallrunLeft"))
local rightAnim = c.Humanoid:LoadAnimation(script:WaitForChild("WallrunRight"))

c.Humanoid:GetPropertyChangedSignal("Jump"):Connect(function()
	wait(0.1)
	jumped = true
	wait(0.25)
	jumped = false
end)

uis.InputBegan:Connect(function(inp, p)

	if not p and jumped == true and inp.KeyCode == Enum.KeyCode.Space then

		holdingKey = true
	end
end)

uis.InputEnded:Connect(function(inp)

	if inp.KeyCode == Enum.KeyCode.Space then

		holdingKey = false
	end
end)
	

game:GetService("RunService").Heartbeat:Connect(function()
	
	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Exclude; raycastParams.FilterDescendantsInstances = {c}; raycastParams.IgnoreWater = true
	
	local rayL = workspace:Raycast(c.HumanoidRootPart.CFrame.Position, -c.HumanoidRootPart.CFrame.RightVector * 3, raycastParams)
	local rayR = workspace:Raycast(c.HumanoidRootPart.CFrame.Position, c.HumanoidRootPart.CFrame.RightVector * 3, raycastParams)
	
	local ray = rayL or rayR
	
	if ray and holdingKey then
		
		if ray == rayL then
			if not leftAnim.IsPlaying then leftAnim:Play() end
			rightAnim:Stop()
			
		else
			if not rightAnim.IsPlaying then rightAnim:Play() end
			leftAnim:Stop()
		end
		
		local part = ray.Instance
		
		local weld = c.HumanoidRootPart:FindFirstChild("WallrunWeld") or Instance.new("WeldConstraint")
		weld.Name = "WallrunWeld"
		weld.Part0 = c.HumanoidRootPart
		weld.Part1 = part

		local bp = c.HumanoidRootPart:FindFirstChild("WallrunBodyPosition") or Instance.new("BodyPosition")
		bp.Parent = c.HumanoidRootPart
		bp.Name = "WallrunBodyPosition"
		bp.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
		bp.Position = c.HumanoidRootPart.Position + c.HumanoidRootPart.CFrame.LookVector * c.Humanoid.WalkSpeed / 3
			
	else
			
		for i, child in pairs(c.HumanoidRootPart:GetChildren()) do

			if child.Name == "WallrunWeld" or child.Name == "WallrunBodyPosition" then

				child:Destroy()
			end
		end
		
		leftAnim:Stop()
		rightAnim:Stop()
	end
end)

Here’s the ledge grab script

local plr = game.Players.LocalPlayer
local Character = plr.Character or plr.CharacterAdded:Wait()
local Root = Character:WaitForChild("HumanoidRootPart")
local Head = Character:WaitForChild("Head")
local Hum = Character:WaitForChild("Humanoid")
local CA = Hum:LoadAnimation(script:WaitForChild("ClimbAnim"))
local HA = Hum:LoadAnimation(script:WaitForChild("HoldAnim"))
local TouchGui = plr:WaitForChild("PlayerGui"):FindFirstChild("TouchGui")
local UIS = game:GetService("UserInputService")
ledgeavailable = true
holding = false

while game:GetService("RunService").Heartbeat:Wait() do
	local r = Ray.new(Head.CFrame.p, Head.CFrame.LookVector * 5)
	local part,position = workspace:FindPartOnRay(r,Character)
	
	if part and ledgeavailable and not holding then
		if part.Size.Y >= 7 then
			if Head.Position.Y >= (part.Position.Y + (part.Size.Y / 2)) - 1 and Head.Position.Y <= part.Position.Y + (part.Size.Y / 2) and  Root.Velocity.Y <= 0 then
				Root.Anchored = true holding = true HA:Play() ledgeavailable = false
			end
		end
	end
	
	function climb()
		local Vele = Instance.new("BodyVelocity")
		Vele.Parent = Root
		Root.Anchored = false
		Vele.MaxForce = Vector3.new(1,1,1) * math.huge
		Vele.Velocity = Root.CFrame.LookVector * 10 + Vector3.new(0,30,0)
		HA:Stop() CA:Play()
		game.Debris:AddItem(Vele,.15)
		holding = false
		wait(.75)
		ledgeavailable = true
	end
	
	UIS.InputBegan:Connect(function(Key,Chat)
		if not holding then return end 
		if Key.KeyCode == Enum.KeyCode.Space and not Chat then
			climb()
		end
	end)
	
	if TouchGui then
		TouchGui:WaitForChild("TouchControlFrame"):WaitForChild("JumpButton").MouseButton1Click:Connect(function()
			if not holding then return end climb()
		end)
	end
end

combining multiple scripts into 1 will not improve performance. If anything it makes it harder to read and maintain. The reason your systems lags is because you’re connecting new events inside of your heartbeat loop without ever disconnecting them.

Your issue is the green part.

while game:GetService("RunService").Heartbeat:Wait() do
	local r = Ray.new(Head.CFrame.p, Head.CFrame.LookVector * 5)
	local part,position = workspace:FindPartOnRay(r,Character)
	
	if part and ledgeavailable and not holding then
		if part.Size.Y >= 7 then
			if Head.Position.Y >= (part.Position.Y + (part.Size.Y / 2)) - 1 and Head.Position.Y <= part.Position.Y + (part.Size.Y / 2) and  Root.Velocity.Y <= 0 then
				Root.Anchored = true holding = true HA:Play() ledgeavailable = false
			end
		end
	end
	
	function climb()
		local Vele = Instance.new("BodyVelocity")
		Vele.Parent = Root
		Root.Anchored = false
		Vele.MaxForce = Vector3.new(1,1,1) * math.huge
		Vele.Velocity = Root.CFrame.LookVector * 10 + Vector3.new(0,30,0)
		HA:Stop() CA:Play()
		game.Debris:AddItem(Vele,.15)
		holding = false
		wait(.75)
		ledgeavailable = true
	end
	
+	UIS.InputBegan:Connect(function(Key,Chat)
+		if not holding then return end 
+		if Key.KeyCode == Enum.KeyCode.Space and not Chat then
+			climb()
+		end
+	end)
	
+	if TouchGui then
+		TouchGui:WaitForChild("TouchControlFrame"):WaitForChild("JumpButton").MouseButton1Click:Connect(function()
+			if not holding then return end climb()
+		end)
+	end
end

Need someone to fact check me on almost everything here, so take it with a grain of salt:

I think having one script over four separate scripts controlling a movement system would only marginally decrease lag and increase performance.

Performance depends on whether or not your scripts are well optimised, garbage collected efficiently, having no unnecessary unused variables, and yada-yada. From what I can tell in your script, you have loops running, which isn’t necessarily a bad thing, but the question is:

Are they being handled effectively in the sense where it’s called when necessary and are they cleaned up efficiently after usage?

No it would not. For example, 4 scripts use 25℅ so if you combine it, it would be 100℅ in one script so there’s not really a difference. Also, thing’s that the player cannot see like folders barely affect a players experience. I’ve seen games with hundreds of modules and scripts yet they ran very well. All that matters is how optimized your code is. Tbh I’d rather have 250-500 lines per script than 1k+ in one

1 Like

they use bodyposition and bodyposition so maybe that’s the issue since they’re deprecated?

Deprecated objects will have no effect on performance.

Unless the object that supersedes that deprecated object is stated to be more performant than it’s predecessor.

I personally believe it to be the case of inefficiently handled instances, loops, etc.

Thank you for your input. I respect it, but I feel like it did not provide any changes towards my original post.

As stated in my original post, it only marginally decreases lag and performance, as this is factored by the scripts not sharing one environment and may possibly duplicate variables across separate scripts.

Once again, I thank and respect your input, and I agree that all it comes down to is code optimisation and maintainability.

thanks for the knowledge. including @sonic_848 both of y’all educated me

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.