(WIP) Pinball Engine for the Pokitto

It certainly comes in handy when creating the #define PI 3.141592653589793 (I didn’t even have to look it up and it’s accurate enough for NASA so it should hopefully be accurate enough for Pokitto Pinball, but I might need the additional 2384 that follows :thinking:).

Here’s the animated GIF of the flipper collision theory as promised.

Frame 1

Ball is approaching the flipper as the flipper starts to rotate

Frame 2

Ball moves closer to flipper and flipper rotates, now a collision is happening and the ball’s angle and velocity get updated accordingly based on the angular velocity of the flipper at the point of impact.

Frame 3

Ball was moving slowly and so is still in path of flipper as flipper continues to rotate resulting in a second collision. Again the ball’s angle and velocity are updated accordingly same as before.

Frame 4

Ball is now moving away from flipper at a different angle then original collision due to a “rolling” effect where the flipper pushes the ball away from it while the ball rotates. Keep in mind these 4 steps would probably happen in about 100ms and would be difficult to see but the results should “feel” close enough to real pinball (as this is how most advanced physics engine treat these sorts of collisions and the effects work even if crude).

flipperCollision

5 Likes

Should it be: 4bpp?

That is correct, I accidentally put 16bpp when I meant 4bpp with 16-colors. Edited the original post drawing a strike through the 16bpp and put the correction in parenthesis next to it.

1 Like

Hey everyone. Giving everyone a nice taste of the pinball physics in action. Currently the flippers are not actually being rendered as sprites, instead you see their collision information. However, I now have a rudimentary shape editor for creating the table collision mask and have the collision implemented in the engine. Occasionally the ball will get stuck in places it looks like it should fit in, this is because the example image I grabbed isn’t exactly designed for this engine (it was actually borrowed from a bigger image, stripped of any details, and scaled down quite a bit).

Controls:

  • Left/Right: Control flippers
  • Up: Launch ball upward

Not posting this at the top since this more of a pre-alpha very early prototype demonstration.
PokittoPinball.zip (75.0 KB)
Instructions: Copy the “pinball” folder to the root of your SD card and put the bin file wherever you like (I personally have a folder called “Dev” for development tests so they don’t clutter my game folders).

6 Likes

I am impressed! The ball physics, collisions and all feels very very good overall. I can even put the flipper up, let the ball to calm down on it and then send the ball when I want to :slight_smile:

Some observations:

  • The ball movement feels a bit jerky due a bit low fps.Completely playable thought.
  • It is very hard for e.g. the left flipper too send the ball to right side of the table. Ball needs to hit to the very top of the flipper, which was not the case in the real thing. But it has been so long since I played the real pinball machine that I might remember wrong :wink:

Good work!

P.s. When this is released we could have a small Pinball jam and choose the best table :slight_smile:

2 Likes

Actually this is caused by excessive movement away from collisions. What I need to do is move the ball just far enough away to no longer be colliding but not so far away so as to cause jerkiness (main problem is moving the ball 1px in a single physics step is the equivalent of moving the ball 200px/s).

I feel this is also true as well, but may be due to a low max speed. I’m setting up a replica table in future pinball so I can get a feel for how the flippers should feel and then tweaking the collisions accordingly.

The physics is handled using what’s known as Continuous Collision Detection (CCD). In a nutshell it means that instead of velocities/accelerations being in terms of units/second they’re in terms of units/step and the steps are locked to a specific unit of time (currently 5 milliseconds, which is 200 steps/second). This means that at 60FPS there will be roughly 3 collision steps between frames, whereas 30FPS will result in 6 steps. Outside of the game update routine it checks the current time in milliseconds and while the previous time is less than that it steps the physics engine and increments the previous time by the predefined step time (currently 5 milliseconds). This means the previous time is not actually being set to the current time, but instead is used to track how many steps the physics engine needs to take.

Playing some online pinball tables has also shown that the flippers should have a tendency to send the ball to the opposite sides of the table. Looking into the methods used to handle the flipper physics and might try a few approaches in an SDL2 based PC engine. I’m not worried about feature creep with this part because imho the physics engine of a pinball table is the most critical component to get right. Currently I’m having trouble sending the ball up or across the table, mostly I keep sending it to the same side the flipper is on.

2 Likes

So implementing motion blur would not help(?)

No motion blur wouldn’t make much of a difference. Also the reason it’s running slower is because of refreshing the whole screen every frame. Temporarily removed the partial refresh optimization since the flippers aren’t rendered as sprites, instead they’re rendered as direct lines and circles to the display (hence the slight flickering). This is so I can monitor the actual collision shapes and make sure everything is behaving correctly.

What I’ve noticed so far is that I’m applying a constant force based on the angular velocity of the flippers at the point of impact, whereas I need to actually scale that force based on the current velocity of the ball in the direction of the normal (ie. if the ball is already moving in roughly the direction of force then a much smaller amount of force would be applied as opposed to the two moving directly towards one another).

There’s a few other things I can experiment with as well to dial in the flipper physics. This is the part that I’ll be focusing on most since I feel it’s very crucial to have the flippers be ‘good’ rather than ‘ok’ though they don’t necessarily need to be ‘perfect’ (remembering the times the ball got suck inside the flipper of Pokemon Pinball and eventually resolved itself).

The source code is available on github in case anyone else knows anything about physics and can offer some suggestions. Unfortunately information online is limited to paywalled articles or people saying to just use box2D since it works and does everything for you.

3 Likes

@tuxinator2009 Impressive stuff! Ball gets stuck in the top holes in relaunch but otherwise just wow!

And some sort of a bug … something gets stuck. When I open the pinball thing again, it fails to open the pinball table file. I need to reflash the game to get it working again.

Looks like this for me…


Is it supposed to? I put the folder on the root, was I supposed to empty the files there instead?

You should have a folder on the root of the SD card called “pinball” with a “test.dat” file inside it. If that’s correct then double check that the SD card isn’t sitting loosely as there’s no current error detection routines to check if the SD card mounted successfully.

Stage 2/? is complete the flippers physics are now amazing. They are far from realistic but they “feel” accurate enough. Here’s a breakdown of what I changed. Below is the zip file with the latest demonstration. There are instructions in the zip file on how to install it. Also please note the new File library is still under development and is occasionally having issues mounting the SD card. There is currently no detection for this so if the table background doesn’t render correctly there’s instructions in the INSTRUCTIONS.txt file explaining what to do).
PokittoPinball.zip (70.0 KB)

Previously I had tried having the flippers register multiple collisions with the ball when rotating, but this led to the ball going in the same direction with the same momentum almost regardless of when you hit it. Now the ball registers collision and bounces off the flippers normally. If the flippers rotate up when the ball collided with it in the previous collision step then it rotates the original collision point and tests if that point is colliding with the ball. If the ball is once again colliding then it’s pushed away from the flipper so it’s no longer colliding and the flippers angular velocity gets added to the ball’s velocity in the direction the original collision point moved.

Additionally the flippers now slow the ball’s velocity upon collision more than the table does (table reduces ball’s velocity in the direction of the normal by 40% whereas the flipper now reduces it by 80%). This is because when researching the materials of a physical pinball table I discovered that flippers are surrounded by a low friction rubber which absorbs a significant amount of force from the impact with the ball. Keeping in line with Force = mass * acceleration, the conservation of momentum, and newton’s third law of motion (for every action there is an equal and opposite reaction) this means that the force in the system is the ball’s change in velocity multiplied by it’s mass plus the flippers velocity multiplied by it’s mass. If no force was absorbed in the system then the ball would bounce around forever without eventually coming to rest. Using the mass of a standard pinball ball and flippers I was able to determine an approximate restitution value (amount of force being absorbed on impact) for each. Standard pinball balls have a restitution of about 0.6 which means upon collision the ball’s velocity in the direction of the collision normal is reduced to 60% of it’s original velocity. For the flippers this results in only 20% of the ball’s velocity remaining. Putting all this together has resulted in the flippers “feeling” more realistic (though nowhere near perfect) and gives the player better control of the ball (ie. allowing for such tricks as a live catch, or a tip pass even).

Coming soon to a Pokitto near you:

  • Drawing the flipper sprites rotated according to their current angle (I think I’ve figured out an approach that’ll work with the scanline rendering I’m using)
  • Implementing two layers of collision (needed for things like ramps and ball returns)
    • These will use a 1-bit per pixel mask that indicates which layer each pixel of the table’s background is on. When a sprite is rendered it will compare it’s layer (0 or 1) with the bit value in the layer mask to determine whether or not to draw that pixel.
  • Implementing bumpers and triggers (these will be collision objects such as lines and circles with additional functionality later). For now they will just increase a number by 1 simply to indicate the trigger was hit successfully.
  • Adding table lights (these will use a 1-bit mask to allow for more lights while taking little space). Lights will be given a single color on the 256-color palette (multiple lights can share a palette index). This also allows the lights color to be changed mid-game leading to a more dynamic range of lighting effects.
  • Add support for music and sound effects
  • Add a, no programming required, event system for handling table logic (ex. an event get’s called when a trigger gets hit that simply adds a certain value to the player’s score and flashes a table light). Once in place more events can easily be added at a later time (after the initial 1.0.0 release).
  • Make an awesome table showcasing all of the various mechanics available.

On another note I’m open to suggestions for changing the name of the engine. I don’t mind Pokitto Pinball at all, but it does seem a bit generic so if anyone has any ideas let me know. One example format that still uses Pokitto in the name is:

  • BLANK Pinball
    for the Pokitto
  • Pinball BLANK
    for the Pokitto
  • Pokitto Pinball
    BLANK

Also I figured out how to support both sizes of pinball table (plus slight variations on each). Essentially each table will specify a rectangular region of the screen that the table is rendered in (width is always equal to table’s width). Sprites can be put told to drawn in table coordinates or screen coordinates (table coordinates means the sprites scroll with the table, whereas screen coordinates stay in place like a HUD).

3 Likes

Can I suggest the controls being left flipper = dpad, right flipper = a/b ?

1 Like

This is planned for the later release. For now the reason for the controls being this way is if I put #define SLOW_MOTION 2 in the main.cpp file then A is used to advance the collision one step (5 milliseconds) at a time, and B is used to advance the collision one step per frame (at 30FPS). Later when it’s no longer in an early alpha phase the controls will be easily customized with the default being Left being the left flipper and A being the right flipper (tilting will be as @Vampirics suggested by holding B and pressing a button on the D-pad, which allows C to be used to pause the game and Up/Down not being used, but events could be tied to them for custom table mechanics).

5 Likes

Here is an update on my pinball table titled Dragonrush.
PokittoPinball.zip (65.8 KB)

Updated controls:

  • Left Flipper: Left Button
  • Right Flipper: B button or Right Button
  • Launch Ball: Up Button
  • Reset ball to start: C Button

Inside you’ll find the latest build of the engine, it’s still in a very early stages as all the components are being setup manually. Once I have all the components fully functional and I know exactly what will be needed for the final version of the engine I can start condensing the code base and organizing everything. From there I’ll be able to start work on the editor itself. In the meantime enjoy a nice little teaser demo.

Here’s a picture of the table so far:
preview
The light pink color that’s used for the veins of the eyes was chosen for the table lights since they will get drawn over by the actual lights and will never be visible. I still need to draw out the floor graphics, wall graphics, targets, and a forest/mountain in the upper right corner (one of the bonus table areas). The stairs on the right will lead to a dungeon themed bonus table and will also be activate a multi-ball mode during a “free the prisoners” quest.

Special thanks to @Vampirics for his help in coaching me on the art design. Rather than having him do the artwork for it I’ve been doing it all myself and sharing the progress with him and he’s been giving me some valuable feedback and pointers on ways to improve the overall appearance. This has really helped me get better at pixel art in general so thank you @Vampirics.

9 Likes

Just tried this.

In-cre-dib-le. Have a badge! Congrats!

wizard journeyman @tuxinator2009

7 Likes

A very good demo! I was able to enter to the castle once :slight_smile: The demo plays very well.

Some feedback:

  • Sometimes hitting the ball at the top of the flipper sends the ball to the same side, when I would expect it to go to opposite side
  • The ball could be bigger, so that it is more visible (look at e.g. Pinball Fantasies where the ball is really big compared to the flippers)
  • The table feels maybe a bit too bouncy (?)
  • We need a pin in between of the flippers
  • I would like more saturated colors but this is a personal preference
  • Waiting for the sound effects :slight_smile: They will make a lot to the atmosphere.
5 Likes

incredible :scream:

2 Likes

Here’s an updated test with larger flippers and slightly less bounciness. Both versions are provided so make sure you have both “drgnrush.dat” and “drgnrsh2.dat” in the “pinball” folder.
PokittoPinball.zip (130.3 KB)

Actually I’ve been playing a lot of different pinball engines lately and found that it’s more likely for the ball to go to the same side unless hit towards the very tip of the flipper (though this is because the flippers are actually rotating by a greater amount than some tables).

This is very much a stylistic part (example Space Cadet had a really small ball). However, each table will be able to specify the ball size used for that table (as well as provide their own ball sprite if they don’t care for the default shiny steel ball).

Indeed, tweaked the values a bit for the updated test let me know if it feels any better (to me it seems to be more controllable and less chaotic with the decreased bounciness). Will also note that the table’s restitution factor (amount of the ball’s impact velocity that gets absorbed) will be configurable on a per-table basis. Mine was absorbing 40% originally, but the new test absorbs 70% (tried it with 40%, 50%, 60%, 70%, and 80%).

This problem actually stemmed from the right flipper accidentally being 2 pixels to the right from where it should be. The space between the flippers is only 4px wider than the ball itself (which becomes -2px if both flippers are in the middle of rotating, making dead drops avoidable just not easily, but that’s where the skill comes in). I noticed only some tables seem to have a pin there as well (and most it’s only there for a short while).

Definitely more of a personal preference (I’ve been kind of liking going for the more cartoony style for this table). That’ll be the nice thing about people being able to make their own tables as well (without any programming necessary) is we’ll really get to see some very stylistic differences of tables.

That’ll be the next step since it’s really the final piece before it’s time to start putting everything together and designing the table logic mechanics.

Thank you. This has taken a lot of effort so far, but the results are really coming together.

4 Likes