Infinite Runner


Started Production April 2021
Finished Production May 2021


This particular project was not meant to become a finished product, nor was it really to be a playable game for that matter. I had tossed together the rough draft of a character controller and level generation for an interview with a company as I was asked for previous code snippets to look over. Unfortunately for me, most of my previous code has since been lost to the ether, with some of it being part of projects with other people years ago, while other more recent code is still in development at previous companies. So I decided it was best to make something new and hand it over for inspection, and so was birthed the start of this project.

Once I was turned down from the job, it really sent me into a bad spiral, with that being the furthest I had gotten in an interview in a while. I brought the issue up with my father, who is also a developer, and he suggested we finish out the project so that something better came out of the experience. With his prodding, as well as some more prodding from my partner, he and I decided we would release the project, regardless of its state, on the 7th of May. Once that was decided, all that was left was to figure out what else needed to be built.

The poor character controller I had made previous was the first to go, as I quickly found many limitations to the way I put it together. For starters, jumping while the game was trying to move the player forwards would slow down, or in some cases fully stop the player's forward motion. With the new controller, not only was I able to jump properly while moving forward, I was also able to control the jump height as needed, as well as the forward speed to allow for speeding up the player as they went further along into the game.

Up next was the level generator, which was able to stay in its original form, abet with a few modifications to how it handled the objects. Originally, I was using prefabs that were instantiated into the scene for the player to run across, and then deleted once they had been left behind, which worked for while the only things I was spawning was the ground itself. However, once I began to place in collectables for the player, I quickly realized that spawning and deleting that many objects constantly would not be good for the speed of the program. Instead, I swapped over to using object pooling, where I would just enable the ground object with the proper placement of it in the world, and then disable it after the player ran off of it.

This leads me into the next part of the equation, which was the collectables. To start with, when they were first added in, they were just used as a way for the player to buy more lives to continue playing the same run for a higher score. Later on however, my father suggested we add in some other upgrades to use the points on, and so was birthed the challenge of making a magnetic powerup for the player. Getting the collectables to move towards the player wasn't too large of a hassle, as it just involved doing (position - player.position).sqrmagnitude < player.MagnetRange() check, with the MagnetRange() returning the current upgrade level of the player's range. The issue came in to play with how this worked with the object pooling that was being used for level generation.

To explain the issue better, the following code is a useful mention. To handle the collectables needing to show back up for the next time that specific level was used in the run, I made a function called ActivateChildren() which had a GameObject passed in. That GameObject was the ground I was spawning, and the function was meant to run through and turn on all disabled objects, with the collectables being the only objects to be turned off during gameplay. That meant that the collectables would be turned on, right where they were previously turned off. Which was fine, until the magnet powerup started moving the objects around to chase the player. The way I fixed this issue was each collectable was placed under an empty game object at the proper position, with a specific tag on the new parent object. Now, ActivateChildren() would go through the children in the ground object, check for the proper tag, and then set the child of the found tagged object to have its localPosition equal to Vector3.zero. This allowed the collectables to move as far as they needed to catch the player, and still be back in the proper spot when the ground was used once again.

Now with all these points the player could earn, I had to give them proper things to spend them on. In this case, I was being lazy and just made the magnet the main thing to upgrade, both its range and its strength. So to start, the player had a 0 in both range and strength, which meant the player had to get enough points to buy both a range and a strength upgrade to see any difference. This felt a little off, so I ended up changing it to be a 5 for the strength to start, and a 3 for the range, allowing the player to see a change regardless of where they spent their points. Now the player had the choice between buying more lives to continue the run, or upgrading their magnetic power to make collecting the points easier. For the final piece for the upgrading, I made a simple rocking animation and red flash of the button should the player try to buy something they don't have the points for, as the points for all upgrades increased each time an upgrade of that type was purchased.

All of the music and sound effects were put into place by my father, and we both played a major role in testing the game as we were building. If I were to restart this project, I would probably do it as a 2D variant instead, allowing for more randomness in the level generation, as well as being something I have little experience in. Most of the projects I have done in unity are based in 3D, and I feel that was a major reason as to why I threw together the original coding using a 3D mind set. Regardless, it did do what we set out for, giving me something more substantial out of a depressive situation, and getting me back into the habit of making these posts for retrospect.