Roblox addresses the cross-boundary simulation challenge by creating a "buffer zone" between the simulation regions of two players. Objects in the buffer zone are simulated by both players. In our vehicle-collision example, both the vehicle and the brick are simulated by player A and player B. Both vehicle A and brick B will generate correct behavior for the collision, as seen in this demo video.
When a buffer zone is active, two players simulate the same physics object(s). One player is the "authority," meaning they run a remote physics simulation of the object and send the resulting data to other players via the server. The other player is "secondary," which means they run the physics simulation locally to fill in any data gaps that come from the "authority" player. Roblox blends the motion between the remote (actual) simulation and local (estimated) simulation.
The overlapping red areas represent shared buffer zones. Objects in the buffer zones are simulated by both players.
The simplest blending algorithm interweaves the results from the remote and local simulations. Whenever a remote update comes in, we change the object position. This works, but can cause fast-moving objects in the buffer zone to stutter, due to the discrepancy between remote and local simulation results.
A discrepancy is guaranteed to exist in proportion to the network lag. We compensate for network lag between the remote and local physics simulations by including the velocity, positional data and timestamp (send and receive time) of simulated objects with each network packet. An update from the remote simulator (at time t2) would look like this:
Instead of blending x (remote position) directly with local simulation results, we compensate for network lag by figuring x as:
Xremote' = Xremote + (t2 - t1) * v
Then, we blend the compensated Xremote' with the local simulation result Xlocal. The discrepancy between the compensated remote and local simulations will be close to zero when the objects are moving at constant speed. When the delta between Xremote' and Xlocal is very small, we can use Xlocal directly to render a trajectory of the moving object with no stuttering.
When objects are colliding or experiencing a significant change in velocity, the compensated remote result can be thrown off because the velocity value is quickly outdated. In these situations we give more weight to the local simulation results and gradually fade in remote results as the collision settles or acceleration levels off. Assuming the time elapsed since a major impact on the object is e seconds, the position x can be blended between remote and local simulations as follows:
When e < 1:
X = (1 - e) * Xlocal + e * Xremote'
When e > 1:
X = Xremote'
These formulas allow us to estimate motion accurately enough to interpolate the two simulations without causing objects to stutter or move unnaturally.
This is still far from perfect. Our vision for the future is building more intelligence into the algorithm that blends motion between separate physics simulations. Ultimately, we want to seamlessly stitch together the simulation results from hundreds of players and render a massive, coherent, physically accurate world via the distributed physics engine.
We're continuously improving the scale at which Roblox's physics engine performs and integrating new dynamics.
For instance, we recently added water and buoyancy simulation to Roblox. We focused our implementation on clean architecture so the behavior of objects and characters in water looks and feels like a natural extension of Roblox's physics. This included integrating buoyancy into our standard physics pipeline; we consider a body of water to be a physics object and apply buoyancy to floating objects via the contact (or collision) between them and the water. Collisions between water and floater, floater and floater, and floater and sunken objects are all simulated in a unified engine.
Our architecture also unifies all the forces -- buoyancy, water viscosity (drag) force, water-flow force, gravity, contact forces and other external forces. The movement of a floating object is a net result of all these forces on a rigid body following Newtonian laws.
We also implemented water and buoyancy simulation with a high level of detail. For example, think about dropping a cube into water. After gravity has submerged it in water, it's likely going to tumble and re-orient itself as the water's buoyancy forces it back to the surface. In Roblox, we simulate that re-orientation by dividing the cube into eight voxels, each of which has its own buoyancy interpolator.
By voxelizing the force of buoyancy on floating objects (cubes, wedges and corner wedges), they orient themselves properly when stabilized and respond accurately to uneven external forces, such as the pressure caused by a player standing on one corner. We also apply water viscosity force against both linear and rotational velocity to dampen the motion and add realism.
Another example: Our advanced water physics make a fine distinction between cross-section area and tangent surface area when we calculate water viscosity force on floating objects. In this demo video, we don't apply any cheating forces or velocities to the boat body. Our engine simulates the actual interaction between the motorized paddles and the water surface to propel the boat. You can see that the thin boat travels faster than thick boat, even though both of them have the same submerged volume. The boats interact with other objects in the water, an example of our unified simulation of advanced water physics and rigid-body dynamics.
In Roblox, the final orientation of a voxel cube is affected by its density, as it would be in the real world.
Our water and buoyancy simulation facilitate a wide variety of practical applications, from boat modeling to real, water-fueled propellers. We've successfully created these, but believe our users will find ways to improve our primitive designs.
Roblox is built on a comprehensive, realistic physics engine. It's a fundamental part of our platform, bringing versatility and intuitiveness to the gameplay and game-creation experiences. While water and buoyancy physics represent a significant advance, facilitated by the efficiency of Assemblies and distributed physics, our vision is to continue optimizing Roblox's physics engine so it can handle interactions between millions of parts and hundreds of players.
With such advanced physics simulation, Roblox users will be able to build anything they want in a massively multiplayer, online world, where dreams and reality converge.
Until then, the evolution continues.