Accessing the 240hz Physics Loop

That is very inefficient due to having to loop through all of the triangles in every object and solve for the intersection of the triangle with the ray of every vertex

Physics used to run at 4000hz with the legacy solver, however, recently that solver was removed and replaced with the PGS solver, which is run at 240hz.


Oh, that makes sens why it went from 240hz to 60hz.

Fixed it

Not any slower than if you were simulating at 240 frames per second. In the end, the # of FLOPS doesn’t change. And as buildthomas said, this is essentially what the ROBLOX engine does.

It’s worth pointing out that ROBLOX is a real-time physics simulator, not a high-precision one. These two categories are to a large extent mutually exclusive, as the constraints of real-time means you only have so much processing power to work with. If computing power continues to increase exponentially, this might change to a degree, as we re-evaluate what “high-precision” means. But the same fundamental problem remains.

Add that to the fact that, for a multitude of reasons, ROBLOX Lua is slower than anything written on the C-side by ROBLOX’s programmers, and we’re left with a very limited frontier of real-time, high precision simulations that we can do. Don’t get me wrong; physics expertise is useful in a wide range of scenarios, ROBLOX included. But if you’re looking for “extremely accurate” physics, plenty of software exists to meet your needs more effectively than ROBLOX ever could.

That’s wrong. You’re getting the numbers confused. The legacy simulator was at 4000hz. The new one is at 240.

I think it would really help if you posted your simulation code, or at the very least your code’s outermost loop. And before dismissing my suggestion, I think you should really try it first. If your physics simulation is correct, then my suggestion should have made the simulation more accurate, not less.


I can assure you that my code is perfectly fine. If I simulate the 240hz physics engine inside the Stepped loop, it is VERY accurate, yet it is 4 times as slow of course.
Everything seems to be running is slowmotion. Aha

My code is a collision algorithm between a sphere and a cube, both of them are completely anchored.
Sometimes when I increase the Velocity of the sphere, if the update rate is at 60hz, the sphere would just tunnel through the Cube, which should’ve obviously never happened.
However when I simulate the same exact situation at 240hz, it works perfectly fine, the collision is detected and dealt with in the code.

How can you be so sure that your simulation code isn’t the problem? I think it would really help if you can get several pairs of eyes on your code.

As @XAXA said, you never know if it is a contributing factor to the speed. Why don’t you test it several times and report back with the results?

Have others look over the code as well.

Because the problem is in the Update rate, not the physics simulation itself.

This phenomenon is called Collision Tunneling and for the max performance that I can get out of LUA, raycasting is not an option. The only solution left is to increase the Update rate that my Physics framework runs at and that is what I initially asked for.

I’m not the right person to say why the script updates at this frequency, but physics is definitely still updating at 240hz (not at 60hz like the solution answer is stating here).


There is a lot of confusion in this thread.

local step = game:GetService('RunService');
while true do
    local total,t = step.Stepped:Wait();

The above code sample NEVER returned 240. There is no mechanism in the engine to allow a Lua script to fire in the internal 240Hz physics steps. .Stepped specifically fires on the 60Hz job that encompasses the internal 240Hz physics steps, and it always has regardless of which solver you used in the past.


RunService.Stepped runs at the frame rate, same as RenderStepped. The frame rate itself is capped at 60 Hz. If your frame rate drops below 60 Hz, so does Stepped.

After every Stepped we then do multiple physics engine steps. Typically 4 world steps per frame. Sometimes more, sometimes less.

Currently there is some DataModel state that we do not update between those 240 Hz steps that we do update before Lua executes again. Allowing Lua to execute between those 240 steps means doing more work to make sure the DataModel is synchronized before Lua executes more often. There’s a lot of serious consequences to supporting this.

We sometimes talk about adding some kind of physics step callback but we’re being very cautious about this. We know it’s basic functionality in other engines… Here it’s extremely performance sensitive and Lua is often a major bottleneck to achieving 60 Hz on many devices. Once we add something like this we’re stuck supporting it forever. We know it’s useful for some kinds of controllers, but we’re taking our time considering the best way to solve these use cases.

Also comparing the update rates of the old and new solver is a bit of an apples to oranges comparison. Very different algorithms. Even for each of those 240 steps there’s multiple internal solver steps.


I am VERY sure that game:GetService(“RunService”).Stepped:wait() used to run at 240hz if you put it in a while loop. I have tested it myself a couple of months ago because I found this thread:

That example is set private or has been deleted.
Do you have access and if so could you save it and put a link up for us?

As a matter of fact, you have said it yourself, that this piece of code runs at 240hz

while true do
   local totalT,t = game:GetService('RunService').Stepped:wait();

Here you have said (from my understanding) that Stepped:wait() runs on the Physics step

And on the post right after it, that the Physics step runs at 240hz.

Thus the code written above should output 240.
And it actually has 100% for a while now outputted 240 until the day I wrote this thread, when I initially noticed that it was changed.

1 Like

No. The render loop runs at 60 hz maximum. Physics runs at 240 hz maximum. RunService.Stepped has always been 60 hz maximum.


You’re ignoring what he said the sentence after that.

I think it’s really possible that you’ve misremembered. Stepped has pretty much run at 60hz for as far as I can remember. Two staff which work on the engine + a bunch of other people in the thread have vouched for this.


Please do not take my poor wording (physics step vs internal physics step was a bad choice to elaborate on the topic on my end) for how the underlying code works. Just to give you the benefit of the doubt I launched an older version of studio to verify that the code you posted in fact could never had run at 240Hz.

There is no mechanism in the engine to allow RunService::Stepped to trigger more than the rendering frame rate.

The only way

while true do
   local totalT,t = game:GetService('RunService').Stepped:wait();

could ever return 240 is if you were playing with a framerate unlocker of some sort, which is very much not supported.


Ok, sorry for using your wording in this context.
Is there any way I could access the older launchers?