Skip to main content

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 (see previous blog posts) 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.


  1. Hi Dennis,

    nice post! Did you add the gyroscopic forces when simulating the broken pieces in your engine? I am wondering if precession/nutation makes a noticeable difference for the trajectory.


  2. Would you pls go into details on exactly what's optmized for the nVidia's Tegra? I think it'd be interesting for the readers with Nexus 7.


  3. Hi Dirk, no definitely no gyroscopic effects on the breakables. I'm 100% sure you wouldn't notice the difference :)

    Henry, for Tegra 3 we added additional breakage. The are many more pieces when something breaks, and there is also additional foliage and grass in the different environments.

  4. Hi Dirk,
    First of all great game,I purchased both Sprinkle and Granny Smith.I actually loved Sprinkle much better especially in lieu of the cool water physics you employed. That said, can you please elaborate on the programming environment you are utilizing, namely are you using visual studio + the Tegra Android Development Pack 2.0 etc? and how do you go about connecting the dots ? porting the outproduct to Ios. etc.

    Any guidance would be much appreciated.


  5. Hi Barak, I mostly use Visual Studio for the actual development, and then XCode to deploy for iOS and the command line tools (ant) for android deployment. I'm getting a lot of questions on the programming environment so I might do a future blog post about that specifically. Cheers!

  6. Hey there Barak ,just wondering,how long did it take to do the drawing board?

  7. First You got a great blog .I will be interested in more similar topics. i see you got really very useful topics , i will be always checking your blog thanks.
    psychic phone chat

  8. Interesting and amazing how your post is! It Is Useful and helpful for me That I like it very much, and I am looking forward to Hearing from your next..famous quotes

  9. I acknowledge the same best work from you at some point or an alternate later.
    stenen keukenwerkblad


Post a Comment

Popular posts from this blog

Bokeh depth of field in a single pass

When I implemented bokeh depth of field I stumbled upon a neat blending trick almost by accident. In my opinion, the quality of depth of field is more related to how objects of different depths blend together, rather than the blur itself. Sure, bokeh is nicer than gaussian, but if the blending is off the whole thing falls flat. There seems to be many different approaches to this out there, most of them requiring multiple passes and sometimes separation of what's behind and in front of the focal plane. I experimented a bit and stumbled upon a nice trick, almost by accident. I'm not going to get into technical details about lenses, circle of confusion, etc. It has been described very well many times before, so I'm just going to assume you know the basics. I can try to summarize what we want to do in one sentence – render each pixel as a discs where the radius is determined by how out of focus it is, also taking depth into consideration "somehow". Taking depth i

Screen Space Path Tracing – Diffuse

The last few posts has been about my new screen space renderer. Apart from a few details I haven't really described how it works, so here we go. I split up the entire pipeline into diffuse and specular light. This post will focusing on diffuse light, which is the hard part. My method is very similar to SSAO, but instead of doing a number of samples on the hemisphere at a fixed distance, I raymarch every sample against the depth buffer. Note that the depth buffer is not a regular, single value depth buffer, but each pixel contains front and back face depth for the first and second layer of geometry, as described in this post . The increment for each step is not view dependant, but fixed in world space, otherwise shadows would move with the camera. I start with a small step and then increase the step exponentially until I reach a maximum distance, at which the ray is considered a miss. Needless to say, raymarching multiple samples for every pixel is very costly, and this is with

Undo for lazy programmers

I often see people recommend the command pattern for implementing undo/redo in, say, a level editor. While it sure works, it's a lot of code and a lot of work. Some ten years ago I came across an idea that I have used ever since, that is super easy to implement and has worked like a charm for all my projects so far. Every level editor already has the functionality to serialize the level state (and save it to disk). It also has the ability to load a previously saved state, and the idea is to simply use those to implement undo/redo. I create a stack of memory buffers and serialize the entire level into that after each action is completed. Undo is implemented by walking one step up the stack and load that state. Redo is implemented in the same way by walking a step down the stack and load. This obviously doesn't work for something like photoshop unless you have terabytes of memory laying around, but in my experience the level information is usually relatively compact and se