The Mechanics of Pong: Much Ado About a Bouncing Ball
Yeah, it's been a while. The last time you heard from me I was writing simulations of some of the world's oldest video games, complete with screen persistence and laggy processors.
Interesting though it was, I want to do something a bit more... fun. The first video games ever made were like technological demonstrations, exciting for their novelty, but not something you'd spend a bucket of quarters on.
When did things start getting fun? Well, some folks say it started with Spacewar!, a PvP shooter where the players are firing bullets at each other while orbiting in the gravity well of a star. It's a great game, and I might eventually try my hand at writing Spacewar!. However, I want to start with something that made a real splash, something that people would obsess over, something that... doesn't involve solving differential equations.
What game do I mean? Why, Pong, of course!
In truth, I already wrote an article on the game in my very first blog entry, but that article was more concerned with high-minded notions of art and cultural context and blah, blah, blah. What I want to do here is very different.
Instead of soliloquizing about it, I'm going to write Pong from the bottom up. Just like Al Alcorn in 1972, I'll start with a simple concept -- two paddles hitting a ball back and forth -- and see what it takes to make it into something fun.
Why This Is Really Unfair
Can you believe I compared myself to Al Alcorn just now? Come on.No, what I'm doing here is not the same thing as making the original Pong, not by a longshot. The difference between modern game design and Atari circa 1972 is much more than the speed of our processors and the quality of our displays.
For starters, modern programming languages are really slick. I'm using Python, which is a highly structured language that makes it easy to manipulate things in a game. For example, once I create a software "object" to represent a paddle or a ball, it only takes a few lines of code to change its properties or even create another object of that type.
Early game programmers had it much harder. Games like Space Invaders and Pac-Man were written in assembly language, where communicating with your computer was only slightly easier than talking to it in binary.
And in fact, with Pong, it was even harder than that. Microprocessors didn't start appearing in arcade games until 1975, so Pong would have had nothing to process code of any kind. That means that the game logic had to be encoded in the circuitry itself!
Here's part of the circuit diagram for the original Pong machine (found at Museum of the Game):
I won't be making that here, but if you want to try a circuit-level reproduction of the original Pong, try Paul Falstad's simulator.
So what I'm doing here is much easier than what Al Alcorn did. But really, that's a good thing, because rather than get bogged down in the technical limitations of long-obsolete hardware, we're going to focus on what it takes to make the game fun. In trying to design the game ourselves, we might encounter some of the same difficulties as Alcorn, and thus get some insight into video game history from the standpoint of the game developer.
The BrowPong program
Okay, before I start tossing around digital balls, here's how you can follow along with me.If you just want to read about my adventures, you don't need to do anything more. I'll post GIFs here demonstrating the game in its various states and you can go to your nearest app store or software repository (or chatbot) for a playable version of Pong.
On the other hand, for those who want a more immersive experience, I suggest you download the executable version of the game (Windows only, for now), which I have lovingly titled BrowPong. If you run the executable, you'll find a menu system so that you can use to configure the game to play in the demo modes I talk about here. You can also play around with the game parameters yourself (ball speed, paddle sizes, colors, etc.), so that you can see how the experience changes as you change the game.
So, without any further ado, let's make Pong!
The Ball
There's something hypnotic about watching a pong ball. Watch how its perfect bounces transcend earthly experience, taunting creation with its flagrant disregard for natural laws, like air resistance or friction. Actually, this is pretty close to the way a ball would bounce in space; I mean, if it were a "perfect" ball that bounced without losing energy. Fortunately, perfect balls are the easiest kind to make.In the animation above, the ball is always moving with some horizontal speed and some vertical speed. In the simplest possible version of Pong, the horizontal and vertical speed will never change, only the direction.
For example, let's say the ball moves 5 pixels to the right and 10 pixels up every second. If it then hits the top wall, the bounce will change the direction of its vertical speed, meaning it's now moving 5 pixels to the right, and 10 pixels down every second. In physics, this is called a "perfectly elastic" collision, meaning that the ball has the same energy before and after colliding. In the diagram, you can see that the ball also comes off the collision with the same angle it came in with. These simple mechanics are similar to what you would see for a ball bouncing off the edge of a pool table (assuming no side-spin) or a beam of light reflecting off of a mirror.
Easy enough, right?
Ok, but as long as I've written the code to make a bouncing ball, why not just throw in, say, 100 balls, all moving in random directions? Well, hmm... that doesn't look right.
The thing about simulating something on a computer is that you're always approximating. Unlike on a real "court", my pong balls can't move anywhere in space. Instead, they can only be drawn at certain locations on a grid of pixels.
The mistake I made was that when I moved the ball on the grid, I always rounded the motion to the nearest pixel. This greatly limited the range of angles that I could represent in the game. For example, I could move the ball 2 pixels up and 1 pixel down, or 1 pixel up and 2 pixels down, but nothing in between. The result is that the balls tend to clump together as they move.
What I want to do instead is keep track of the ball's position in an imaginary "perfect" space, where there are no pixels. I will still need to project the ball onto the pixels on the screen in every frame, but as long as I keep track of its "perfect" position under the hood, I can represent a much larger range of angles in the game.
Note that this is a solution that is specific to my CPU-based implementation. Al Alcorn had no CPU and no memory with which to store a "perfect" position of the ball.
Here's what it looks like when I make that change and give the balls some time move around: Much better. If you're following along in BrowPong, you can use the "Room Many Balls" preset to watch their evolution to this state.
Alright, my balls are bouncing right, so let's talk about paddles.
The Paddles
I think part of the reason people continue to think of Pong as the first video game (it's certainly not) is that it's so conceptually simple. What feels more like a "first" game than a circle bouncing off of a pair of rectangles?Regardless, we've already created our bouncing circle, so let's create the rectangles. Here's what happens when I replace the left/right walls with player-controlled paddles. This corresponds to the "Two Player Simple Bounce" preset in BrowPong. Really, the only difference between this and the enclosed room is the possibility that you can miss. The bounces work in exactly the same way as they did with the walls, so you have no actual control over the ball's trajectory.
This is a problem for two reasons. The first is that it decreases your engagement with the game. If you can't control where the ball goes, there's no need for strategy and it becomes purely a test of hand-eye coordination.
The other problem becomes quickly apparent the more you watch the game being played above. Since the ball only ever executes "perfect" bounces, there are only four possible angles of motion. This leads to repetitive gameplay, where the player returns to the same positions over and over.
As it turns out, this actually is a problem that Al Alcorn encountered when he originally developed Pong. His solution was to have the ball bounce at a different angle depending on where it hit the paddle, similar to what I show below. Note that with this design, it doesn't matter what angle the ball came in with. These bounces are not even close to being physically realistic. I mean, imagine trying a bounce pass to a basketball teammate only to have the ball bounce right back at you. This can happen with Pong physics.
But that's fine; this is a game, after all. However, there is one final issue I want to consider.
Ball Speed
Let's look again at the speed of the ball. You may notice that in most versions of Pong, the ball seems to move faster when it bounces at a large angle. In fact, it is moving faster overall, but is actually moving the same speed in the horizontal direction. Here's what it looks like when you simultaneously bounce balls off of different parts of a paddle. Notice how the balls remain aligned horizontally as they move across the screen, despite moving at different vertical speeds. This was probably done originally in order to simplify the implementation without a CPU; remember, there's no memory to store a position or total speed. However, it also has an important consequence: it encourages high-angle shots.Why? Well, if the ball were moving at a constant total speed, a high angle shot would take more time to cross the playing field, giving you more time to adjust your position. However, by instead keeping a constant horizontal speed, you have the same amount of time to respond to a high-angle shot as a straight shot. Anyone who plays more than a few seconds knows that it's harder to anticipate the position of the ball when it's coming in at a large angle.
All of this means that players are encouraged to use the edges of the paddles for their shots so that their opponents will have to a tougher time defending. When a game promotes risk-taking and rewards skill, it tends to do well, and Pong did very, very well.
What happens if the players are too skilled? In the original Pong, the speed of the ball went up as play continued so that highly skilled players couldn't monopolize the cabinet for too long. Again, I think this was a good change, even if it was originally motivated by profit. The gradual increase in ball speed creates a rising tension, similar to the way the aliens gradually speed up in Space Invaders.
So that should do it. Let's take a look at our final product. Here is the executable version of BrowPong. Watch out for program updates on the GitHub page and it is open source, so you can feel free to use the code as a starting point for your own experiments.
Welcome back!
ReplyDeleteThanks. Can't believe you're all the way up to 1985! Love the commitment.
Delete