Skip to main content

Pinball physics

This might be the first time I reveal something about an upcoming title on this blog, but here it is – we are currently working on a pinball game. Not a classical pinball game, it has a pretty cool twist, but the basic mechanic is still very similar. As a physics programmer this sounded easy at first. Hey, it's just a sphere. What could possibly be easier to simulate?

I wouldn't call myself a pinball player, but I've always enjoyed it and spent a lot of time with the old Amiga games Pinball Dreams/Fantasies and even more with Slam Tilt. It's an interesting challenge to create a pinball simulation because it is quite the opposite of what physics programmers are usually facing – forget stacks of boxes, thousands of objects, streaming geometry and convex decomposition. With pinball it's all about detail and accuracy. We are not aiming for maximum realism in this game, but I think realism is a good place to start and then tweak the parameters to fit the gameplay.

Let's go over the pinball components. There is the ball, not much to say. It's a perfect, solid sphere. The table is a glossy, very slippery, polished surface, similar to the floor in a bowling alley. We also have a lot of curved geometry, ramps and various obstacles. The last component are the flippers. This might be the hardest part to get right. They are built with a double-coiled solenoid actuating a hinged, plastic flipper covered with high friction rubber. The main coil causes the initial strong pull, and at the end of the stroke it switches to just using the outer layer, holding the flipper up without overheating.

This particular setup seems to be important to give pinball it's signature characteristics and enables a lot of advanced playing techniques that simply wouldn't work with a different setup, for example the live catch, drop catch and tip pass.

Since the ball is solid steel it has a fairly high moment of inertia. The glossy table causes the ball to mostly slide across the surface, but when touching high-friction rubber on a flipper, it has to start rotating. In physical terms this translates linear momentum into angular momentum, causing the ball to drop a lot of speed. This gives the player control, being able to capture the ball using the flippers. The reverse is of course also true, if the ball is rotating heavily and touching a flipper, it will translate angular momentum into linear momentum.

Curved geometry is important in order to alter the direction of motion of the ball without loosing too much momentum. This is a bit of a headache in physics, since we're used to model most things using convex polyhedra, and now suddenly everything is concave! On the up-side collision detection will not be a performance bottleneck with a single sphere, so we can easily use detailed triangle meshes for everything, but on the down-side no matter how many triangles we use, they still aren't curved – they're flat!

Another thing in pinball is the speed. The ball can easily travel at 6 m/s, which translates to more than three times the diameter per frame at 60 FPS. Fortunately, this can easily be solved using substepping, as performance is not an issue.

I'm only starting to explore this world and I will post more details as I dive deeper into each specific part.


  1. For curved collision geometry, you might try nurbs patches. I guess it's beneficial to have accurate collision response of the ball when it comes to pinball, although with very detailed meshes you might get close enough. Of course things can get a bit hairy compuitation wise. Just a thought.


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