Synchronizing Physics and Rendering at a Smooth 60 FPS

September

29, 2013

by Kevin He


Archive

ROBLOX Battle June 2013The ROBLOX game engine interweaves multiple jobs to create an accurate on-screen representation of your multiplayer, physically simulated games. The primary jobs are physics, rendering, networking and Lua scripts, and each job is updated at a frequency that balances performance and fidelity. We are working on rolling out an optimization to those update frequencies – particularly in relation to the physics and rendering jobs – to boost ROBLOX’s max framerate to 60 at almost no cost to performance.

In an ideal world, each of the primary jobs would be updated at exactly the same frequency (let’s say 120Hz), your computer and network would be able to manage the load, and the framerate would stay locked at 120. However, in an online game as complex and variable as ROBLOX, that’s a dream. Instead, we have to optimize the frequency at which each job provides new data for the best possible experience. This is what we’ve done to increase ROBLOX’s framerate to 60: optimize the frequency and distribution of physics updates, and ultimately synchronize the physics frequency with the render frequency.

Let’s step back and take a look at how ROBLOX currently manages each job. This is a linear perspective.

Current Threading

As you can see, the physics step happens once for every two render steps. That means physics is updating at 30 FPS, while rendering is updating at 60 FPS. Players will see some choppiness in the motion of physically simulated objects (e.g., characters, projectiles, and falling bricks, to name a few).

Now, here’s an illustration of how ROBLOX will manage each thread in the near future.

60 FPS Physics Threading

The difference is that, for each physics step, there is one render step – and, ultimately, both physics and rendering are updating at a synchronized 60 FPS.

The performance effect of this change is minimal. We’ve broken what was originally an eight-iteration forward-dynamics update of each object’s position and velocity (this is known as the “world step”) into two smaller, but no less accurate four-iteration updates. Since we’ve divided the same workload into two pieces, this introduces no performance burden. The UI component of the physics step – this, for example, scans mechanical constructs for updates – does need to be repeated in each physics step, but it’s such a small (i.e., 1-2%) part of the physics update that it only introduces a small CPU load. However, it’s enough that we wouldn’t want to repeat it eight times (i.e., once per “world step”). That’s the reason why we are not planning to run the physics step at 240 FPS yet.

As an aside, we’re digging into low-level optimizations to find out exactly what pieces of the UI component actually need to be checked at 60 FPS. We want to be doing the bare minimum at that rate. Right now, we’re doing roughly 75% of the original 30Hz UI step workload at 60Hz.

Physics FPS Comparison

You can always press control + shift + F4 to see the physics and render framerates. Right: 60 FPS physics.

The most obvious effect of updating the physics and rendering threads at the same frequency is a smoother framerate for physically simulated objects. Since that includes your character, the entire game experience feels much more fluid. The optimization also improves Touch events, which are contained in the UI step, meaning the engine will report collisions between objects to Lua scripts faster and more accurately. The effect is magnified in fast-moving projectiles, such as rockets, which will no longer penetrate into walls before the Touch event is fired and the rocket explodes. Melee battling also becomes more accurate.

ROBLOX runs a distributed physics simulation, where each player is responsible for simulating physics within a dynamic “region” of the world. This optimization is very noticeable on your local simulation, but less so on that of other players. To reduce the discrepancy between motion you’re simulating locally and motion everyone else is simulating — in other words, between the rocket you shoot and the rocket your opponent shoots — we have increased our interpolation frequency to better fill the gaps in physics updates sent over the network.

We want ROBLOX to not only look great – hence dynamic lighting, outlines, and upcoming materials updates – but play like a top-tier game. This 60 FPS physics update brings a new feeling of smoothness to the gameplay experience, and does so without introducing a change in our existing performance. We’ll be rolling this out soon (those of you paying attention know it was enabled for a few days already) after we finish our final optimizations.