Pong

This is first post for a series of games I made to learn game development. Obviously, first up is a pong clone.

Scope

The scope of this project was to recreate the simple pong game, along with having some basic sound effects and a singleplayer mode, while hopefully creating no bugs ;)

Process

I first created an arena with two walls, each at top and bottom (using the StaticBody2d node). The purpose being giving ball a surface to bounce away from. Similarly, I placed left and right walls (using the Area2D node). This time the idea was to detect if the ball has entered the area and if so decrease the point of losing player.

Next up, I created a separate player scene with as a CharacterBody2D node, and added collision and sprite to it. Added it twice to the made game scene and labeled it player 1 and 2 accordingly. The default script with the node worked pretty well, I simply had to remove gravity and disable motion along the x direction. Not much was changed from the default behavior.

Now, I did the same for the ball, with a few changes to its script. To make sure that the ball launch behavior wasn’t predictable, I selected a random angle in (-π/4, π/4) and gave it a 50-50 change that it will be flipped towards one of the players. This created a random change of the ball launching towards either player.

I then added signals for the earlier Area2D nodes we made, so that we can detect if the ball has entered and reduce a point from losing player.

I then wrote a script that follows the y position of the ball and makes so that player 1 always matches it. This become the main of the AI logic, however, it was a little too perfect. The trick I used to fix this is only follow ball if the distance between player’s paddle center and ball is greater than some value. And there it was, losing some of the shots making the singleplayer game fun too.

Lastly, I added some basic sounds, to indicate point loss and wall bounces. Rest of the time was spend to tidy up the codebase, add the menu UI and overall playtesting and polish.

Insights

Before making the game, I wasn’t sure how the AI logic should be implemented. Unlike all shower thoughts, I had this good one to keep a track of the y position of the ball and that was my eureka! (no pun intended).

To further test the theory and the randomness of the game. I made it so that both the players are the same AIs and that they are stuck in a repeated loop of playing pong (yes, the genre of this game is dystopia) and left it to run overnight.

What I found was rather uninteresting, the avg probability that a player will win was 0.5. Since this was over thousands of points, I was convinced that the system is fairly random. This was a somewhat unnecessary fun experiment I did, to test the limits of the engine.

Changes

With all this being said, below are things I would do differently:

  1. Sketch out a graph of gameplay loop (doesn’t matter how small or big the game is).
  2. Have global variables controlling the state of the game.
  3. Don’t cram everything in a single script.
  4. Use signals more often.
  5. Use @onready variable declarations instead of directly referencing the node with $.
  6. Stick to the pixel grid, anything that is not multiple of 4 might cause issues, only do it when you know what you’re doing.

Remarks

If you made it this far, Thank you so much for reading this. Feel free to let me know your thoughts and checkout the links below. Like always, more stuff is coming!

My archive of code and chaos


By SoloMazer, 2026-07-17


On this page: