[RETRO] Replicate roblox's physics from before 2017

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).

13 Likes

Anyway to get the explosiveness of 2017 physics?

could you make an example code of the require script with the function n stuff?
also why do you need to apply the old physics to each part separately by scripting? why not have an option to just apply everything via tags?

other than that, this looks pretty interesting! keep up the good work.

Can you show an example of this ‘explosiveness’? A before and after would be very helpful

local Module = require(PathToModule)

Module.StartSimulation()

Module:AddObject(Part)

task.wait(5) – Assume the part is no longer being simulated by the player

Module:RemoveObject(Part)

You can easily fork the module to allow for just looping over a group of tags, there’s no reason why this wouldn’t be possible.

thanks! does this work on player models too? (like for example: in a 2016 client, when you walk into a wall and repeatedly go left then right, your character rotates left and right instead of just looking in one direction)

Probably not, no sorry

I’d imagine you could replicate the same behavior with the new humanoid controllers though

I believe he’s talking about this, shown at the very beginning of the video.