How to script collisions for moving objects in 2d engine?

I have a game that uses a custom 2d engine to simulate circles going around, being controlled by players, sorta like agar.io, however, I ran into a problem when scripting the behaviour of circles when they start colliding with other circles.

What do you want to achieve?

In this scenario, both dots are going in the same direction, but the one on the bottom is going 3 times faster than the first one, and it’s also colliding with it, thus pushing it. What should technically happen is the bottom dot starts pushing the first one and eventually slides around it, but making it behave that way would be too resource intensive for the game, so all I need to do is make the top one get pushed and make sure they don’t clip

What is the issue?

Implementing this in the current script is very difficult. The way it works right now is each tick it loops for every dot and takes the angle a player gives to it and calculates it’s next position.

The full script:

``````local TickSpeed = 1/15 --How many ticks a second

while true do
local NewPositions = {}

for Plr, Properties in pairs(ListOfPlayers) do
local MainFolder = Baseplate.Blobs[Plr.Name]

local Speed = Properties["Speed"]

if Speed > 2 then Speed = 2 end

for _, Blob in pairs(MainFolder:GetChildren()) do
local Count = CountToTable(Blob)

--COLLISIONS
local HitBox = Blob.HitBox

local Parts = HitBox:GetTouchingParts()

local WallCollisions = ""
local BlobCollisions = {}

for _, Item in pairs(Parts) do
if Item.Parent.Name == "Walls" then
WallCollisions = WallCollisions..string.split(Item.Name, "Wall")[2]
end

if Item.Parent.Parent.Name == "Blobs" then
table.insert(BlobCollisions, #BlobCollisions+1, Item.Parent)
end
end

local FrictionX, FrictionY = Friction(WallCollisions, Angle)

local OldPos = Properties["Position"][Count]
local NewPos = Vector3.new(OldPos.X + math.sin(Angle) * Speed * SlowdownX, 1 , OldPos.Z + math.cos(Angle) * Speed * SlowdownY)

if BlobCollisions then
--change the newpos to account for collisions
end

Properties["Position"][Count] = NewPos
HitBox.Position = Properties["Position"][Count]

table.insert(NewPositions, #NewPositions+1, {Plr.Name, Properties["Position"]})
end
end

InterpEvent:FireAllClients(NewPositions)

wait(TickSpeed)
end
``````

My issues are the maths behind the speed changes, the fact that you have to keep track of collisions outside the loop, and making sure the dots don’t clip through eachother. I don’t know how I should go about doing these

What solutions have you tried so far?

I’ve tried taking the distance between the dots and correcting the positions, but it was clunky, probably not compatible with the rest of the script, and I simply got stuck at the other two

Any help on this would be appreciated, thanks!