Stabilizer is a local multiplayer tennis game with an optional AI opponent. Designed to be lightweight and 2D, it runs through a web browser on itch.io and will soon be playable in virtual reality through VRChat. It features the simplicity of a classic flash or mobile game and allows users to jump right in.
Concept & Design
I had started learning Unity and C# early 2021. It was my new years resolution to master the software and make a handful of games to master my skills. I practiced making a simple tabletop character survey, then a block breaking game, then a top-down arcade shooter via an online course before deciding to put all I had learned to the test with an original concept.
I knew I wanted to do something that was inspired or based on an Atari 2600 title. My scope needed to be reasonable, especially since 3D would be much too grand an effort alone, and I was not good at 2D art. I found the simplicity of Atari's Pong appealing, and felt there was a large amount of space to create a derivative work. Thus I began writing up a design document with all my thoughts.
After I wrote the game design document, I never updated it throughout the project. It seemed a bit tedious since I was the only one working on the project. A few things changed by the end such as not doing a Nintendo Switch port and some delays/skips in releases. However at the time of writing the doc I was very confident in the project I had designed, and was eager to get coding.
If you didn't read the game design document, here is a short summary of what the game was at alpha:
Tennis is a 2D retro tennis game where players have full vertical and horizontal control of their paddles. Hitting the ball gives ownership to that player, so any colored points on the field the ball passes is added to their goal payout. Score a goal, and the payout is yours. Fail, and that payout resets. After 10 rounds, the player with the most points wins. Beware! Points don't just increase your payout- they also modify the ball by making it slower or faster! Some points can even stun your opponent or give your goal a temporary shield!
The biggest struggle I had at alpha was the ball passing through the paddle if the paddle was moving forward into the oncoming ball. I had been using a Kinematic movement system based on updating transform.position. After struggling to understand, I finally realized that I need to physically move the paddle through space instead of teleporting it to new locations. Below is a sample of the original code (commented out) and the new code below it.
The boundaries mentioned here were used to keep the paddle from escaping the field. However the move to a velocity based system and a dynamic rigidbody finally allowed my paddles to collide with the walls of the arena. Most of the other code is pretty standard- tracking scores, scripting overlaps, etc etc. While this may have been a breeze for a seasoned coder, the amount of scripting I had to do was extremely large compared to my previous coursework projects, so it gave me a chance to really put my knowledge to the test. Of all the work I did, it seems designing the AI was most interesting to other people, so I can cover a bit of that.
Despite being designed for two players, most people do not play with another person locally on their computer. Especially in a browser game. Thus, creating an AI opponent was necessary. I had worked with AI plenty before and enjoy it a lot. The question of "how do I make a fake intelligence feel real? How does a human think when they play my game?". The solution came pretty quickly to me: When a player is playing Pong, they follow the ball- they can expect it to bounce in a certain direction after hitting a wall. It is rare that a player would chase the ball directly- they stay where they are and follow it's trajectory.
In order to get the AI to follow the ball, I created what I call the "beacon". It is a second, invisible ball that shoots out constantly from the visible ball. It is faster, and dies within 1.5 seconds. It moves ahead of the real ball and on death, tells the AI to move to that location. It is essentially saying "based on the trajectory of the ball, I've moved ahead of it and determined this is where it will be in 1.5 seconds". It works pretty well, sometimes too well, as people have complained it's too smart. This is false, as the AI is relatively stupid and will sometimes not chase the ball. I never figured this out, but felt it unnecessary to fix as it may add some realistic mistakes to the AI.
Below I have included links to the code that powers the AI: the Ball, Beacon, and AI scripts.
I had originally intended to do a beta before the completed release, but It just didn't happen. I had a rough couple of months (a stressful event, chronic insomnia, eye inflammation) that just put me out of a creative mindset and pushed things back. At this point I was happy with the code and was ready to start making my game look pretty. I wanted to keep the simplistic look of Atari 2600 games with a mix of modern design. One game that really stood out for me visually was Geometry Wars.
I didn't want to completely rip-off that look, and it was a bit too "neon" for my taste. I took a course on Affinity Designer (Adobe Illustrator) and began making different shapes and designs. I wanted to go with a more scientific theme with a small hint of neon. Portal was an inspiration for tone, and so I made some neon particles and paddles, but kept the background filled with neutral shapes and colors. The end result was a battle between two drones in a particle accelerator, trying to keep the core particle within the bounds of the field and away from the other unstable reactors on each side. Do I know anything about this stuff? Nope, but it was a game and it looked cool. Most importantly, players understand what is going on.
Despite wanting to learn FL Studio, I never had a chance to create my own sounds. It will have to wait until my next project. For this, I grabbed some free sounds off of freesound.org. I tried to go with a laboratory/industrial theme. The music is a bit tense and the sound effects are bubbly and echo-y. The last touch was making the main menu interesting. For this, I hopped into Blender and made some basic 3D models. I threw those into Unreal Engine to make a 3D concept of the game I had created. I think this complimented the title screen well.