Lagging problems with game

I am making a game like slitherio and whenever the players eat food their snakes gets larger.The problem is that if the snake gets too big it causes a lot of lag

local previouspart = nil
local distance = 2
local numberofballs = 5
local total = numberofballs
local hrp
local char = game.Players.LocalPlayer.Character
local db = true
local limit = 400
local part
local goal

wait()

for i = 1,numberofballs,1 do

	part = Instance.new("Part",game.Workspace)
	part.Anchored = true
	part.Material = Enum.Material.SmoothPlastic
	part.Shape = "Ball"
	part.BrickColor = BrickColor.random()
	part.CanCollide = false
	part.Massless = true
	--[[local bodyposition = Instance.new("BodyPosition",part)
	bodyposition.P = 10000
	bodyposition.D = limit
	bodyposition.MaxForce = Vector3.new(99999,999999,999999)]]--

	hrp = char.HumanoidRootPart

	if i == 1 then
		part.Position = hrp.Position - hrp.CFrame.LookVector*2
		part.Name = "Part1"
	else
		part.Position = previouspart.Position - previouspart.CFrame.LookVector*distance
		part.Name = "Part"..i
	end


	previouspart = part

	wait()
end

spawn(function()
	while task.wait() do

			for i = 1,numberofballs,1 do
				local partfound = game.Workspace:FindFirstChild("Part"..i)

				if partfound then

					if partfound.Name == "Part1" then

						spawn(function()
							for x = 0,1,0.01 do
								goal = hrp.Position - hrp.CFrame.LookVector*2
								partfound.Position = partfound.Position:Lerp(goal,x)
								task.wait()
							end
						end)


					elseif partfound ~= nil then

					spawn(function()
						for x = 0,1,0.005 do
							goal = game.Workspace:FindFirstChild("Part"..i-1).Position - game.Workspace:FindFirstChild("Part"..i-1).CFrame.LookVector*Vector3.new(1,0,1)*distance
							partfound.Position = partfound.Position:Lerp(goal,x)
							task.wait()
						end
					end)

					end

					partfound.CFrame = CFrame.new(partfound.Position,hrp.Position)
				end

			end

	end
end)

wait(1)


spawn(function()
	while true do

		for i, v in pairs(game.Workspace:GetChildren()) do

			if game.ReplicatedStorage.food:FindFirstChild(v.Name) then

				v.Touched:Connect(function(hit)
					if hit.Parent:FindFirstChild("Humanoid") and db then

						print("length:"..total+1)
						db = false

						v:Destroy()

						part = Instance.new("Part",game.Workspace)
						part.Anchored = true
						part.Material = Enum.Material.SmoothPlastic
						part.Shape = "Ball"
						part.BrickColor = BrickColor.random()
						part.CanCollide = false
						part.Massless = true
						part.Position = game.Workspace:FindFirstChild("Part"..numberofballs).Position - game.Workspace:FindFirstChild("Part"..numberofballs).CFrame.LookVector*Vector3.new(1,0,1)*distance
						part.Name = "Part"..numberofballs+1
						
						numberofballs += 1
						
						--[[local bodyposition = Instance.new("BodyPosition",part)
						bodyposition.P = 10000
						bodyposition.D = limit
						bodyposition.MaxForce = Vector3.new(99999,999999,999999)--]]

						wait(0.1)
						db = true

					end
				end)
			end

		end
		wait()
	end
end)

There is an alternative version of your code of how your code can be optimized. But let’s talk about this

for x = 0,1,0.005 do
	goal = game.Workspace:FindFirstChild("Part"..i-1).Position - game.Workspace:FindFirstChild("Part"..i-1).CFrame.LookVector*Vector3.new(1,0,1)*distance
	partfound.Position = partfound.Position:Lerp(goal,x)
	task.wait()
end

The code above can probably cause a lag. Since you are using Lerp for smooth movement of the part. But Lerp function also does calculate distance between 2 points, so you create the loop and lerp it within milliseconds which is really unnecessary. Even that, this loop is place inside another loop. the loop inside spawn has 200 iterations (0,1,0.005) and each of this loop will be multiplied by numberofballs. Let’s say you have 5 balls in you game, that will result in 1,000 iteration in total. Adding numbers for 1,000 times is not heavy, but your method recalculate position for 1,000 times over and over again. Even the loop is inside the spawn which is multi-threaded, it can result in lag at some points.

Alternative version of your code could be try implementing RunService and use Heartbeat for better performance. AlignPosition and AlignOrientation can also be implemented.

3 Likes

The reason why i used such a small number is so it has a snake movement.Also i used alignposition and it didnt work that well

Understood, you can then use AlignPosition and AlignOrientation for the movement.

What is wrong with that? Have you tried configuring Responsiveness or other values?

i will try to use alignposition to see if it works

You have a lot of loops and loops within loops going on here. One thing that should help you is to not repeatedly loop through all children of game.Workspace and add a touch handler. You are adding a touch handler to the same food parts over and over again like every 1/60th of a second which is a lot of overhead. You should add the touch handler only when that piece of food is created. You might also look up using TAGS to tag something as food so it will set up your generic touch handler the moment you create something and tag it as food.

The best way to implement this is to use attach both AlignPosition and AlignOrientation on each joint of your snake. The first joint will be only one that control direction of your snake. AlignPosition and AlignOrientation in other joints will do the job. I have never implemented this, but I think it is a good approach.

The structure will be like this

AP = AlignPosition
AO = AlignOrientation

First Joint <— AP,AO ---- Second Joint <— AP,AO — Third Joint. And so on.

should the mode of the alignposition be oneattachment or twoattachments

I believe using two attachments will be a good approach on this one.

image

I dont know how alignposition works so i cant really use it

It is really simple! So basically, Attachment1 will try its best to relocate its position to be close Attachment0. Same thing with AlignOrientation that it will try to relocate the orientation.

for some reason the position property of the alignposition doesnt work,it just doesnt change anything

Only Attachment1, and Attachment0 are important, you can adjust also adjust speed of that by adjusting MaxForce MaxVelocity, or Responsiveness. Try playing around with those values and see how they affect the movement.

the snake is made up by balls and each ball is behind the other.AlignPosition just makes all the balls be in the same position

Then try creating an attachment behind those balls, and use AlignPosition to that Attachment instead.

image

after some hours i got it to work although a small problem with it is that the tail of the snake kinda points up

Can you attach with some videos or images?

robloxapp-20230303-2014134.wmv (2.2 MB)
The balls get flinged when i turn around

Have you used AlignOrientation yet?, or you can try increasing Responsiveness on each AlignPosition. Too low, your model will fling too much, Too high, your model will fling less, but in an unnatural way. Try finding a sweet spot for the value.

Looking good so far by the way!