The Physics of an Old Lady
It's been almost two months since we released our second title - Granny Smith (available on App Store and Google Play). It's a platform racer starring an old lady chasing an apple thief through different environments. Our ambition was to make a smaller game than Sprinkle, but it turned out to be a lot more ambitious. I think mostly due to graphics. It started off as a 2D platformer with 3D-ish graphics - a few layers of parallaxed polygons, but the editor got gradually more advanced, and even though all graphics are still drawn as 2D polygons or splines, they can be extruded, beveled, rotated, textured, etc in heaps of different ways. In fact, all level data is still stored as 2D polygons and then transformed into 3D object at load time, making the level data extremely small. Even a complex level in the city environment is typically less than 30 kb in compressed form (not including textures).
I will talk about the physics in this blog post and save the graphics details for later. Just as with Sprinkle, we use Box2D for gameplay physics, with the addition of a special "motion joint", described in my previous blog post. In Sprinkle, each level was small enough keep all dynamic objects awake at all times, but in Granny Smith, the levels are much bigger, so objects are sleeping until touched and then completely disabled at a certain distance behind the player. Some of the more complex objects use fixed joints to glue objects together. It's a rather expensive method instead of just merging several objects into a single body, but 2D physics was never a bottleneck in this game, so I just went with the simplest solution.
Using a physics-based character for a fast-paced racing platformer was in retrospect quite a bold move, and we ended up implementing certain "speed normalization", "jumping aid" and "grabbing aid" sensors, manually placed in the level editor to help the player time jumps and release handles at exactly the right moment (pushing it more and more in the direction of an arcade game). This was by far the most tricky part of the whole project - to give the impression of a physics-based game while still making it playable and enjoyable. Without all the sensors, levels were practically unbeatable unless you followed the intended path very precisely.
The most interesting physics in Granny Smith is the fracture feature. We realized early on that we wanted a "wow"-feature in the game, similar to the water in Sprinkle, and our choice fell on fracture and breakable objects, mostly because it has not been used much in mobile games and it fits the setting nicely. I have always argued that when fracturing objects in games, it is very important that the fracture pattern is determined by the point of impact. Exactly how it breaks is less important. I also think it's very important that the broken pieces sum up to the original object. It sound obvious, but many games just replace the broken object with some random pieces when it breaks, which creates a very noticable pop. Lastly, I think the motion of the broken pieces must respond physically to the impact. To sum it up, it is very hard to cheat with breakage - at least from a geometric perspective. The exact breakage pattern is not that important, but it's highly relevant that it a) breaks at the point of impact, b) that the pieces sum up to the original object, and c) that they follow a realistic trajectory after the impact.
In Granny Smith, we only break flat objects, so the breakage actually happens in 2D. This simplifies things a lot. Breakable objects are special objects in the editor, and from a level design perspective they are always a straight line, which is then extruded and can be broken along the extruded surface - a quad. The quad is broken in real time, based on the point of impact. The breakage algorithm itself is rather dumb, basically just slicing polygons with random lines recursively (while preserving texture coordinates) until there is a certain number of pieces. Pieces that fall within a certain radius from the impact are made dynamic and the rest are marked static. Impulses from the impact are then applied to the pieces to ensure that they fly off in a natural trajectory. It took some tweaking to get it all right, but it turned out quite nicely in the end.
The broken off pieces are simulated using my own 3D rigid body solver and collision detection in the simplest way possible. There is no contact manifold, no pair tracking, no friction tracking, just a single contact point per piece and no collision between pieces. There is a very lightweight sleeping algorithm to disable objects that fall below a velocity threshold. Once they fall asleep they never wake up, and objects that fall outside the screen are immediately removed. Because Granny Smith is a fast-paced game you typically only see a breakable object for a second or two, so the relative inacurracy in the brekable physics is very hard to notice. I think this is a quite good example of "effect physics" in 3D that don't need a full-fledged, generic rigid body simulator.
All pieces from a breakable oject are rendered in a single draw call using a dynamic vertex buffer. This is far more efficient than drawing each piece separately, even though dynamic buffers have a some overhead. On multi-core devices (most phones and tablets nowadays!) the 3D physics calculations take place on a separate thread.