[An ex-Blizzard physics and networking lead for online game Roblox shares the secrets of how the Lego-like building game simulates rigid bodies for millions of players at a time -- without losing either performance or fun.]
Roblox is built on a comprehensive physics engine, and our millions of users are constantly generating content that pushes it to the limits of its capabilities. To enable our users' unrestrained creativity and cope with their passion for ever-larger and increasingly complex simulations, we've committed ourselves to a regimen of physics-engine optimization.
In Roblox, we simulate all rigid-body physics because our users create games on the foundation of bricks, blocks, wedges, spheres and cylinders. These elements behave in game as they would in the real world, which eases the learning curve, makes it possible for users to create games in almost any genre, and adds a layer of discoverability -- all contributors to the 250 million hours of gameplay our users logged in 2011.
We should note that complex physics simulation doesn't make a game good and, in many cases, would be a waste of resources. Instead, the complexity of a physics engine should parallel the gameplay requirements.
Roblox's Physics, In Context
Roblox is near the extreme end of the physics-complexity spectrum in gaming. On the other end are MMORPGs -- from EverQuest to World of Warcraft -- which employ basic collision detection to keep players confined to playable areas.
First person shooters, such as Halo, and action RPGs, such as Diablo III, take collision-detection a step further with contact force and limited collision shapes (e.g., capsule) to generate a collision response. They also put characters into a "passive" ragdoll state, sending them tumbling after death or flying after an explosion, and use "decorative" ragdoll -- moving hair, for example -- to add dynamic visuals.
Sports are where physics simulations start to get interesting and complex. In addition to everything seen in MMORPGs and action games, sports games, such as Fight Night Round 4 and FIFA 12, introduce "active" ragdoll, where motors actually power the joints of the fighters and players. This helps achieve smooth, life-like motion and animation. Without their motors, fighters' and players' limbs would hang lifelessly and they'd collapse to the ground.
Finally, there's Roblox, where full physics simulation is enabled by default, disabled as the exception. All physical objects -- terrain excluded -- are simulated. Our engine features:
- Collision-detection with contact force and a rich set of collision shapes, including box, sphere, cylinder, wedge, convex hull and more
- Full rigid-body dynamics, integrating all relevant forces (gravity, contact force, friction, joint/spring force, buoyancy, viscosity and kinematic body force) in one pipeline
- Physics-based character animation, "passive" and "active" ragdolls, balance controllers for standing, running, jumping, falling and swimming
- Mechanical vehicles and boats, built on a rich set of joint types, including kinematic, hinge, weld, rope, prismatic, revolute, motorized and more
- Buoyancy and advanced water physics
These simulations must also perform in a networked, multiplayer environment.
From Discrete to Aggregated Physics
Give someone a set of building blocks and they're probably going to use as many as possible to create something massive. Roblox is no exception, but simulating every single part of a skyscraper or a Titanic-sized ship as an individual -- or "discrete" -- rigid body is prohibitively expensive for network and CPU/GPU resources.
We are smart about simulating massive structures and vehicles. When a skyscraper is anchored to the ground and immobile, we treat it as a single entity, attached to the background environment. No dynamic motion is simulated for the discrete bricks and only collision detection is performed between the skyscraper and other moving parts or mechanisms. Our engine compresses the entire skyscraper into a static, "featherweight" part that consumes little memory. "Featherweighting" helps a Roblox world scale to thousands of complex buildings with minimal cost.
For a Titanic-sized ship sailing in water, the entire ship must run in our rigid-body dynamics engine in order to simulate a realistic, floating effect, the interaction with water and collisions with other floating objects. Simulating each of the ship's thousands of parts as individual rigid bodies would be prohibitively expensive, so Roblox simulates such high-volume, welded rigid bodies as a more efficient "Assembly" to manage resources during physics simulations.
Roblox dynamically identifies pairs of objects that do not move, relative to one another, during a frame of motion. It groups such objects together, creating an Assembly. Even a Titanic-sized ship with a thousand parts welded together is simulated as a single rigid body. This is the kind of efficiency we need to scale our physics simulation to millions of parts.
In this scenario, two parts form an Assembly, as they do not move, relative to one another, during a frame of motion.
Assemblies are not a silver bullet; their implementation presents a unique set of challenges. In a dynamic environment with constant movement, collisions, explosions, and human interactions, Assemblies are formed, fragmented, and merged all the time. Here are some common examples:
- Parts glued together can break with enough separation force
- Bodies originally separated can be welded together at run time when the "inlet" of a part's surface touches the "outlet" of a part's surface
- Humanoid characters will be torn apart when killed, even due to a sword strike, because the joints are broken
- Users can write LUA scripts to dynamically insert or remove joints between two parts and cause the break-up or merge of Assemblies
Our engine has to synchronize a consistent composition of Assemblies in real time, between clients and servers, while these changes are happening. We select the same root bodies for Assemblies and generate them in the same order across the client and server boundary to achieve smooth networked motion.