Free fall of objects

Hi.

This doesn’t pertain exactly to scripting support, but it’s the closest category I can find.

Simply, I want to mathematically prove different kinematic equations using ROBLOX physics.


Methodology

I’ve found that objects within a traditional workspace are treated as being in a vacuum, and hence exist in free fall.

The following assumes that the object in question has no initial velocity, though accounts for it anyway.

The way I’ve approached the problem:

local function Calc(s, g, v0)
    local t, v, vAVG

    -- A rearrangement of s = gt^2 / 2
    t = math.sqrt((2 * s) / g)

    -- An adaptation of v = gt, taking account of initial velocity
    v = v0 + (g * t)

    -- A mean average of the object's velocity
    vAVG = (v + v0) / 2

    local tbl = {
        ["height"] = s,
        ["time to fall"] = t,
        ["initial velocity"] = v0,
        ["final velocity"] = v,
        ["average velocity"] = vAVG,
        ["gravity"] = g
    }

    for k, v in pairs(tbl) do
        print(k, string.format("%.2f", v))
    end
end

Calc(script.Parent.Position.Y, workspace.Gravity, script.Parent.Velocity.Y)

Find a source here that explains the concepts and equations better.


Findings

The issue I’m facing is that, when I try to apply Newtonian mechanics mathematically, the values never align.

Using the above function with substituted values of:

  • s [height] = 500 studs
  • g [acc. due to grav.] = 35 studs per second^-2

I record that a uniform object undergoing free-fall with a constant acceleration will:

  • take 5.35 seconds to reach 0 on the Y-axis
  • have a final velocity of -187 studs per second^-1

However, in practice I find that the object will:

  • take 7 seconds to reach 0 on the Y-axis
  • have a final velocity of -181 studs per second^-1

I’ve spent a fair while on this, trying several different equations and practices, all to no avail - the findings are too imprecise.

I’m hopeful that my maths (not my strong suit) holds true, but is there something obvious that I’m missing, else why do the values differ so greatly?

Any help is appreciated, thanks!

1 Like

Have you seen this post?

I presume its because of a truncation error in the physics engine:

1 Like

Just a side question, are you using a blank baseplate for your tests, or do you have a complex place you are testing in?
Just saying, if it’s simple then the equation may give different results than it if’s a complex place full of other Parts and scripts that may lag the findings slightly.

I’ll be honest, my knowledge of classical mechanics and mathematical abilities let me down here, but you’ve provided a resource I can assuredly dig my teeth into - with the added bonus of providing a fix.

Moreover, that post provides the formula which I’m about to use to try and rectify the imprecision in my calculations.

Thank you for the link, kind stranger! I’ll get back to replying on this thread in a bit when I test the new implementation.

Quite literally a void excluding one part, the inconsistencies due to server-client delay should be negligible considering the project is being locally run (therefore my machine is simultaneously the server and client).

1 Like

I think the discrepancy comes from the time it takes for the part to fall once you started running your test. While the post linked above does explain a discrepancy, it is smaller and in the other direction (objects fall slightly faster than mechanics would predict - ending up 0.4 studs lower than they should every second, with a gravity of 196.2).

Here’s a file that uses your script and waits a second before unanchoring the part. For a height of 500 and a gravity of 35, I’m getting something much closer to the predicted results: 5.349 and -187.249 respectively. But if the part is initially unanchored, my travel time is somewhere around 5.70s.

test_fall.rbxl (33.0 KB)

The code is as follows:

local function Calc(s, g, v0)
	local t, v, vAVG

	-- A rearrangement of s = gt^2 / 2
	t = math.sqrt((2 * s) / g)

	-- An adaptation of v = gt, taking account of initial velocity
	v = v0 + (g * t)

	-- A mean average of the object's velocity
	vAVG = (v + v0) / 2

	local tbl = {
		["height"] = s,
		["time to fall"] = t,
		["initial velocity"] = v0,
		["final velocity"] = v,
		["average velocity"] = vAVG,
		["gravity"] = g
	}

	for k, v in pairs(tbl) do
		print(k, string.format("%.2f", v))
	end
end

Calc(script.Parent.Position.Y, workspace.Gravity, script.Parent.Velocity.Y)

wait(1)
script.Parent.Anchored = false

local t0 = tick()
local e
e = game:GetService("RunService").Stepped:Connect(function()
	if script.Parent.Position.Y < 0 then
		print(tick() - t0)
		print(script.Parent.AssemblyLinearVelocity.Y)
		e:Disconnect()
	end
end)
5 Likes

That’s interesting. I wonder if the discrepancy stems from the time taken for objects to initialize when the server starts, or whether there’s a different contributing factor? I assume this is the case, as not calling wait() before unanchoring the part returns the velocity as correct to 3 s.f., but the time is still imprecise.

I’ve been able to successfully reproduce your results, which is definitely a good sign towards this being a fix for the issue.

Thanks for the solution to the problem I’m having, now I’m just left wondering why!

It’s likely the initialization of objects, physics service and other stuff contribute to the time not being accurate, as you mentioned. I just wouldn’t trust the first few frames of a test run to be any accurate, as they could take longer to render and delay the stepping of physics, and would just wait until everything seems to be properly loaded to run performance tests on anything: the specifics of why the time would be more inaccurate than the velocity, for example, could be down to the timing function you use, or to the details of how Studio works under the hood, rather than options directly accessible to you.

1 Like

I thought it might be something similar to that. I’ll bear that in mind for future physics problems - thanks for all the info!

1 Like