Really impressive stuff.
The Prototyping of "Flipper Studies"
A few months ago, around the 20th of September or so, I finally decided that I would start on a pinball simulation. This is an idea I've been probing for at least a year or more, just as part of a series of studies into the game, at first as a casual player and then seeing it as a venue for storytelling, a historical study and more. One of the first video games I remember making something in was Pinball Construction Set on the Atari 800, and now I have something that is considerably more accurate that I can build on freely.
So, there are already ways to make virtual pinball games. There's an asset for Unity, and there's a standalone tool called Visual Pinball with a complete editor. Why build my own?
Well, three reasons.
- I wanted to spend time studying the actual mechanisms of the game, rather than just throw them together into a layout.
- I want freedom to control my workflow. I can get pretty particular about how I go about implementing things, and that's always going to conflict with pre-existing tools.
- As a game programmer I was unhappy with some of the technical aspects and wanted to attempt to do them better. In particular I wanted to really focus on high-refresh gameplay because it's so critical to the feel to have the ball-flipper interaction behave in a precise, responsive fashion, and for the most part, existing pinball games seem to be more concerned with supporting higher resolutions than higher refresh rates.
So then the second part to this is, why make it 3D and why use Godot for the task? The 3D part is simply that I gradually decided, after evaluating a lot of 2D pinball games, that it wasn't capturing enough of the game to suit me. I wanted something that felt sim-like and a major part of that is including the correct spin and vertical motion. The ball often does bounce up during gameplay, even if the playfield controls it most of the time. From there, Godot entered the picture as an open-source engine(always a plus) with a robust physics integration using Bullet, a commonly used physics library. The requirements of a pinball scene, visually, don't stretch Godot in the ways that people run into when they attempt projects with a large, dynamic world, detailed character animations and complex shaders: The playfield elements are rounded so they tend to be high-poly, and there's an emphasis on lighting, but everything moves in simple ways and the scene remains mostly static most of the time.
One "downside" of sticking with Bullet is that it's not quite up-to-the-minute with new developments in real-time physics sims. This deformation simulation paper, for example, would be wonderful for better simulation of pinball rubbers, ball collisions, and momentum on wireform habitrails. However, I'm not a physics engine developer, and my focus is on engineering the best thing I can with what's available - and it's already possible to get very close with Bullet and a lot of trial and error.
I needed a target for what I was prototyping, and quickly settled on Gottlieb's El Dorado from 1975. Besides being a pretty good example of the game from that era, it has a relatively simple layout without any unusual mechanisms, multiple playfields, ramps, etc., and the game's layout was heavily reused both in rebranded form as Target Alpha, Gold Strike, Lucky Strike, Canada Dry, and Solar City, plus an actual sequel in the 80's, El Dorado: City of Gold. Simulated remakes are available both in Farsight's The Pinball Arcade and for Visual Pinball. This makes it really easy to find source material for the game.
I assumed that maybe this would be a two-week task to get the mechanisms sorted out and then focus on layout. That was in late September. In the end, it turns out that I'm still not really done. Here is what I have implemented:
- Ball Shooter
- Slingshot Bumper
- Pop Bumper
- Stand-up Target
- Drop Target
- One-way Gate
- Playfield Posts and Rubbers
Here are things I still have not addressed at all:
- Playfield Toys
- Playfield Plastics
And even of the things I have done, there's still more tuning to do. The current drop targets, for example, have a tendency to throw the ball up in the air a bit too excessively. I went to the length of ordering some real replacement parts from Marco Specialties to take measurements for things like the exact dimensions of the pop bumper assembly and different styles of flipper, and I may make some more orders before I'm done.
Why does it take this long? Simply, besides a little bit of unfamiliarity with Godot and Bullet to start with, it takes a few iterations of each thing before it's in a good, playable state. I often referred to slow-motion footage to get a sense of what the action really was and how I might recreate it in Bullet. I'll explain the three most complex mechanisms: The flippers, the slingshot, and the pop bumper.
The flippers, in real life, consist of a flipper bat(the visible thing that flips), a shaft that extends under the playfield, and an assembly that wires the shaft up to electromechanical coils that give it power. But it's not as simple as "when you press the button it rotates", even. No, a real flipper has two coils, one for the primary flipping action, and another, weaker one for the "end-of-stroke". When you hold the flipper upright, it switches to the end-of-stroke coil, which, being lower power, is less prone to overheating and burning up. If you are around pinball machines for long enough you will eventually learn the distinct smell of a burnt out coil. But an effect of this on gameplay is that the end-of-stroke will have more give when it's hit by the ball, and bounce backwards a little bit.
Therefore, an accurate flipper simulation must have: Appropriate mass, dimensions, and angles, a motor controlling power and providing varying counterforce to ball hits, and scripting to change the amount of force based on context.
OK. So, then, a few days later, I have my flipper. Now it's time to start on the slingshot. These are the triangular bumpers that you usually see on the lower playfield. They are triggered, in real life, by the ball pushing in the rubber slightly, causing a switch to contact, which then fires a coil which makes a kicker swing downwards, pushing out the rubber at great velocity.
In the end, after trying a few things, did I simulate any of that directly? No. The ball first enters an area that indicates that it could be kicked by the slingshot(we'll see why it needs this in a moment). It triggers it at contact with a script that determines if the force surpasses a certain threshold. Then, a large wedge-shaped rigid body appears and pushes out of the slingshot body along a slider joint, then snaps back a moment later. The wedge is so large that it sticks out of the back of the slingshot when not in use, so the kick area is needed just to ensure that collision is unaffected elsewhere.
Now our slingshot feels pretty good, so we get to the pop bumper. Oh boy, now this one is an adventure. The real pop bumper is the mushroom shaped bumper that kicks the ball out from any direction. It's triggered by a skirt around the base: the base is not to actually be hit, it's rather fragile. Instead, the ball rolls onto the skirt, tilting it slightly like a dish. This triggers a switch underneath the playfield that fires a coil pushing a "thruster ring" downwards, kicking out the ball.
First of all, there are a ton of specific dimensions and angles involved in this. The ring, as it turns out, is shaped with a 45 degree angle, and at maximum extent, it's the same radius as the skirt. But even knowing the dimensions, there's a problem with triggering it. As I noted above, there are limits to what Bullet does well, and one of them is this kind of "dishing" motion. I can probably get it somewhat accurate with more attempts, or perhaps copy what Visual Pinball does(which involves a customized formula just for skirt motion). But for the sake of simplicity and being able to move on, I ultimately ended up with a simple slider push-down to give the skirt a basic behavior, and an invisible trigger volume to actually make the thruster fire. This is why the skirt currently disappears underneath the playfield if you examine it in the 3D view.
The thruster itself became simple after I had given it some thought. Knowing that it pushes down on the ball with a slope from all sides, I was able to reduce it to an invisible cone shape, which gives pretty good results(provided the trigger and dimensions are correct).
But after I had all three of these in hand, I felt pretty confident that I could finish everything else.
Then I started really working on the playfield and had to spend over a week understanding how to procedurally generate smoothed playfield rubbers from a description of posts, their radius and relative positions. This is the sort of thing that I could have ignored and done by manually crafting every polygon, but I wanted to make a system that is actually fun to prototype with. There is a decent amount of geometry and winding order problems involved. I am still not happy with the playfield workflow because I don't have fast feedback, but this is something I can aim to fix in the next prototype.
Anyway, after that, and some work on the simpler mechanisms, the playable result emerged:
It does not play like the original game, but I know why: I got lazy, and didn't really measure it out! So there are a lot of poorly tuned and missing elements. But I'm still happy with it, regardless. The mechanisms work well, and I'll be more able to focus on layouts in the next iteration.
Something I learned in the process of working on this is a greater appreciation of proportion. In video games it's all too easy to forget about proportions because the entire game is based on an ungrounded fiction. It helps to have tangible connections to relate things back to. I actually really enjoyed the process of measuring out the parts and each time I switched from my guesswork dimensions to the real ones, there was a noticeable change in the behavior towards something that felt much more accurate.
How do I see this shaping up, ultimately?
One thing I mentioned in my preliminary studies of pinball was about storytelling. Last year around this time I had been taking a class on storytelling and wrote a story about a "pinball vampire" who takes her dates on a pinball adventure where they become the ball. I believe the character can be taken further than that and so I've been considering what the right way to align it is, and I currently think a pinball sim that builds an appreciation of the game, with tutorials, exercises, game modes and a bit of historical and cultural background, is approximately right for her character. It also addresses a longstanding problem with pinball being an incomprehensible light show for casual players: Everyone who wants to get their friends into it could say "play this and it'll teach you all the basics". But even with that rough pitch, there's so much to be done in terms of figuring out how "wordy" I make the game, the audiovisual aesthetic, specifics about the scenario, how exactly to teach the game, and all those kinds of content design issues.
So I see more prototypes in my future to help myself answer some of those questions. For right now I'm returning to Galapagos which I am aiming to make a complement to this game by helping me structure some parts of the content. (This may turn out unwise, given that it caters to my tendency to turn everything into an ever-changing offshoot of a single project, but we'll see.)