In 2017, an update was released by roblox which essentially removed friction from the roblox physics engine. This led to physics objects (most notably balls) essentially forever rolling when moved. Of course, people have found ways to simulate friction so balls don’t perpetually roll, however of course, this doesn’t replicate the exact old behaviour that used to occur pre 2017.
This is quite a simple module, all based upon this old forum post by an engineer in 2016, exposing the old formula used to simulate friction. Using this exact formula, we’re able to perfectly match the old behaviour that roblox used to simulate.
You can access the source code here or simply just copy and paste the below code:
--!strict
type Object = Part | BasePart
local RunService = game:GetService("RunService")
local OldFrictionModule = {
SimulationObjects = {} :: {[Object] : boolean},
Connection = nil :: RBXScriptConnection?
}
function OldFrictionModule:AddObject(Part : Object)
if Part:IsA("BasePart") or Part:IsA("Part") then
OldFrictionModule.SimulationObjects[Part] = true
end
end
function OldFrictionModule:RemoveObject(Part : Object)
if OldFrictionModule.SimulationObjects[Part] ~= nil then
OldFrictionModule.SimulationObjects[Part] = nil
end
end
function OldFrictionModule.StartSimulation()
OldFrictionModule.Connection = RunService.Stepped:Connect(function(Time, DeltaTime)
for Part, Index in OldFrictionModule.SimulationObjects do
if Part:IsA("BasePart") or Part:IsA("Part") then
Part.AssemblyAngularVelocity *= math.exp(-0.911328 * DeltaTime)
end
end
end)
end
function OldFrictionModule.StopSimulation()
if OldFrictionModule.Connection ~= nil then
OldFrictionModule.Connection:Disconnect()
OldFrictionModule.Connection = nil
end
end
return OldFrictionModule
Simply require the module and run the function .StartSimulation in order to start running the main code responsible for replicating the old physics. You must also use :AddObject(Part) in order to add objects where the old physics will be applied towards. Please note that you should only add objects that the client (if you’re running this on the client) or the server (if you’re running this on the server) owns, otherwise you’re simply wasting compute (or in the server’s case, just applying physics based on old data relative to the owning client).